------- Comment #6 from rguenth at gcc dot gnu dot org 2010-02-15 16:57 ------- The following doesn't make too much sense:
static bool cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, VEC (cgraph_edge_p, heap) **new_edges) { ... /* Now update size of caller and all functions caller is inlined into. */ for (;e && !e->inline_failed; e = e->caller->callers) { to = e->caller; old_size = e->caller->global.size; new_size = cgraph_estimate_size_after_inlining (1, to, what); to->global.size = new_size; to->global.time = cgraph_estimate_time_after_inlining (freq, to, what); } gcc_assert (what->global.inlined_to == to); if (new_size > old_size) overall_size += new_size - old_size; so we adjust inlined callers size but do not accumulate those changes to overall_size. And in ... static bool cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what, cgraph_inline_failed_t *reason, bool one_only) { ... if (to->global.inlined_to) to = to->global.inlined_to; we seem to adjust for this effect by taking to->global.inlined_to, but that's obviously not the same. Also when deciding function called once inlining we should use cgraph_check_inline_limits (..., true) and cgraph_mark_inline_edge. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43058