>It's probably because we know it's only called once and thus not performance 
>relevant. Try put it into a loop.

Thanks for the hint, but I'm afraid it is not that. I tried this and it still 
calls f_add. I also try with i = 1[...]000.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main (int argc, char *argv[])
{
    int x, y, z;
    if (argc < 4) return -1;
    f_init(ADD);
    x = atoi(argv[1]);
    y = atoi(argv[2]);
    z = atoi(argv[3]);
    for (int i = z; i > 0; i -= 1)
        x = f(x, y);
    printf("%d\n", x);
    return 0;
}

Note that doing the same source transformation than STEP 2 will work and 
properly optimize it as x + y * z.

for (int i = z; i > 0; i -= 1)
    if (f == &f_add)
        x = f_add(x, y);
    else
        x = f(x, y); 

Frédéric Recoules

----- Mail original -----
De: "Richard Biener" <richard.guent...@gmail.com>
À: "gcc" <gcc@gcc.gnu.org>, "FRÉDÉRIC RECOULES" 
<frederic.recou...@univ-grenoble-alpes.fr>
Envoyé: Samedi 14 Mars 2020 12:12:15
Objet: Re: Thought on inlining indirect function calls

On March 14, 2020 10:55:09 AM GMT+01:00, "FRÉDÉRIC RECOULES" 
<frederic.recou...@univ-grenoble-alpes.fr> wrote: 
>Hello the GCC community, 
>I just want to share some thoughts on inlining a function even if 
>it is called through a function pointer. 
>My starting point is the version 9.2 (used at https://godbolt.org/), 
>so I am sorry if something similar have already been discussed since. 
> 
> 
>For the context, I got very excited when I discovered the (not so new 
>but not yet really used) Link Time Optimization and I started to play 
>with 
>to put under the test the inlining capacities. 
>I will assume however that LTO is just an enabler and so, examples can 
>be 
>simplified by writing everything in the same file and activate the 
>whole 
>program optimization. 
> 
> 
>To make my remarks concrete, I will rely on the following (dumb but 
>inspired by real software) example compiled with -O3 -fwhole-program: 
> 
>int (*f) (int, int); 
> 
>static int f_add (int x, int y) 
>{ 
> return x + y; 
>} 
> 
>static int f_sub (int x, int y) 
>{ 
> return x - y; 
>} 
> 
>enum f_e { ADD, SUB }; 
>void f_init(enum f_e op) { 
> switch (op) { 
> case ADD: 
> f = &f_add; 
> break; 
> case SUB: 
> f = &f_sub; 
> } 
>} 
> 
>STEP 1: statically known at function call site 
> 
>#include <stdlib.h> 
>#include <stdio.h> 
> 
>int main (int argc, char *argv[]) 
>{ 
> int x, y, z; 
> f_init(ADD); 
> if (argc < 3) return -1; 
> x = atoi(argv[1]); 
> y = atoi(argv[2]); 
> z = f(x, y); 
> printf("%d\n", z); 
> return 0; 
>} 
> 
>I was pretty disappointed to see that even if the compiler knows we are 
>calling f_add, it doesn't inline the call (it ends up with "call 
>f_add"). 

It's probably because we know it's only called once and thus not performance 
relevant. Try put it into a loop. 

Richard. 

>I can but only suppose it is because its address is taken and from a 
>blind black box user perspective, it doesn't sound too difficult to 
>completely inline it. 
> 
>STEP 2: statically known as being among a pool of less than 
> (arbitrarily fixed = 2) N functions 
> 
>#include <stdlib.h> 
>#include <stdio.h> 
>#include <string.h> 
> 
>int main (int argc, char *argv[]) 
>{ 
> int x, y, z; 
> enum f_e e; 
> if (argc < 4) return -1; 
> if (strcmp(argv[1], "add") == 0) 
> e = ADD; 
> else if (strcmp(argv[1], "sub") == 0) 
> e = SUB; 
> else return -1; 
> f_init(e); 
> x = atoi(argv[2]); 
> y = atoi(argv[3]); 
> z = f(x, y); 
> printf("%d\n", z); 
> return 0; 
>} 
> 
>Here the compiler can't know at compile time the function that will be 
>called but I suppose that it knows that it will be either f_add or 
>f_sub. 
>A simple work around would be for the compiler to test at the call site 
>the value of f and inline the call thereafter: 
> 
> if (f == &f_add) 
> z = f_add(x, y); 
> else if (f == &f_sub) 
> z = f_sub(x, y); 
> else __builtin_unreachable(); /* or z = f(x, y) to be conservative */ 
> 
>Once again, this transformation don't sound too complicated to 
>implement. 
>Still, easy to say-so without diving into the compiler's code. 
> 
> 
>I hope it will assist you in your reflections, 
>Have a nice day, 
>Frédéric Recoules 

Reply via email to