]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
doloop.c (doloop_valid_p): Correct comment.
authorAlan Modra <amodra@bigpond.net.au>
Mon, 24 Jun 2002 02:16:42 +0000 (02:16 +0000)
committerAlan Modra <amodra@gcc.gnu.org>
Mon, 24 Jun 2002 02:16:42 +0000 (11:46 +0930)
* doloop.c (doloop_valid_p): Correct comment.
(doloop_modify_runtime <abs_inc != 1>): Simplify.
(doloop_modify_runtime <do-while>): Don't emit code when NE.

From-SVN: r54938

gcc/ChangeLog
gcc/doloop.c

index bf84a9460785a9477e25a3a19c91d7055be2103c..25a13a3627c297b2a0cf5648c86df6797f87f081 100644 (file)
@@ -1,3 +1,9 @@
+2002-06-24  Alan Modra  <amodra@bigpond.net.au>
+
+       * doloop.c (doloop_valid_p): Correct comment.
+       (doloop_modify_runtime <abs_inc != 1>): Simplify.
+       (doloop_modify_runtime <do-while>): Don't emit code when NE.
+
 Thu Jun 20 00:26:53 2002  Denis Chertykov  <denisc@overta.ru>
 
        * config.gcc: Add support for ip2k.
index de59562f6bb9cbb24a424516932e825b623dfb64..ee5b788a911c6507f02dd0013eb563e9029968b2 100644 (file)
@@ -361,8 +361,8 @@ doloop_valid_p (loop, jump_insn)
     {
       /* If the comparison is LEU and the comparison value is UINT_MAX
         then the loop will not terminate.  Similarly, if the
-        comparison code is GEU and the initial value is 0, the loop
-        will not terminate.
+        comparison code is GEU and the comparison value is 0, the
+        loop will not terminate.
 
         If the absolute increment is not 1, the loop can be infinite
         even with LTU/GTU, e.g. for (i = 3; i > 0; i -= 2)
@@ -591,6 +591,10 @@ doloop_modify_runtime (loop, iterations_max,
        n = abs (final - initial) / abs_inc;
        n += (abs (final - initial) % abs_inc) != 0;
 
+     But when abs_inc is a power of two, the summation won't overflow
+     except in cases where the loop never terminates.  So we don't
+     need to use this more costly calculation.
+
      If the loop has been unrolled, then the loop body has been
      preconditioned to iterate a multiple of unroll_number times.  If
      abs_inc is != 1, the full calculation is
@@ -666,50 +670,22 @@ doloop_modify_runtime (loop, iterations_max,
   if (abs_inc * loop_info->unroll_number != 1)
     {
       int shift_count;
-      rtx extra;
-      rtx label;
-      unsigned HOST_WIDE_INT limit;
 
       shift_count = exact_log2 (abs_inc * loop_info->unroll_number);
       if (shift_count < 0)
        abort ();
 
-      /* abs (final - initial) / (abs_inc * unroll_number)  */
-      iterations = expand_simple_binop (GET_MODE (diff), LSHIFTRT,
-                                       diff, GEN_INT (shift_count),
-                                       NULL_RTX, 1,
-                                       OPTAB_LIB_WIDEN);
-
       if (abs_inc != 1)
-       {
-         /* abs (final - initial) % (abs_inc * unroll_number)  */
-         rtx count = GEN_INT (abs_inc * loop_info->unroll_number - 1);
-         extra = expand_simple_binop (GET_MODE (iterations), AND,
-                                      diff, count, NULL_RTX, 1,
-                                      OPTAB_LIB_WIDEN);
-
-         /* If (abs (final - initial) % (abs_inc * unroll_number)
-              <= abs_inc * (unroll - 1)),
-            jump past following increment instruction.  */
-         label = gen_label_rtx ();
-         limit = abs_inc * (loop_info->unroll_number - 1);
-         emit_cmp_and_jump_insns (extra, GEN_INT (limit),
-                                  limit == 0 ? EQ : LEU, NULL_RTX,
-                                  GET_MODE (extra), 0, label);
-         JUMP_LABEL (get_last_insn ()) = label;
-         LABEL_NUSES (label)++;
-
-         /* Increment the iteration count by one.  */
-         iterations = expand_simple_binop (GET_MODE (iterations), PLUS,
-                                           iterations, GEN_INT (1),
-                                           iterations, 1,
-                                           OPTAB_LIB_WIDEN);
-
-         emit_label (label);
-       }
+       diff = expand_simple_binop (GET_MODE (diff), PLUS,
+                                   diff, GEN_INT (abs_inc - 1),
+                                   diff, 1, OPTAB_LIB_WIDEN);
+
+      /* (abs (final - initial) + abs_inc - 1) / (abs_inc * unroll_number)  */
+      diff = expand_simple_binop (GET_MODE (diff), LSHIFTRT,
+                                 diff, GEN_INT (shift_count),
+                                 diff, 1, OPTAB_LIB_WIDEN);
     }
-  else
-    iterations = diff;
+  iterations = diff;
 
   /* If there is a NOTE_INSN_LOOP_VTOP, we have a `for' or `while'
      style loop, with a loop exit test at the start.  Thus, we can
@@ -722,17 +698,20 @@ doloop_modify_runtime (loop, iterations_max,
      iteration count to one if necessary.  */
   if (! loop->vtop)
     {
-      rtx label;
-
       if (loop_dump_stream)
        fprintf (loop_dump_stream, "Doloop: Do-while loop.\n");
 
-      /* A `do-while' loop must iterate at least once.  If the
-        iteration count is bogus, we set the iteration count to 1.
+      /* A `do-while' loop must iterate at least once.  For code like
+        i = initial; do { ... } while (++i < final);
+        we will calculate a bogus iteration count if initial > final.
+        So detect this and set the iteration count to 1.
         Note that if the loop has been unrolled, then the loop body
-        is guaranteed to execute at least once.  */
-      if (loop_info->unroll_number == 1)
+        is guaranteed to execute at least once.  Also, when the
+        comparison is NE, our calculated count will be OK.  */
+      if (loop_info->unroll_number == 1 && comparison_code != NE)
        {
+         rtx label;
+
          /*  Emit insns to test if the loop will immediately
              terminate and to set the iteration count to 1 if true.  */
          label = gen_label_rtx();