tree-vect-loop-manip.c (slpeel_add_loop_guard): New param and mark new edge's irreduc...
authorBin Cheng <amker@gcc.gnu.org>
Tue, 28 Mar 2017 15:32:29 +0000 (15:32 +0000)
committerBin Cheng <amker@gcc.gnu.org>
Tue, 28 Mar 2017 15:32:29 +0000 (15:32 +0000)
* tree-vect-loop-manip.c (slpeel_add_loop_guard): New param and
mark new edge's irreducible flag accordign to it.
(vect_do_peeling): Check loop preheader edge's irreducible flag
and pass it to function slpeel_add_loop_guard.
gcc/testsuite
* gcc.c-torture/compile/irreducible-loop.c: New.

From-SVN: r246540

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/irreducible-loop.c [new file with mode: 0644]
gcc/tree-vect-loop-manip.c

index 19b9d578508c652227d736301c8a64eb9535cd6b..fa216e904ab93af81b0de5bcc441987f0e25803c 100644 (file)
@@ -1,3 +1,10 @@
+2017-03-28  Bin Cheng  <bin.cheng@arm.com>
+
+       * tree-vect-loop-manip.c (slpeel_add_loop_guard): New param and
+       mark new edge's irreducible flag accordign to it.
+       (vect_do_peeling): Check loop preheader edge's irreducible flag
+       and pass it to function slpeel_add_loop_guard.
+
 2017-03-28  Richard Sandiford  <richard.sandiford@arm.com>
 
        PR tree-optimization/80218
index 8cbbc16220ea56a3dceed36f0623b1a1fc0d3c8d..446096199d425b3c06fecdafb75db7d16d17abe2 100644 (file)
@@ -1,6 +1,10 @@
+2017-03-28  Bin Cheng  <bin.cheng@arm.com>
+
+       * gcc.c-torture/compile/irreducible-loop.c: New.
+
 2017-03-28  Richard Sandiford  <richard.sandiford@arm.com>
 
-        PR tree-optimization/80218
+       PR tree-optimization/80218
        * gcc.dg/pr80218.c: New test.
 
 2017-03-28  Richard Biener  <rguenther@suse.de>
diff --git a/gcc/testsuite/gcc.c-torture/compile/irreducible-loop.c b/gcc/testsuite/gcc.c-torture/compile/irreducible-loop.c
new file mode 100644 (file)
index 0000000..e4be667
--- /dev/null
@@ -0,0 +1,21 @@
+void foo (int n, double a, double *b, double *x)
+{
+  int i, j;
+
+  if(n <= 0) return;
+  if (a == 0.0e0) return;
+
+  if (a > 5.0)
+    {
+      i = 0;
+      goto sec;
+    }
+  for (i = 0; i < 1024; i++)
+    {
+      double y = b[i];
+sec:
+      b[i+1] = y + 5.0;
+      for (j = 0; j < n; j++)
+       x[j] = x[j] + a;
+    }
+}
index 2f82061afa9720831d5742c386627cfccfe06f39..f48336bff5858a3866d41af172a8384a1d3ba5ed 100644 (file)
@@ -534,12 +534,13 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop,
 /* Given the condition expression COND, put it as the last statement of
    GUARD_BB; set both edges' probability; set dominator of GUARD_TO to
    DOM_BB; return the skip edge.  GUARD_TO is the target basic block to
-   skip the loop.  PROBABILITY is the skip edge's probability.  */
+   skip the loop.  PROBABILITY is the skip edge's probability.  Mark the
+   new edge as irreducible if IRREDUCIBLE_P is true.  */
 
 static edge
 slpeel_add_loop_guard (basic_block guard_bb, tree cond,
                       basic_block guard_to, basic_block dom_bb,
-                      int probability)
+                      int probability, bool irreducible_p)
 {
   gimple_stmt_iterator gsi;
   edge new_e, enter_e;
@@ -566,6 +567,9 @@ slpeel_add_loop_guard (basic_block guard_bb, tree cond,
   new_e->count = guard_bb->count;
   new_e->probability = probability;
   new_e->count = apply_probability (enter_e->count, probability);
+  if (irreducible_p)
+    new_e->flags |= EDGE_IRREDUCIBLE_LOOP;
+
   enter_e->count -= new_e->count;
   enter_e->probability = inverse_probability (probability);
   set_immediate_dominator (CDI_DOMINATORS, guard_to, dom_bb);
@@ -1667,6 +1671,7 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
 
   struct loop *prolog, *epilog = NULL, *loop = LOOP_VINFO_LOOP (loop_vinfo);
   struct loop *first_loop = loop;
+  bool irred_flag = loop_preheader_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP;
   create_lcssa_for_virtual_phi (loop);
   update_ssa (TODO_update_ssa_only_virtuals);
 
@@ -1748,7 +1753,8 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
          guard_to = split_edge (loop_preheader_edge (loop));
          guard_e = slpeel_add_loop_guard (guard_bb, guard_cond,
                                           guard_to, guard_bb,
-                                          inverse_probability (prob_prolog));
+                                          inverse_probability (prob_prolog),
+                                          irred_flag);
          e = EDGE_PRED (guard_to, 0);
          e = (e != guard_e ? e : EDGE_PRED (guard_to, 1));
          slpeel_update_phi_nodes_for_guard1 (prolog, loop, guard_e, e);
@@ -1813,7 +1819,8 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
          guard_to = split_edge (loop_preheader_edge (epilog));
          guard_e = slpeel_add_loop_guard (guard_bb, guard_cond,
                                           guard_to, guard_bb,
-                                          inverse_probability (prob_vector));
+                                          inverse_probability (prob_vector),
+                                          irred_flag);
          e = EDGE_PRED (guard_to, 0);
          e = (e != guard_e ? e : EDGE_PRED (guard_to, 1));
          slpeel_update_phi_nodes_for_guard1 (first_loop, epilog, guard_e, e);
@@ -1853,7 +1860,8 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
          guard_to = split_edge (single_exit (epilog));
          guard_e = slpeel_add_loop_guard (guard_bb, guard_cond, guard_to,
                                           skip_vector ? anchor : guard_bb,
-                                          inverse_probability (prob_epilog));
+                                          inverse_probability (prob_epilog),
+                                          irred_flag);
          slpeel_update_phi_nodes_for_guard2 (loop, epilog, guard_e,
                                              single_exit (epilog));
          /* Only need to handle basic block before epilog loop if it's not