OSDN Git Service

* cgraph.c (cgraph_clone_node): Add redirect_callers parameter.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 1 Oct 2009 23:20:15 +0000 (23:20 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 1 Oct 2009 23:20:15 +0000 (23:20 +0000)
(cgraph_create_virtual_clone): Just pass redirect_callers
around.
* cgraph.h (cgraph_clone_node): Update prototype.
* ipa-pure-const.c (self_recursive_p): New function.
(propagate): Use it.
* ipa-inline.c (cgraph_clone_inlined_nodes,
* cgraph_decide_recursive_inlining): Update.
* gcc.dg/tree-ssa/ipa-cp-1.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152388 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/ipa-inline.c
gcc/ipa-pure-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c [new file with mode: 0644]

index cdaee93..aebdbff 100644 (file)
@@ -1,3 +1,14 @@
+2009-10-01  Jan Hubicka  <jh@suse.cz>
+
+       * cgraph.c (cgraph_clone_node): Add redirect_callers parameter.
+       (cgraph_create_virtual_clone): Just pass redirect_callers
+       around.
+       * cgraph.h (cgraph_clone_node): Update prototype.
+       * ipa-pure-const.c (self_recursive_p): New function.
+       (propagate): Use it.
+       * ipa-inline.c (cgraph_clone_inlined_nodes,
+       cgraph_decide_recursive_inlining): Update.
+
 2009-10-01  David Daney  <ddaney@caviumnetworks.com>
 
        * gcc/config/mips/mips.c (mips_process_sync_loop) Emit syncw
index 75447be..15dd60a 100644 (file)
@@ -1656,11 +1656,13 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
    by node.  */
 struct cgraph_node *
 cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq,
-                  int loop_nest, bool update_original)
+                  int loop_nest, bool update_original,
+                  VEC(cgraph_edge_p,heap) *redirect_callers)
 {
   struct cgraph_node *new_node = cgraph_create_node ();
   struct cgraph_edge *e;
   gcov_type count_scale;
+  unsigned i;
 
   new_node->decl = n->decl;
   new_node->origin = n->origin;
@@ -1691,6 +1693,14 @@ cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq,
        n->count = 0;
     }
 
+  for (i = 0; VEC_iterate (cgraph_edge_p, redirect_callers, i, e); i++)
+    {
+      /* Redirect calls to the old version node to point to its new
+        version.  */
+      cgraph_redirect_edge_callee (e, new_node);
+    }
+
+
   for (e = n->callees;e; e=e->next_callee)
     cgraph_clone_edge (e, new_node, e->call_stmt, count_scale, freq, loop_nest,
                       update_original);
@@ -1744,8 +1754,6 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
   struct cgraph_node *new_node = NULL;
   tree new_decl;
   struct cgraph_node key, **slot;
-  unsigned i;
-  struct cgraph_edge *e;
 
   gcc_assert  (tree_versionable_function_p (old_decl));
 
@@ -1762,7 +1770,8 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
   SET_DECL_RTL (new_decl, NULL);
 
   new_node = cgraph_clone_node (old_node, old_node->count,
-                               CGRAPH_FREQ_BASE, 0, false);
+                               CGRAPH_FREQ_BASE, 0, false,
+                               redirect_callers);
   new_node->decl = new_decl;
   /* Update the properties.
      Make clone visible only within this translation unit.  Make sure
@@ -1821,13 +1830,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
       gcc_assert (!*aslot);
       *aslot = new_node;
     }
-   for (i = 0; VEC_iterate (cgraph_edge_p, redirect_callers, i, e); i++)
-     {
-       /* Redirect calls to the old version node to point to its new
-         version.  */
-       cgraph_redirect_edge_callee (e, new_node);
-     }
-  
+
   return new_node;
 }
 
index 67670ef..292eccd 100644 (file)
@@ -409,7 +409,7 @@ struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *,
                                        struct cgraph_node *,
                                        gimple, gcov_type, int, int, bool);
 struct cgraph_node * cgraph_clone_node (struct cgraph_node *, gcov_type, int,
-                                       int, bool);
+                                       int, bool, VEC(cgraph_edge_p,heap) *);
 
 void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
 
index 662e13f..8851d60 100644 (file)
@@ -238,7 +238,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
        {
          struct cgraph_node *n;
          n = cgraph_clone_node (e->callee, e->count, e->frequency, e->loop_nest, 
-                                update_original);
+                                update_original, NULL);
          cgraph_redirect_edge_callee (e, n);
        }
     }
@@ -723,7 +723,8 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node,
             cgraph_node_name (node));
 
   /* We need original clone to copy around.  */
-  master_clone = cgraph_clone_node (node, node->count, CGRAPH_FREQ_BASE, 1, false);
+  master_clone = cgraph_clone_node (node, node->count, CGRAPH_FREQ_BASE, 1,
+                                   false, NULL);
   master_clone->needed = true;
   for (e = master_clone->callees; e; e = e->next_callee)
     if (!e->inline_failed)
index e5ff3a7..04d4e11 100644 (file)
@@ -688,6 +688,18 @@ ignore_edge (struct cgraph_edge *e)
   return (!e->can_throw_external);
 }
 
+/* Return true if NODE is self recursive function.  */
+
+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 == node)
+      return true;
+  return false;
+}
+
 /* Produce the global information by preforming a transitive closure
    on the local information that was produced by generate_summary.
    Note that there is no function_transform pass since this only
@@ -776,6 +788,8 @@ propagate (void)
          if (w_l->state_previously_known != IPA_NEITHER
              && this_state > w_l->state_previously_known)
             this_state = w_l->state_previously_known;
+         if (!this_looping && self_recursive_p (w))
+           this_looping = true;
          if (!w_l->looping_previously_known)
            this_looping = false;
 
index 1d34fb7..a981836 100644 (file)
@@ -1,3 +1,7 @@
+2009-10-01  Jan Hubicka  <jh@suse.cz>
+
+       * gcc.dg/tree-ssa/ipa-cp-1.c: New testcase.
+
 2009-10-01  Loren J. Rittle  <ljrittle@acm.org>
 
        * gcc.dg/20021014-1.c (*-*-freebsd*): Use dg-message.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c
new file mode 100644 (file)
index 0000000..bd24446
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized -fno-inline" } */
+int
+very_long_function(int a)
+{
+  return very_long_function (a)/4;
+}
+main()
+{
+  very_long_function (1);
+}
+/* One appereance for dump, one self recursive call and one call from main.  */
+/* { dg-final { scan-tree-dump-times "very_long_function.clone.0 \\(\\)" 3 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized -fno-inline" } */
+int
+very_long_function(int a)
+{
+  return very_long_function (a)/4;
+}
+main()
+{
+  very_long_function (1);
+}
+/* One appereance for dump, one self recursive call and one call from main.  */
+/* { dg-final { scan-tree-dump-times "very_long_function.clone.0 \\(\\)" 3 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized -fno-inline" } */
+int
+very_long_function(int a)
+{
+  return very_long_function (a)/4;
+}
+main()
+{
+  very_long_function (1);
+}
+/* One appereance for dump, one self recursive call and one call from main.  */
+/* { dg-final { scan-tree-dump-times "very_long_function.clone.0 \\(\\)" 3 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */