2016-01-26 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Jan 2016 11:51:01 +0000 (11:51 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Jan 2016 11:51:01 +0000 (11:51 +0000)
PR tree-optimization/69452
* tree-ssa-loop-im.c (move_computations_dom_walker): Remove.
(move_computations_dom_walker::before_dom_children): Rename
to ...
(move_computations_worker): This.
(move_computations): Perform an RPO rather than a DOM walk.

* gcc.dg/torture/pr69452.c: New testcase.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr69452.c [new file with mode: 0644]
gcc/tree-ssa-loop-im.c

index 17f9b2b..65b1fb3 100644 (file)
@@ -1,3 +1,12 @@
+2016-01-26  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/69452
+       * tree-ssa-loop-im.c (move_computations_dom_walker): Remove.
+       (move_computations_dom_walker::before_dom_children): Rename
+       to ...
+       (move_computations_worker): This.
+       (move_computations): Perform an RPO rather than a DOM walk.
+
 2016-01-26  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/69442
index 67bc4e4..ec6456a 100644 (file)
@@ -1,3 +1,8 @@
+2016-01-26  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/69452
+       * gcc.dg/torture/pr69452.c: New testcase.
+
 2016-01-26  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/69442
diff --git a/gcc/testsuite/gcc.dg/torture/pr69452.c b/gcc/testsuite/gcc.dg/torture/pr69452.c
new file mode 100644 (file)
index 0000000..8bd931d
--- /dev/null
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+
+short a, f, h;
+struct S0 {
+    int f0;
+} b;
+char c, d, e, j, k;
+int g;
+char fn1(char p1, int p2) { return 7 >> p2 ? p1 : p2; }
+void fn2() {
+    int l, m, n;
+    struct S0 o = {0};
+    for (;;) {
+       int p = 1, r = e;
+       unsigned q = 6;
+       l = r == 0 ? q : q % r;
+       n = l;
+       c = f;
+       k = fn1(p, n ^ e);
+       char s = k;
+       j = s / 6;
+       if (j) {
+           int t = d, u = m = d ? t : t / d;
+           h = a || u;
+           b.f0 = h;
+           for (; d;)
+             ;
+       } else {
+           b = o;
+           if (d != g)
+             for (;;)
+               ;
+       }
+    }
+}
index e1b22de..ec0fb7f 100644 (file)
@@ -1112,15 +1112,16 @@ public:
    data stored in LIM_DATA structures associated with each statement.  Callback
    for walk_dominator_tree.  */
 
-edge
-move_computations_dom_walker::before_dom_children (basic_block bb)
+unsigned int
+move_computations_worker (basic_block bb)
 {
   struct loop *level;
   unsigned cost = 0;
   struct lim_aux_data *lim_data;
+  unsigned int todo = 0;
 
   if (!loop_outer (bb->loop_father))
-    return NULL;
+    return todo;
 
   for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi); )
     {
@@ -1171,7 +1172,7 @@ move_computations_dom_walker::before_dom_children (basic_block bb)
                      gimple_cond_lhs (cond), gimple_cond_rhs (cond));
          new_stmt = gimple_build_assign (gimple_phi_result (stmt),
                                          COND_EXPR, t, arg0, arg1);
-         todo_ |= TODO_cleanup_cfg;
+         todo |= TODO_cleanup_cfg;
        }
       if (INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (new_stmt)))
          && (!ALWAYS_EXECUTED_IN (bb)
@@ -1266,7 +1267,8 @@ move_computations_dom_walker::before_dom_children (basic_block bb)
       else
        gsi_insert_on_edge (e, stmt);
     }
-  return NULL;
+
+  return todo;
 }
 
 /* Hoist the statements out of the loops prescribed by data stored in
@@ -1275,14 +1277,20 @@ move_computations_dom_walker::before_dom_children (basic_block bb)
 static unsigned int
 move_computations (void)
 {
-  move_computations_dom_walker walker (CDI_DOMINATORS);
-  walker.walk (cfun->cfg->x_entry_block_ptr);
+  int *rpo = XNEWVEC (int, last_basic_block_for_fn (cfun));
+  int n = pre_and_rev_post_order_compute_fn (cfun, NULL, rpo, false);
+  unsigned todo = 0;
+
+  for (int i = 0; i < n; ++i)
+    todo |= move_computations_worker (BASIC_BLOCK_FOR_FN (cfun, rpo[i]));
+
+  free (rpo);
 
   gsi_commit_edge_inserts ();
   if (need_ssa_update_p (cfun))
     rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
 
-  return walker.todo_;
+  return todo;
 }
 
 /* Checks whether the statement defining variable *INDEX can be hoisted