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