class A;
typedef void (A::*pafn_t)(void);
void callfn (A* p, pafn_t pafn)
{
(p->*pafn)();
}
-------------------------------------------
g++ -S -Os:
-------------------------------------------
_Z6callfnP1AMS_FvvE:
.LFB2:
testb $1, %sil
movq %rsi, -16(%rsp)
movq %rdx, -8(%rsp)
movq %rsi, %rax
je .L3
movq (%rdi,%rdx), %rax
movq -1(%rsi,%rax), %rax
.L3:
addq %rdx, %rdi
movq %rax, %r11
jmp *%r11
-------------------------------------------
There are some rather puzzling inefficiencies. In the end, rax is copied to r11
for the jump, even though jmp *%rax would have worked just fine. The function
has no return value, so I don't see the reason for setting rax. Then there is
the superfluous copying of the member pointer address to the stack, and then
not using those stored values.
-------------------------------------------
g++ -S -O1:
-------------------------------------------
_Z6callfnP1AMS_FvvE:
.LFB2:
subq $24, %rsp
.LCFI0:
movq %rsi, 8(%rsp)
movq %rdx, 16(%rsp)
movq %rsi, %rax
testb $1, %sil
je .L3
movq (%rdi,%rdx), %rax
movq -1(%rsi,%rax), %rax
.L3:
addq %rdx, %rdi
call *%rax
addq $24, %rsp
ret
-------------------------------------------
Here we see that it is perfectly acceptable to use rax for the call. Here is
source of the superfluous stack usage, which should have been removed by
further stages along with realizing that those values are already in registers.
--
Summary: Useless instructions in member call by pointer
Product: gcc
Version: 4.3.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: 9ugsa9j02 at sneakemail dot com
GCC host triplet: x86_64-pc-gnu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37512