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

Reply via email to