OSDN Git Service

* class.c, gjavah.c, parse.y, verify.c: Don't use PTR.
[pf3gnuchains/gcc-fork.git] / gcc / doloop.c
index f79fbad..4f9eaff 100644 (file)
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "rtl.h"
 #include "flags.h"
 #include "expr.h"
@@ -339,6 +341,7 @@ doloop_valid_p (loop, jump_insn)
      condition at run-time and have an additional jump around the loop
      to ensure an infinite loop.  */
   if (loop_info->comparison_code == NE
+      && !loop_info->preconditioned
       && INTVAL (loop_info->increment) != -1
       && INTVAL (loop_info->increment) != 1)
     {
@@ -598,16 +601,19 @@ doloop_modify_runtime (loop, iterations_max,
 
      If the loop has been unrolled, the full calculation is
 
-       t1 = abs_inc * unroll_number;           increment per loop
-       n = abs (final - initial) / t1;         full loops
-       n += (abs (final - initial) % t1) != 0; partial loop
+       t1 = abs_inc * unroll_number;                   increment per loop
+       n = (abs (final - initial) + abs_inc - 1) / t1;    full loops
+       n += (abs (final - initial) + abs_inc - 1) % t1) >= abs_inc;
+                                                          partial loop
+     which works out to be equivalent to
 
-     However, in certain cases the unrolled loop will be preconditioned
-     by emitting copies of the loop body with conditional branches,
-     so that the unrolled loop is always a full loop and thus needs
-     no exit tests.  In this case we don't want to add the partial
-     loop count.  As above, when t1 is a power of two we don't need to
-     worry about overflow.
+       n = (abs (final - initial) + t1 - 1) / t1;
+
+     In the case where the loop was preconditioned, a few iterations
+     may have been executed earlier; but 'initial' was adjusted as they
+     were executed, so we don't need anything special for that case here.
+     As above, when t1 is a power of two we don't need to worry about
+     overflow.
 
      The division and modulo operations can be avoided by requiring
      that the increment is a power of 2 (precondition_loop_p enforces
@@ -668,8 +674,8 @@ doloop_modify_runtime (loop, iterations_max,
            fprintf (loop_dump_stream,
                 "Doloop: Basic induction var skips initial incr.\n");
 
-         diff = expand_simple_binop (mode, PLUS, diff, increment, diff,
-                                     unsigned_p, OPTAB_LIB_WIDEN);
+         diff = expand_simple_binop (mode, PLUS, diff, GEN_INT (abs_inc),
+                                     diff, unsigned_p, OPTAB_LIB_WIDEN);
        }
     }
 
@@ -682,10 +688,10 @@ doloop_modify_runtime (loop, iterations_max,
       if (shift_count < 0)
        abort ();
 
-      if (!loop_info->preconditioned)
-       diff = expand_simple_binop (GET_MODE (diff), PLUS,
-                                   diff, GEN_INT (abs_loop_inc - 1),
-                                   diff, 1, OPTAB_LIB_WIDEN);
+      /* (abs (final - initial) + abs_inc * unroll_number - 1) */
+      diff = expand_simple_binop (GET_MODE (diff), PLUS,
+                                 diff, GEN_INT (abs_loop_inc - 1),
+                                 diff, 1, OPTAB_LIB_WIDEN);
 
       /* (abs (final - initial) + abs_inc * unroll_number - 1)
         / (abs_inc * unroll_number)  */