On Tue, Dec 30, 2008 at 1:08 PM, Kristian Spangsege
<kristian.spangs...@gmail.com> wrote:
> 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.

It's a missed optimization that should be fixed (somewhat) with GCC
4.4 through the
fixing and enabling of IPA-CP (interprocedural constant propagation).

Richard.

Reply via email to