aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/ipa-inline-transform.c12
-rw-r--r--gcc/ipa-inline.c30
3 files changed, 49 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 88f7a23..b28ed88 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index 759ab78..5dc0b5a 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -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)
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 07e661e..57a4588 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -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;
}