Hi

A simple example (see below) seems to reveal that GCC considers the
unoptimized size of a function rather that the optimized one, when
deciding whether it is small enough to be inlined. In fact, it shows
that GCC does consider the optimized size, but optimized based only on
its body, not the constant/literal arguments of a particular
invocation.

In the example below 'g1' does not get inline, but 'g2' does, although
they exapnd to the exact same thing, which is a single call to 'f',
because the argument is true. As can be seen, the "work around" is to
factor out the bulk of the function. That is, if a "bulky" function
has one or more special cases that each amount to little code, and can
be selected based on constant arguments, it is wise to factor out the
"bulky" part into a separate function. It would have been nice if GCC
had been able to "see" past this barrier, such that one would not have
to be aware of the limitation, but I guess there is a complexity issue
to take into account.

If one defines 'f' as an empty function and declares it 'inline', then
'g1' gets inlined too, ergo, GCC does some optimization before
considering its size for inlining, but as suggested above, it probably
does not optimize it further based on arguments of a particular
invocation, until it is actually selected to be inlined. It seems that
inlining is performed bottom-up, rather than top-down.

These observations are made with GCC version 4.3.2.


void f()

inline void g1(bool b)
{
  if(b) { f(); return; }
  f();f();f();f();f();f();f();f();f();f();f();f();
  f();f();f();f();f();f();f();f();f();f();f();f();
  f();f();f();f();f();f();f();f();f();f();f();f();
  f();f();f();f();f();f();f();f();f();f();f();f();
  f();f();f();f();f();f();f();f();f();f();f();f();
  f();f();f();f();f();f();f();f();f();f();f();f();
}

inline void h()
{
  f();f();f();f();f();f();f();f();f();f();f();f();
  f();f();f();f();f();f();f();f();f();f();f();f();
  f();f();f();f();f();f();f();f();f();f();f();f();
  f();f();f();f();f();f();f();f();f();f();f();f();
  f();f();f();f();f();f();f();f();f();f();f();f();
  f();f();f();f();f();f();f();f();f();f();f();f();
}

inline void g2(bool b)
{
  if(b) { f(); return; }
  h();
}

int main()
{
  g1(true);
  g2(true);
  return 0;
}


I assume that this behaviour of the GCC optimizer is a concious and
deliberate choice,
but I would by happy if someone could confirm it, and maybe comment briefly on
the rationale behind it.


Regards,
Kristian Spangsege

Reply via email to