diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/ipa-inline-transform.c | 12 | ||||
-rw-r--r-- | gcc/ipa-inline.c | 30 |
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; } |