re PR middle-end/37448 (cannot compile big function)

2016-02-22  Richard Biener  <rguenther@suse.de>

	PR ipa/37448
	* ipa-inline-transform.c (inline_call): When not updating
	overall summaries adjust self size by the growth estimate.
	* ipa-inline.c (inline_to_all_callers_1): Add to the callers
	hash-set, do not update overall summaries here.  Renamed from ...
	(inline_to_all_callers): ... this which is now wrapping the
	above and performing delayed overall summary update.
	(early_inline_small_functions): Delay updating of the overall
	summary.

From-SVN: r233598
This commit is contained in:
Richard Biener 2016-02-22 09:32:35 +00:00 committed by Richard Biener
parent f97374a73f
commit bddead150b
3 changed files with 49 additions and 5 deletions

View File

@ -1,3 +1,15 @@
2016-02-22 Richard Biener <rguenther@suse.de>
PR ipa/37448
* ipa-inline-transform.c (inline_call): When not updating
overall summaries adjust self size by the growth estimate.
* ipa-inline.c (inline_to_all_callers_1): Add to the callers
hash-set, do not update overall summaries here. Renamed from ...
(inline_to_all_callers): ... this which is now wrapping the
above and performing delayed overall summary update.
(early_inline_small_functions): Delay updating of the overall
summary.
2016-02-21 Markus Trippelsdorf <markus@trippelsdorf.de>
* tree-chkp.c (chkp_mark_invalid_bounds_walker): Initialize

View File

@ -301,9 +301,11 @@ inline_call (struct cgraph_edge *e, bool update_original,
struct cgraph_node *callee = e->callee->ultimate_alias_target ();
bool new_edges_found = false;
int estimated_growth = 0;
if (! update_overall_summary)
estimated_growth = estimate_edge_growth (e);
/* This is used only for assert bellow. */
#if 0
int estimated_growth = estimate_edge_growth (e);
bool predicated = inline_edge_summary (e)->predicate != NULL;
#endif
@ -373,7 +375,13 @@ inline_call (struct cgraph_edge *e, bool update_original,
new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
check_speculations (e->callee);
if (update_overall_summary)
inline_update_overall_summary (to);
inline_update_overall_summary (to);
else
/* Update self size by the estimate so overall function growth limits
work for further inlining into this function. Before inlining
the function we inlined to again we expect the caller to update
the overall summary. */
inline_summaries->get (to)->size += estimated_growth;
new_size = inline_summaries->get (to)->size;
if (callee->calls_comdat_local)

View File

@ -2163,7 +2163,8 @@ flatten_function (struct cgraph_node *node, bool early)
recursion. */
static bool
inline_to_all_callers (struct cgraph_node *node, void *data)
inline_to_all_callers_1 (struct cgraph_node *node, void *data,
hash_set<cgraph_node *> *callers)
{
int *num_calls = (int *)data;
bool callee_removed = false;
@ -2193,7 +2194,10 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
inline_summaries->get (node->callers->caller)->size);
}
inline_call (node->callers, true, NULL, NULL, true, &callee_removed);
/* Remember which callers we inlined to, delaying updating the
overall summary. */
callers->add (node->callers->caller);
inline_call (node->callers, true, NULL, NULL, false, &callee_removed);
if (dump_file)
fprintf (dump_file,
" Inlined into %s which now has %i size\n",
@ -2211,6 +2215,23 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
return false;
}
/* Wrapper around inline_to_all_callers_1 doing delayed overall summary
update. */
static bool
inline_to_all_callers (struct cgraph_node *node, void *data)
{
hash_set<cgraph_node *> callers;
bool res = inline_to_all_callers_1 (node, data, &callers);
/* Perform the delayed update of the overall summary of all callers
processed. This avoids quadratic behavior in the cases where
we have a lot of calls to the same function. */
for (hash_set<cgraph_node *>::iterator i = callers.begin ();
i != callers.end (); ++i)
inline_update_overall_summary (*i);
return res;
}
/* Output overall time estimate. */
static void
dump_overall_stats (void)
@ -2590,10 +2611,13 @@ early_inline_small_functions (struct cgraph_node *node)
fprintf (dump_file, " Inlining %s into %s.\n",
xstrdup_for_dump (callee->name ()),
xstrdup_for_dump (e->caller->name ()));
inline_call (e, true, NULL, NULL, true);
inline_call (e, true, NULL, NULL, false);
inlined = true;
}
if (inlined)
inline_update_overall_summary (node);
return inlined;
}