> The problem here is that compiler thinks that atoi may call back some
> static function in unit that may change value of the variable.  There is
> no analysis implemented on how such calls back to unit can affect the
> value.  We have leaf attribute that you can annotate atoi (but glibc
> does not do that) which  should make gcc to work out the propagation.

Here is the gimple that I obtain for atoi:

__attribute__((gnu_inline, pure, leaf, nothrow))
atoi (const char * __nptr)
{
  int D.3183;

  # DEBUG BEGIN_STMT
  _1 = strtol (__nptr, 0B, 10);
  D.3183 = (int) _1;
  return D.3183;
}

It is both pure and leaf, but the strtol it calls is not. I would however
have thought that because strtol is called from a pure function, it would
have inherited from the pure attribute.

Frédéric Recoules


----- Mail original -----
De: "Jan Hubicka" <hubi...@ucw.cz>
À: "FRÉDÉRIC RECOULES" <frederic.recou...@univ-grenoble-alpes.fr>
Cc: "Richard Biener" <richard.guent...@gmail.com>, "gcc" <gcc@gcc.gnu.org>, 
"mjambor" <mjam...@suse.cz>
Envoyé: Samedi 14 Mars 2020 18:34:38
Objet: Re: Thought on inlining indirect function calls

> > I think it is because during early opts we do not know if f is not 
> > modified by atoi call and at IPA time (where we already know that from 
> > resolution info) we do not have jump functions to track global variables. 
> 
> I confirm that if I remove the calls to atoi, the function is correctly 
> inlined. 
> Note however that, if I declare f as static, such as it can theoretically not 
> be 
> impacted by atoi, the compiler still doesn't inline the function. 

The problem here is that compiler thinks that atoi may call back some 
static function in unit that may change value of the variable. There is 
no analysis implemented on how such calls back to unit can affect the 
value. We have leaf attribute that you can annotate atoi (but glibc 
does not do that) which should make gcc to work out the propagation. 

Honza 
> 
> Yet, if STEP 1 was an issue, and that your answers has provided some 
> clarification, 
> what is about the STEP 2? As far as I know, it is not supported, it is? 
> 
> Frédéric Recoules 
> 
> 
> ----- Mail original ----- 
> De: "Jan Hubicka" <hubi...@ucw.cz> 
> À: "Richard Biener" <richard.guent...@gmail.com> 
> Cc: "gcc" <gcc@gcc.gnu.org>, "FRÉDÉRIC RECOULES" 
> <frederic.recou...@univ-grenoble-alpes.fr>, mjam...@suse.cz 
> Envoyé: Samedi 14 Mars 2020 14:05:07 
> Objet: Re: Thought on inlining indirect function calls 
> 
> > >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. 
> 
> I think it is because during early opts we do not know if f is not 
> modified by atoi call and at IPA time (where we already know that from 
> resolution info) we do not have jump functions to track global variables. 
> 
> Honza 
> > 
> > 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