This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Inlining behaviour in GCC
- From: "Richard Guenther" <richard dot guenther at gmail dot com>
- To: "Kristian Spangsege" <kristian dot spangsege at gmail dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Tue, 30 Dec 2008 13:24:51 +0100
- Subject: Re: Inlining behaviour in GCC
- References: <19c077830812300408l1a92b832t8ca474e777199cb6@mail.gmail.com>
On Tue, Dec 30, 2008 at 1:08 PM, Kristian Spangsege
<kristian.spangsege@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.