On Sun, Jan 8, 2012 at 12:38 AM, Jan Hubicka <hubi...@ucw.cz> wrote:
> Hi,
> this patch fixes first half of the PR.  The PR is about a function that is 
> supposed
> to be inlined at -O2.  The function contains two calls, one indirect and 
> inlining
> the indirect call makes things a lot better. GCC however things that 
> replacing call
> by two calls at -O2 is a bad idea.
>
> This patch solves first part of it.  The function in question is COMDAT. We 
> already
> know that C++ coding style makes COMDATs quite rarely to be shared and at -Os 
> we
> already handle them sort of similarly to static ufnctions.  We however don't 
> do that
> at -O2.  This patch makes it happen in both cases.
>
> Bootstrapped/regtested x86_64-linux, comitted.
> Will commit the testcase with the followup fix.

Err ...

>        PR tree-optimization/51680
>        * ipa-inline.c (want_inline_small_function_p): Be more lax on functions
>        whose inlining reduce unit size.
>
> Index: ipa-inline.c
> ===================================================================
> --- ipa-inline.c        (revision 182949)
> +++ ipa-inline.c        (working copy)
> @@ -482,21 +482,13 @@ want_inline_small_function_p (struct cgr
>           e->inline_failed = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
>          want_inline = false;
>        }
> -      else if (!DECL_DECLARED_INLINE_P (callee->decl)
> -              && !flag_inline_functions)
> -       {
> -          e->inline_failed = CIF_NOT_DECLARED_INLINED;
> -         want_inline = false;
> -       }
> -      else if (!DECL_DECLARED_INLINE_P (callee->decl)
> -              && growth >= MAX_INLINE_INSNS_AUTO)
> -       {
> -          e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
> -         want_inline = false;
> -       }
> -      /* If call is cold, do not inline when function body would grow.
> -        Still inline when the overall unit size will shrink because the 
> offline
> -        copy of function being eliminated.
> +      /* Before giving up based on fact that caller size will grow, allow
> +         functions that are called few times and eliminating the offline
> +        copy will lead to overall code size reduction.
> +        Not all of these will be handled by subsequent inlining of functions
> +        called once: in particular weak functions are not handled or 
> funcitons
> +        that inline to multiple calls but a lot of bodies is optimized out.
> +        Finally we want to inline earlier to allow inlining of callbacks.
>
>         This is slightly wrong on aggressive side:  it is entirely possible
>         that function is called many times with a context where inlining
> @@ -509,24 +501,39 @@ want_inline_small_function_p (struct cgr
>         first, this situation is not a problem at all: after inlining all
>         "good" calls, we will realize that keeping the function around is
>         better.  */
> -      else if (!cgraph_maybe_hot_edge_p (e)
> -              && (DECL_EXTERNAL (callee->decl)
> +      else if (growth <= MAX_INLINE_INSNS_SINGLE

That surely should be MAX_INLINE_INSNS_AUTO instead.  At _least_.
You are triggering very much more inlining during early inlining now -
I don't see
where we did this for -Os already as you claim.  In fact it is totally
against the spirit of early inlining now :(

Why does IPA inlining not figure out that inlining the indirect call is good?

> +              /* Unlike for functions called once, we play unsafe with
> +                 COMDATs.  We can allow that since we know functions
> +                 in consideration are small (and thus risk is small) and
> +                 moreover grow estimates already accounts that COMDAT
> +                 functions may or may not disappear when eliminated from
> +                 current unit. With good probability making aggressive
> +                 choice in all units is going to make overall program
> +                 smaller.
> +
> +                 Consequently we ask cgraph_can_remove_if_no_direct_calls_p
> +                 instead of
> +                 cgraph_will_be_removed_from_program_if_no_direct_calls  */
> +               && !DECL_EXTERNAL (callee->decl)
> +               && cgraph_can_remove_if_no_direct_calls_p (callee)
> +               && estimate_growth (callee) <= 0)
> +       ;
> +      else if (!DECL_DECLARED_INLINE_P (callee->decl)
> +              && !flag_inline_functions)
> +       {
> +          e->inline_failed = CIF_NOT_DECLARED_INLINED;
> +         want_inline = false;
> +       }
> +      else if (!DECL_DECLARED_INLINE_P (callee->decl)
> +              && growth >= MAX_INLINE_INSNS_AUTO)
> +       {
> +          e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
> +         want_inline = false;
> +       }
> +      /* If call is cold, do not inline when function body would grow. */
> +      else if (!cgraph_maybe_hot_edge_p (e))
>
> -                  /* Unlike for functions called once, we play unsafe with
> -                     COMDATs.  We can allow that since we know functions
> -                     in consideration are small (and thus risk is small) and
> -                     moreover grow estimates already accounts that COMDAT
> -                     functions may or may not disappear when eliminated from
> -                     current unit. With good probability making aggressive
> -                     choice in all units is going to make overall program
> -                     smaller.
> -
> -                     Consequently we ask 
> cgraph_can_remove_if_no_direct_calls_p
> -                     instead of
> -                     cgraph_will_be_removed_from_program_if_no_direct_calls  
> */
>
> -                  || !cgraph_can_remove_if_no_direct_calls_p (callee)
> -                  || estimate_growth (callee) > 0))
>        {
>           e->inline_failed = CIF_UNLIKELY_CALL;
>          want_inline = false;

Reply via email to