On Tue, Feb 12, 2019 at 6:16 PM Martin Jambor <mjam...@suse.cz> wrote:
>
> On Tue, Feb 12 2019, Bin.Cheng wrote:
> > Hi,
> > When reading inlining code in GCC, I wonder if we have size heuristics
> > to limit inlining long call sequence?  For example, for call sequence
> > A -> B -> C -> D -> ... -> X -> Y -> Z
> > if each function call grows size by a very small amount, inlining Z
> > all the way up to the outermost function could result in a big
> > function which may hurt icache.  Is this case handled in inliner? if
> > yes, which code handles this?  Thanks in advance.
> >
> > BTW, I am using GCC 6, not sure if trunk has different behavior.
>
> I believe it is done in caller_growth_limits() in ipa-inline.c in both
> trunk and GCC 6.  The following comment in the function might shed a bit
> more light on the behavior regarding big functions:
>
>   /* Look for function e->caller is inlined to.  While doing
>      so work out the largest function body on the way.  As
>      described above, we want to base our function growth
>      limits based on that.  Not on the self size of the
>      outer function, not on the self size of inline code
>      we immediately inline to.  This is the most relaxed
>      interpretation of the rule "do not grow large functions
>      too much in order to prevent compiler from exploding".  */
Thanks, assume it's below code collecting maximum code size limit
along call stack:

  while (true)
    {
      info = inline_summaries->get (to);
      if (limit < info->self_size)
        limit = info->self_size;
      if (stack_size_limit < info->estimated_self_stack_size)
        stack_size_limit = info->estimated_self_stack_size;
      if (to->global.inlined_to)
        to = to->callers->caller;

Question is it only collects the maximum self_size of outer callers,
since we are inlining from outer function to inner, only check
self_size of caller means we can still get bloated size for some
cases? Or what piece of code I have missed?

Another question is in want_inline_small_function_p:

      /* Apply MAX_INLINE_INSNS_AUTO limit for functions not declared inline
         Upgrade it to MAX_INLINE_INSNS_SINGLE when hints suggests that
         inlining given function is very profitable.  */
      else if (!DECL_DECLARED_INLINE_P (callee->decl)
               && !big_speedup
               && !(hints & INLINE_HINT_known_hot)
               && growth >= ((hints & (INLINE_HINT_indirect_call
                                       | INLINE_HINT_loop_iterations
                                       | INLINE_HINT_array_index
                                       | INLINE_HINT_loop_stride))
                             ? MAX (MAX_INLINE_INSNS_AUTO,
                                    MAX_INLINE_INSNS_SINGLE)
                             : MAX_INLINE_INSNS_AUTO))
So for function not declared as inline, if it's considered as
known_hot, there will be no size restriction at all.  This looks like
an issue to me, given we do restrict size even for know_hot function
which is declared as inline:

      /* Apply MAX_INLINE_INSNS_SINGLE limit.  Do not do so when
         hints suggests that inlining given function is very profitable.  */
      else if (DECL_DECLARED_INLINE_P (callee->decl)
               && growth >= MAX_INLINE_INSNS_SINGLE
               && ((!big_speedup
                    && !(hints & (INLINE_HINT_indirect_call
                                  | INLINE_HINT_known_hot
                                  | INLINE_HINT_loop_iterations
                                  | INLINE_HINT_array_index
                                  | INLINE_HINT_loop_stride)))
                   || growth >= MAX_INLINE_INSNS_SINGLE * 16))

Again, this is on GCC6.

Thanks,
bin
>
> HTH
>
> Martin

Reply via email to