The performance of exchange2 built with PGO will decrease ~28% by r278808 due to profile count set incorrectly. The cloned nodes are updated to a very small count caused later pass cunroll fail to unroll the recursive function in exchange2, This patch enables adding orig_sum to the new nodes for self recursive node.
digits_2 -> digits_2.constprop.0, digits_2.constprop.1, etc. gcc/ChangeLog: 2019-12-10 Luo Xiong Hu <luo...@linux.ibm.com> * ipa-pure-const.c (self_recursive_p): Move it from ... (propagate_pure_const): Use cgraph_node::self_recursive_p. (pass_nothrow::execute): Likewise. * cgraph.h (cgraph_node::self_recursive_p): to ... this. * ipa-cp.c (update_profiling_info): Check self_recursive_p node. --- gcc/cgraph.h | 18 ++++++++++++++++++ gcc/ipa-cp.c | 5 ++++- gcc/ipa-pure-const.c | 19 ++----------------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/gcc/cgraph.h b/gcc/cgraph.h index cdeea4d9953..1aca7d114e9 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -1329,6 +1329,9 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node /* Return true if function should be optimized for size. */ bool optimize_for_size_p (void); + /* Return true if NODE is self recursive function. */ + inline bool self_recursive_p (void); + /* Dump the callgraph to file F. */ static void dump_cgraph (FILE *f); @@ -3285,6 +3288,21 @@ cgraph_node::optimize_for_size_p (void) return false; } +/* Return true if NODE is self recursive function. + Indirectly recursive functions appears as non-trivial strongly + connected components, so we need to care about self recursion + only. */ + +inline bool +cgraph_node::self_recursive_p (void) +{ + struct cgraph_edge *e; + for (e = this->callees; e; e = e->next_callee) + if (e->callee->function_symbol () == this) + return true; + return false; +} + /* Return symtab_node for NODE or create one if it is not present in symtab. */ diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 14064ae0034..76c1b309d04 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -4305,7 +4305,10 @@ update_profiling_info (struct cgraph_node *orig_node, remainder = remainder.guessed_local (); new_sum = orig_node_count.combine_with_ipa_count (new_sum); - new_node->count = new_sum; + if (orig_node->self_recursive_p ()) + new_node->count = (orig_sum + new_sum).apply_scale (5, 10); + else + new_node->count = new_sum; orig_node->count = remainder; profile_count::adjust_for_ipa_scaling (&new_sum, &orig_new_node_count); diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index a142e0cc8f6..520ed39b476 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -1371,21 +1371,6 @@ ignore_edge_for_nothrow (struct cgraph_edge *e) || !opt_for_fn (ultimate_target->decl, flag_ipa_pure_const)); } -/* Return true if NODE is self recursive function. - Indirectly recursive functions appears as non-trivial strongly - connected components, so we need to care about self recursion - only. */ - -static bool -self_recursive_p (struct cgraph_node *node) -{ - struct cgraph_edge *e; - for (e = node->callees; e; e = e->next_callee) - if (e->callee->function_symbol () == node) - return true; - return false; -} - /* Return true if N is cdtor that is not const or pure. In this case we may need to remove unreachable function if it is marked const/pure. */ @@ -1666,7 +1651,7 @@ propagate_pure_const (void) if (this_state == IPA_NEITHER) this_looping = w_l->looping_previously_known; } - if (!this_looping && self_recursive_p (w)) + if (!this_looping && w->self_recursive_p ()) this_looping = true; if (!w_l->looping_previously_known) this_looping = false; @@ -2342,7 +2327,7 @@ pass_nothrow::execute (function *) node->set_nothrow_flag (true); bool cfg_changed = false; - if (self_recursive_p (node)) + if (node->self_recursive_p ()) FOR_EACH_BB_FN (this_block, cfun) if (gimple *g = last_stmt (this_block)) if (is_gimple_call (g)) -- 2.21.0.777.g83232e3864