------- 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