Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimizing out helper functions

This is more or less a request for clarification on Casting a function pointer to another type with example code

struct my_struct;
void my_callback_function(struct my_struct* arg);
void do_stuff(void (*cb)(void*));

static void my_callback_helper(void* pv)
{
    my_callback_function(pv);
}
int main()
{
    do_stuff(&my_callback_helper);
}

The answer says a "good" compiler should be able to optimize out the my_callback_helper() function but I found no compiler at https://gcc.godbolt.org that does it and the helper function gets always generated even if it's just a jump to my_callback_function() (-O3):

my_callback_helper:
        jmp     my_callback_function
main:
        subq    $8, %rsp
        movl    $my_callback_helper, %edi
        call    do_stuff
        xorl    %eax, %eax
        addq    $8, %rsp
        ret

So my question is: Is there anything in the standard that prevents compilers from eliminating the helper?

like image 681
PSkocik Avatar asked Sep 27 '17 11:09

PSkocik


Video Answer


1 Answers

There's nothing in the standard that directly prevents this optimization. But in practice, it's not always possible for compilers when they don't have a "full picture".

You have taken the address of my_callback_helper. So compiler can't easily optimize it out because it doesn't know what do_stuff does with it. In a separate module where do_stuff is defined, compiler doesn't know that it can simply use/call my_callback_function in place of its argument (my_callback_helper). In order to optimize out my_callback_helper completely, compiler has to know what do_stuff does as well. But do_stuff is an external function whose definition isn't available to compiler. So this sort of optimization may happen if you provide a definition for do_stuff and all its uses.

like image 132
P.P Avatar answered Sep 29 '22 23:09

P.P