* Re: question about inlining long call sequence
2019-02-12 10:16 ` Martin Jambor
@ 2019-02-13 10:09 ` Bin.Cheng
0 siblings, 0 replies; 3+ messages in thread
From: Bin.Cheng @ 2019-02-13 10:09 UTC (permalink / raw)
To: Martin Jambor; +Cc: GCC Development, Jan Hubicka
On Tue, Feb 12, 2019 at 6:16 PM Martin Jambor <mjambor@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
^ permalink raw reply [flat|nested] 3+ messages in thread