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