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.