loop-unroll.c (unroll_loop_runtime_iterations): Condition initial loop peel to loops...
authorPat Haugen <pthaugen@us.ibm.com>
Fri, 14 Oct 2016 17:21:19 +0000 (17:21 +0000)
committerPat Haugen <pthaugen@gcc.gnu.org>
Fri, 14 Oct 2016 17:21:19 +0000 (17:21 +0000)
* loop-unroll.c (unroll_loop_runtime_iterations): Condition initial
loop peel to loops with exit test at the beginning.

From-SVN: r241173

gcc/ChangeLog
gcc/loop-unroll.c

index c555f22f0e4e120d87024f5a7ea3c8521818c089..a998060b3b3f215df2ad099bc5085a7c7d1e9e74 100644 (file)
@@ -1,3 +1,8 @@
+2016-10-14  Pat Haugen  <pthaugen@us.ibm.com>
+
+       * loop-unroll.c (unroll_loop_runtime_iterations): Condition initial
+       loop peel to loops with exit test at the beginning.
+
 2016-10-14  Pat Haugen  <pthaugen@us.ibm.com>
 
        PR rtl-optimization/68212
index f412698f17002d5fa2ce4a399defc05d903b43e6..91118a310d004ec4d1f9da731206a5a86dc30ea9 100644 (file)
@@ -858,7 +858,7 @@ unroll_loop_runtime_iterations (struct loop *loop)
   rtx old_niter, niter, tmp;
   rtx_insn *init_code, *branch_code;
   unsigned i, j, p;
-  basic_block preheader, *body, swtch, ezc_swtch;
+  basic_block preheader, *body, swtch, ezc_swtch = NULL;
   int may_exit_copy, iter_freq, new_freq;
   gcov_type iter_count, new_count;
   unsigned n_peel;
@@ -918,6 +918,16 @@ unroll_loop_runtime_iterations (struct loop *loop)
   if (tmp != niter)
     emit_move_insn (niter, tmp);
 
+  /* For loops that exit at end, add one to niter to account for first pass
+     through loop body before reaching exit test. */
+  if (exit_at_end)
+    {
+      niter = expand_simple_binop (desc->mode, PLUS,
+                                  niter, const1_rtx,
+                                  NULL_RTX, 0, OPTAB_LIB_WIDEN);
+      old_niter = niter;
+    }
+
   /* Count modulo by ANDing it with max_unroll; we use the fact that
      the number of unrollings is a power of two, and thus this is correct
      even if there is overflow in the computation.  */
@@ -936,20 +946,21 @@ unroll_loop_runtime_iterations (struct loop *loop)
 
   auto_sbitmap wont_exit (max_unroll + 2);
 
-  /* Peel the first copy of loop body (almost always we must leave exit test
-     here; the only exception is when we have extra zero check and the number
-     of iterations is reliable.  Also record the place of (possible) extra
-     zero check.  */
-  bitmap_clear (wont_exit);
-  if (extra_zero_check
-      && !desc->noloop_assumptions)
-    bitmap_set_bit (wont_exit, 1);
-  ezc_swtch = loop_preheader_edge (loop)->src;
-  ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
-                                     1, wont_exit, desc->out_edge,
-                                     &remove_edges,
-                                     DLTHE_FLAG_UPDATE_FREQ);
-  gcc_assert (ok);
+  if (extra_zero_check)
+    {
+      /* Peel the first copy of loop body.  Leave the exit test if the number
+        of iterations is not reliable.  Also record the place of the extra zero
+        check.  */
+      bitmap_clear (wont_exit);
+      if (!desc->noloop_assumptions)
+       bitmap_set_bit (wont_exit, 1);
+      ezc_swtch = loop_preheader_edge (loop)->src;
+      ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
+                                         1, wont_exit, desc->out_edge,
+                                         &remove_edges,
+                                         DLTHE_FLAG_UPDATE_FREQ);
+      gcc_assert (ok);
+    }
 
   /* Record the place where switch will be built for preconditioning.  */
   swtch = split_edge (loop_preheader_edge (loop));