re PR tree-optimization/58459 (Loop invariant is not hoisted out of loop after r202525.)
authorRichard Biener <rguenther@suse.de>
Fri, 27 Sep 2013 08:14:53 +0000 (08:14 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 27 Sep 2013 08:14:53 +0000 (08:14 +0000)
2013-09-27  Richard Biener  <rguenther@suse.de>

PR tree-optimization/58459
* tree-ssa-forwprop.c (forward_propagate_addr_expr): Remove
restriction not propagating into loops.

* gcc.dg/tree-ssa/ssa-pre-31.c: New testcase.

From-SVN: r202966

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-31.c [new file with mode: 0644]
gcc/tree-ssa-forwprop.c

index 484d868b88b676d98aa5a991bd9290915bf2e2b3..5cb2a52165746a9adc04486822ec3ebc44c40fcf 100644 (file)
@@ -1,3 +1,9 @@
+2013-09-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/58459
+       * tree-ssa-forwprop.c (forward_propagate_addr_expr): Remove
+       restriction not propagating into loops.
+
 2013-09-26  Florian Weimer  <fw@deneb.enyo.de>
 
        * tree-ssa.h (walk_use_def_chains_fn, walk_use_def_chains): Delete.
index b35d8b5e52bd737b0dbd80d72d7a83df19c0a0b8..094fafc35a7ca862101a34b04ac8188e8ed64ea9 100644 (file)
@@ -1,3 +1,8 @@
+2013-09-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/58459
+       * gcc.dg/tree-ssa/ssa-pre-31.c: New testcase.
+
 2013-09-26  Bernd Edlinger  <bernd.edlinger@hotmail.de>
 
        PR fortran/58113
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-31.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-31.c
new file mode 100644 (file)
index 0000000..2094de4
--- /dev/null
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-pre" } */
+
+typedef struct {
+    unsigned int key;
+} S;
+typedef struct s1  {
+    unsigned int key;
+    unsigned int bits;
+    struct s1 *left, *right;
+}S1;
+extern S a[1024];
+static inline int bar( S* p, S1* n )
+{
+  S1 *curr;
+  S1 *next;
+
+  if ( n->left == n )
+    return (int)(p->key == n->key);
+
+  curr = n;
+  next = n->left;
+
+  while (curr->bits > next->bits ) {
+      curr = next;
+      if (p->key & (1 << curr->bits))
+       next = curr->right;
+      else
+       next = curr->left;
+  }
+
+  return (int)(p->key == next->key);
+
+}
+
+int foo (S1 *root, int N)
+{
+  volatile int r;
+  int i,j;
+  for (i=0; i<N; i++)
+    for (j=0;j<1024; j++)
+      r = bar(&a[j], root);
+  return 0;
+} 
+
+/* { dg-final { scan-tree-dump-times "key" 4 "pre" } } */
+/* { dg-final { cleanup-tree-dump "pre" } } */
index f1a407774fb6d3bb1d4f2777d5adee33d0e14c30..ddcfe4c24be0f2a8ec95f19b46195fd3c7c6e44b 100644 (file)
@@ -1001,7 +1001,6 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
 static bool
 forward_propagate_addr_expr (tree name, tree rhs)
 {
-  int stmt_loop_depth = bb_loop_depth (gimple_bb (SSA_NAME_DEF_STMT (name)));
   imm_use_iterator iter;
   gimple use_stmt;
   bool all = true;
@@ -1014,37 +1013,24 @@ forward_propagate_addr_expr (tree name, tree rhs)
 
       /* If the use is not in a simple assignment statement, then
         there is nothing we can do.  */
-      if (gimple_code (use_stmt) != GIMPLE_ASSIGN)
+      if (!is_gimple_assign (use_stmt))
        {
          if (!is_gimple_debug (use_stmt))
            all = false;
          continue;
        }
 
-      /* If the use is in a deeper loop nest, then we do not want
-        to propagate non-invariant ADDR_EXPRs into the loop as that
-        is likely adding expression evaluations into the loop.  */
-      if (bb_loop_depth (gimple_bb (use_stmt)) > stmt_loop_depth
-         && !is_gimple_min_invariant (rhs))
+      gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
+      result = forward_propagate_addr_expr_1 (name, rhs, &gsi,
+                                             single_use_p);
+      /* If the use has moved to a different statement adjust
+        the update machinery for the old statement too.  */
+      if (use_stmt != gsi_stmt (gsi))
        {
-         all = false;
-         continue;
+         update_stmt (use_stmt);
+         use_stmt = gsi_stmt (gsi);
        }
-
-      {
-       gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
-       result = forward_propagate_addr_expr_1 (name, rhs, &gsi,
-                                               single_use_p);
-       /* If the use has moved to a different statement adjust
-          the update machinery for the old statement too.  */
-       if (use_stmt != gsi_stmt (gsi))
-         {
-           update_stmt (use_stmt);
-           use_stmt = gsi_stmt (gsi);
-         }
-
-       update_stmt (use_stmt);
-      }
+      update_stmt (use_stmt);
       all &= result;
 
       /* Remove intermediate now unused copy and conversion chains.  */