OSDN Git Service

* loop.h (struct loop_info): Define new structure.
authorm.hayes <m.hayes@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 25 Nov 1998 21:19:21 +0000 (21:19 +0000)
committerm.hayes <m.hayes@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 25 Nov 1998 21:19:21 +0000 (21:19 +0000)
(precondition_loop_p): Added prototype.
(unroll_loop): Added new argument loop_info to prototype.
(final_biv_value, final_giv_value): Added new argument n_iterations
to prototype.
* loop.c (strength_reduce): Declare new structure loop_iteration_info
and new pointer loop_info.
(loop_n_iterations): Replace global variable by element in
loop_info structure.
(check_final_value): New argument n_iterations.
(insert_bct): New argument loop_info.
(loop_unroll_factor): Replace global array by element in
loop_info structure.
(loop_optimize): Remove code to allocate and initialise
loop_unroll_factor_array.
* unroll.c (precondition_loop_p):  No longer static since
used by branch on count optimization.
(precondition_loop_p, unroll_loop): New argument loop_info.
(final_biv_value, final_giv_value, find_splittable_regs): New
argument n_iterations.
(loop_iteration_var, loop_initial_value, loop_increment,
loop_final_value, loop_comparison_code, loop_unroll_factor):
Replaced global variables by loop_info structure.
(loop_unroll_factor): Replace global array by element in
loop_info structure.

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

gcc/ChangeLog
gcc/loop.c
gcc/loop.h
gcc/unroll.c

index d066040..e295f1c 100644 (file)
@@ -1,3 +1,32 @@
+Thu Nov 26 18:05:04 1998  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>
+
+       * loop.h (struct loop_info): Define new structure.
+       (precondition_loop_p): Added prototype.
+       (unroll_loop): Added new argument loop_info to prototype.
+       (final_biv_value, final_giv_value): Added new argument n_iterations
+       to prototype.
+       * loop.c (strength_reduce): Declare new structure loop_iteration_info
+       and new pointer loop_info.
+       (loop_n_iterations): Replace global variable by element in 
+       loop_info structure.
+       (check_final_value): New argument n_iterations.
+       (insert_bct): New argument loop_info.
+       (loop_unroll_factor): Replace global array by element in 
+       loop_info structure.
+       (loop_optimize): Remove code to allocate and initialise 
+       loop_unroll_factor_array.
+       * unroll.c (precondition_loop_p):  No longer static since
+       used by branch on count optimization.
+       (precondition_loop_p, unroll_loop): New argument loop_info.
+       (final_biv_value, final_giv_value, find_splittable_regs): New
+       argument n_iterations.
+       (loop_iteration_var, loop_initial_value, loop_increment, 
+       loop_final_value, loop_comparison_code, loop_unroll_factor): 
+       Replaced global variables by loop_info structure.
+       (loop_unroll_factor): Replace global array by element in
+       loop_info structure.
+
+
 Thu Nov 26 17:49:29 1998  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>
 
        * loop.c (check_dbra_loop): Update JUMP_LABEL field of jump insn
index 4fb5198..1d0e08d 100644 (file)
@@ -88,14 +88,6 @@ int *loop_outer_loop;
 int *loop_used_count_register;
 #endif  /* HAVE_decrement_and_branch_on_count */
 
-/* For each loop, keep track of its unrolling factor.
-   Potential values:
-      0: unrolled
-      1: not unrolled.
-     -1: completely unrolled
-     >0: holds the unroll exact factor.  */
-int *loop_unroll_factor;
-
 /* Indexed by loop number, contains a nonzero value if the "loop" isn't
    really a loop (an insn outside the loop branches into it).  */
 
@@ -118,14 +110,6 @@ rtx *loop_number_exit_labels;
 
 int *loop_number_exit_count;
 
-/* Holds the number of loop iterations.  It is zero if the number could not be
-   calculated.  Must be unsigned since the number of iterations can
-   be as high as 2^wordsize-1.  For loops with a wider iterator, this number
-   will be zero if the number of loop iterations is too large for an
-   unsigned integer to hold.  */
-
-unsigned HOST_WIDE_INT loop_n_iterations;
-
 /* Nonzero if there is a subroutine call in the current loop.  */
 
 static int loop_has_call;
@@ -320,7 +304,8 @@ static void find_single_use_in_loop PROTO((rtx, rtx, varray_type));
 static int valid_initial_value_p PROTO((rtx, rtx, int, rtx));
 static void find_mem_givs PROTO((rtx, rtx, int, rtx, rtx));
 static void record_biv PROTO((struct induction *, rtx, rtx, rtx, rtx, int, int));
-static void check_final_value PROTO((struct induction *, rtx, rtx));
+static void check_final_value PROTO((struct induction *, rtx, rtx, 
+                                    unsigned HOST_WIDE_INT));
 static void record_giv PROTO((struct induction *, rtx, rtx, rtx, rtx, rtx, int, enum g_types, int, rtx *, rtx, rtx));
 static void update_giv_derive PROTO((rtx));
 static int basic_induction_var PROTO((rtx, enum machine_mode, rtx, rtx, rtx *, rtx *));
@@ -365,7 +350,7 @@ typedef struct rtx_pair {
 
 #ifdef HAVE_decrement_and_branch_on_count
 /* Test whether BCT applicable and safe.  */
-static void insert_bct PROTO((rtx, rtx));
+static void insert_bct PROTO((rtx, rtx, struct loop_info *));
 
 /* Auxiliary function that inserts the BCT pattern into the loop.  */
 static void instrument_loop_bct PROTO((rtx, rtx, rtx));
@@ -478,12 +463,6 @@ loop_optimize (f, dumpfile, unroll_p, bct_p)
   loop_number_exit_labels = (rtx *) alloca (max_loop_num * sizeof (rtx));
   loop_number_exit_count = (int *) alloca (max_loop_num * sizeof (int));
 
-  /* This is initialized by the unrolling code, so we go ahead
-     and clear them just in case we are not performing loop
-     unrolling.  */
-  loop_unroll_factor = (int *) alloca (max_loop_num *sizeof (int));
-  bzero ((char *) loop_unroll_factor, max_loop_num * sizeof (int));
-
 #ifdef HAVE_decrement_and_branch_on_count
   /* Allocate for BCT optimization */
   loop_used_count_register = (int *) alloca (max_loop_num * sizeof (int));
@@ -3573,6 +3552,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
   rtx test;
   rtx end_insert_before;
   int loop_depth = 0;
+  struct loop_info loop_iteration_info;
+  struct loop_info *loop_info = &loop_iteration_info;
 
   reg_iv_type = (enum iv_mode *) alloca (max_reg_before_loop
                                         * sizeof (enum iv_mode));
@@ -3771,7 +3752,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
       /* Can still unroll the loop anyways, but indicate that there is no
         strength reduction info available.  */
       if (unroll_p)
-       unroll_loop (loop_end, insn_count, loop_start, end_insert_before, 0);
+       unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
+                    loop_info, 0);
 
       return;
     }
@@ -4040,7 +4022,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
      be called after all giv's have been identified, since otherwise it may
      fail if the iteration variable is a giv.  */
 
-  loop_n_iterations = loop_iterations (loop_start, loop_end);
+  loop_iterations (loop_start, loop_end, loop_info);
 
   /* Now for each giv for which we still don't know whether or not it is
      replaceable, check to see if it is replaceable because its final value
@@ -4053,7 +4035,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
 
       for (v = bl->giv; v; v = v->next_iv)
        if (! v->replaceable && ! v->not_replaceable)
-         check_final_value (v, loop_start, loop_end);
+         check_final_value (v, loop_start, loop_end, loop_info->n_iterations);
     }
 
   /* Try to prove that the loop counter variable (if any) is always
@@ -4099,7 +4081,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
           && ! bl->nonneg
 #endif
           && ! reg_mentioned_p (bl->biv->dest_reg, SET_SRC (bl->init_set)))
-         || ((final_value = final_biv_value (bl, loop_start, loop_end))
+         || ((final_value = final_biv_value (bl, loop_start, loop_end, 
+                                             loop_info->n_iterations))
 #ifdef HAVE_decrement_and_branch_until_zero
              && ! bl->nonneg
 #endif
@@ -4562,13 +4545,14 @@ strength_reduce (scan_start, end, loop_top, insn_count,
      collected.  */
   
   if (unroll_p)
-    unroll_loop (loop_end, insn_count, loop_start, end_insert_before, 1);
+    unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
+                loop_info, 1);
 
 #ifdef HAVE_decrement_and_branch_on_count
   /* Instrument the loop with BCT insn.  */
   if (HAVE_decrement_and_branch_on_count && bct_p
       && flag_branch_on_count_reg)
-    insert_bct (loop_start, loop_end);
+    insert_bct (loop_start, loop_end, loop_info);
 #endif  /* HAVE_decrement_and_branch_on_count */
 
   if (loop_dump_stream)
@@ -5058,9 +5042,10 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
    have been identified.  */
 
 static void
-check_final_value (v, loop_start, loop_end)
+check_final_value (v, loop_start, loop_end, n_iterations)
      struct induction *v;
      rtx loop_start, loop_end;
+     unsigned HOST_WIDE_INT n_iterations;
 {
   struct iv_class *bl;
   rtx final_value = 0;
@@ -5087,7 +5072,7 @@ check_final_value (v, loop_start, loop_end)
   v->replaceable = 0;
 #endif
 
-  if ((final_value = final_giv_value (v, loop_start, loop_end))
+  if ((final_value = final_giv_value (v, loop_start, loop_end, n_iterations))
       && (v->always_computable || last_use_this_basic_block (v->dest_reg, v->insn)))
     {
       int biv_increment_seen = 0;
@@ -7965,8 +7950,9 @@ get_condition_for_loop (x)
  */
 
 static void
-insert_bct (loop_start, loop_end)
+insert_bct (loop_start, loop_end, loop_info)
      rtx loop_start, loop_end;
+     struct loop_info *loop_info;
 {
   int i;
   unsigned HOST_WIDE_INT n_iterations;
@@ -7982,7 +7968,7 @@ insert_bct (loop_start, loop_end)
   int loop_num = uid_loop_num [INSN_UID (loop_start)];
 
   /* It's impossible to instrument a competely unrolled loop.  */
-  if (loop_unroll_factor [loop_num] == -1)
+  if (loop_info->unroll_number == -1)
     return;
 
   /* Make sure that the count register is not in use.  */
@@ -8040,10 +8026,10 @@ insert_bct (loop_start, loop_end)
     }
 
   /* Account for loop unrolling in instrumented iteration count.  */
-  if (loop_unroll_factor [loop_num] > 1)
-    n_iterations = loop_n_iterations / loop_unroll_factor [loop_num];
+  if (loop_info->unroll_number > 1)
+    n_iterations = loop_info->n_iterations / loop_info->unroll_number;
   else
-    n_iterations = loop_n_iterations;
+    n_iterations = loop_info->n_iterations;
 
   if (n_iterations != 0 && n_iterations < 3)
     {
@@ -8071,7 +8057,7 @@ insert_bct (loop_start, loop_end)
      at compile time.  In this case we generate run_time calculation
      of the number of iterations.  */
 
-  if (loop_iteration_var == 0)
+  if (loop_info->iteration_var == 0)
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
@@ -8080,8 +8066,8 @@ insert_bct (loop_start, loop_end)
       return;
     }
 
-  if (GET_MODE_CLASS (GET_MODE (loop_iteration_var)) != MODE_INT
-      || GET_MODE_SIZE (GET_MODE (loop_iteration_var)) != UNITS_PER_WORD)
+  if (GET_MODE_CLASS (GET_MODE (loop_info->iteration_var)) != MODE_INT
+      || GET_MODE_SIZE (GET_MODE (loop_info->iteration_var)) != UNITS_PER_WORD)
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
@@ -8091,7 +8077,7 @@ insert_bct (loop_start, loop_end)
     }
 
   /* With runtime bounds, if the compare is of the form '!=' we give up */
-  if (loop_comparison_code == NE)
+  if (loop_info->comparison_code == NE)
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
index d0ae25f..f747e46 100644 (file)
@@ -143,6 +143,43 @@ struct iv_class {
                                   biv controls. */
 };
 
+/* Information required to calculate the number of loop iterations. 
+   This is set by loop_iterations.  */
+
+struct loop_info
+{
+  /* Register or constant initial loop value.  */
+  rtx initial_value;
+  /* Register or constant value used for comparison test.  */
+  rtx comparison_value;
+  /* Register or constant approximate final value.  */
+  rtx final_value;
+  /* Register or constant initial loop value with term common to
+     final_value removed.  */
+  rtx initial_equiv_value;
+  /* Register or constant final loop value with term common to
+     initial_value removed.  */
+  rtx final_equiv_value;
+  /* Register corresponding to iteration variable.  */
+  rtx iteration_var;
+  /* Constant loop increment.  */
+  rtx increment;
+  enum rtx_code comparison_code;
+  /* Holds the number of loop iterations.  It is zero if the number
+     could not be calculated.  Must be unsigned since the number of
+     iterations can be as high as 2^wordsize - 1.  For loops with a
+     wider iterator, this number will be zero if the number of loop
+     iterations is too large for an unsigned integer to hold.  */
+  unsigned HOST_WIDE_INT n_iterations;
+  /* The loop unrolling factor.
+     Potential values:
+     0: unrolled
+     1: not unrolled.
+     -1: completely unrolled
+     >0: holds the unroll exact factor.  */
+  int unroll_number;
+};
+
 /* Definitions used by the basic induction variable discovery code.  */
 enum iv_mode { UNKNOWN_INDUCT, BASIC_INDUCT, NOT_BASIC_INDUCT,
                 GENERAL_INDUCT };
@@ -155,7 +192,6 @@ extern int *uid_loop_num;
 extern int *loop_outer_loop;
 extern rtx *loop_number_exit_labels;
 extern int *loop_number_exit_count;
-extern unsigned HOST_WIDE_INT loop_n_iterations;
 extern int max_reg_before_loop;
 
 extern FILE *loop_dump_stream;
@@ -175,21 +211,18 @@ void emit_iv_add_mult PROTO((rtx, rtx, rtx, rtx, rtx));
 void find_loop_tree_blocks PROTO((void));
 void unroll_block_trees PROTO((void));
 
-void unroll_loop PROTO((rtx, int, rtx, rtx, int));
+void unroll_loop PROTO((rtx, int, rtx, rtx, struct loop_info *, int));
 rtx biv_total_increment PROTO((struct iv_class *, rtx, rtx));
-unsigned HOST_WIDE_INT loop_iterations PROTO((rtx, rtx));
-rtx final_biv_value PROTO((struct iv_class *, rtx, rtx));
-rtx final_giv_value PROTO((struct induction *, rtx, rtx));
+unsigned HOST_WIDE_INT loop_iterations PROTO((rtx, rtx, struct loop_info *));
+int precondition_loop_p PROTO((rtx, struct loop_info *, 
+                              rtx *, rtx *, rtx *));
+rtx final_biv_value PROTO((struct iv_class *, rtx, rtx,
+                          unsigned HOST_WIDE_INT));
+rtx final_giv_value PROTO((struct induction *, rtx, rtx,
+                          unsigned HOST_WIDE_INT));
 void emit_unrolled_add PROTO((rtx, rtx, rtx));
 int back_branch_in_range_p PROTO((rtx, rtx, rtx));
 
-extern int *loop_unroll_factor;
+extern int *loop_unroll_number;
 
-#ifdef HAVE_decrement_and_branch_on_count
-extern rtx loop_iteration_var;
-extern rtx loop_initial_value;
-extern rtx loop_increment;
-extern rtx loop_final_value;
-extern enum rtx_code loop_comparison_code;
-#endif  /* HAVE_decrement_and_branch_on_count */
 
index 9bf6a51..5f9f2c7 100644 (file)
@@ -186,19 +186,9 @@ static rtx *splittable_regs;
 
 static int *splittable_regs_updates;
 
-/* Values describing the current loop's iteration variable.  These are set up
-   by loop_iterations, and used by precondition_loop_p.  */
-
-rtx loop_iteration_var;
-rtx loop_initial_value;
-rtx loop_increment;
-rtx loop_final_value;
-enum rtx_code loop_comparison_code;
-
 /* Forward declarations.  */
 
 static void init_reg_map PROTO((struct inline_remap *, int));
-static int precondition_loop_p PROTO((rtx *, rtx *, rtx *, rtx));
 static rtx calculate_giv_inc PROTO((rtx, rtx, int));
 static rtx initial_reg_note_copy PROTO((rtx, struct inline_remap *));
 static void final_reg_note_copy PROTO((rtx, struct inline_remap *));
@@ -206,8 +196,9 @@ static void copy_loop_body PROTO((rtx, rtx, struct inline_remap *, rtx, int,
                                  enum unroll_types, rtx, rtx, rtx, rtx));
 void iteration_info PROTO((rtx, rtx *, rtx *, rtx, rtx));
 static rtx approx_final_value PROTO((enum rtx_code, rtx, int *, int *));
-static int find_splittable_regs PROTO((enum unroll_types, rtx, rtx, rtx, int));
-static int find_splittable_givs PROTO((struct iv_class *,enum unroll_types,
+static int find_splittable_regs PROTO((enum unroll_types, rtx, rtx, rtx, int,
+                                      unsigned HOST_WIDE_INT));
+static int find_splittable_givs PROTO((struct iv_class *, enum unroll_types,
                                       rtx, rtx, rtx, int));
 static int reg_dead_after_loop PROTO((rtx, rtx, rtx));
 static rtx fold_rtx_mult_add PROTO((rtx, rtx, rtx, enum machine_mode));
@@ -227,11 +218,12 @@ static rtx remap_split_bivs PROTO((rtx));
 
 void
 unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
-            strength_reduce_p)
+            loop_info, strength_reduce_p)
      rtx loop_end;
      int insn_count;
      rtx loop_start;
      rtx end_insert_before;
+     struct loop_info *loop_info;
      int strength_reduce_p;
 {
   int i, j, temp;
@@ -304,18 +296,19 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
   /* Determine type of unroll to perform.  Depends on the number of iterations
      and the size of the loop.  */
 
-  /* If there is no strength reduce info, then set loop_n_iterations to zero.
-     This can happen if strength_reduce can't find any bivs in the loop.
-     A value of zero indicates that the number of iterations could not be
-     calculated.  */
+  /* If there is no strength reduce info, then set
+     loop_info->n_iterations to zero.  This can happen if
+     strength_reduce can't find any bivs in the loop.  A value of zero
+     indicates that the number of iterations could not be calculated.  */
 
   if (! strength_reduce_p)
-    loop_n_iterations = 0;
+    loop_info->n_iterations = 0;
 
-  if (loop_dump_stream && loop_n_iterations > 0)
+  if (loop_dump_stream && loop_info->n_iterations > 0)
     {
       fputs ("Loop unrolling: ", loop_dump_stream);
-      fprintf (loop_dump_stream, HOST_WIDE_INT_PRINT_DEC, loop_n_iterations);
+      fprintf (loop_dump_stream, HOST_WIDE_INT_PRINT_DEC, 
+              loop_info->n_iterations);
       fputs (" iterations.\n", loop_dump_stream);
     }
 
@@ -326,7 +319,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
   /* Calculate how many times to unroll the loop.  Indicate whether or
      not the loop is being completely unrolled.  */
 
-  if (loop_n_iterations == 1)
+  if (loop_info->n_iterations == 1)
     {
       /* If number of iterations is exactly 1, then eliminate the compare and
         branch at the end of the loop since they will never be taken.
@@ -355,13 +348,13 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
        }
       return;
     }
-  else if (loop_n_iterations > 0
-      && loop_n_iterations * insn_count < MAX_UNROLLED_INSNS)
+  else if (loop_info->n_iterations > 0
+      && loop_info->n_iterations * insn_count < MAX_UNROLLED_INSNS)
     {
-      unroll_number = loop_n_iterations;
+      unroll_number = loop_info->n_iterations;
       unroll_type = UNROLL_COMPLETELY;
     }
-  else if (loop_n_iterations > 0)
+  else if (loop_info->n_iterations > 0)
     {
       /* Try to factor the number of iterations.  Don't bother with the
         general case, only using 2, 3, 5, and 7 will get 75% of all
@@ -370,7 +363,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
       for (i = 0; i < NUM_FACTORS; i++)
        factors[i].count = 0;
 
-      temp = loop_n_iterations;
+      temp = loop_info->n_iterations;
       for (i = NUM_FACTORS - 1; i >= 0; i--)
        while (temp % factors[i].factor == 0)
          {
@@ -857,8 +850,8 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
     {
       rtx initial_value, final_value, increment;
 
-      if (precondition_loop_p (&initial_value, &final_value, &increment,
-                              loop_start))
+      if (precondition_loop_p (loop_start, loop_info,
+                              &initial_value, &final_value, &increment))
        {
          register rtx diff ;
          enum machine_mode mode;
@@ -939,7 +932,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
             case.  This check does not apply if the loop has a NE
             comparison at the end.  */
 
-         if (loop_comparison_code != NE)
+         if (loop_info->comparison_code != NE)
            {
              emit_cmp_insn (initial_value, final_value, neg_inc ? LE : GE,
                             NULL_RTX, mode, 0, 0);
@@ -1141,11 +1134,11 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
 
   /* At this point, we are guaranteed to unroll the loop.  */
 
-  /* Keep track of the unroll factor for each loop.  */
+  /* Keep track of the unroll factor for the loop.  */
   if (unroll_type == UNROLL_COMPLETELY)
-    loop_unroll_factor [uid_loop_num [INSN_UID (loop_start)]] = -1;
+    loop_info->unroll_number = -1;
   else
-    loop_unroll_factor [uid_loop_num [INSN_UID (loop_start)]] = unroll_number;
+    loop_info->unroll_number = unroll_number;
 
 
   /* For each biv and giv, determine whether it can be safely split into
@@ -1160,7 +1153,8 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
     temp = 0;
   else
     temp = find_splittable_regs (unroll_type, loop_start, loop_end,
-                               end_insert_before, unroll_number);
+                                end_insert_before, unroll_number,
+                                loop_info->n_iterations);
 
   /* find_splittable_regs may have created some new registers, so must
      reallocate the reg_map with the new larger size, and must realloc
@@ -1318,52 +1312,54 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
    when the increment is not a power of 2.  Use RTX_COST to compute
    whether divide is cheap.  */
 
-static int
-precondition_loop_p (initial_value, final_value, increment, loop_start)
-     rtx *initial_value, *final_value, *increment;
+int
+precondition_loop_p (loop_start, loop_info,
+                    initial_value, final_value, increment)
      rtx loop_start;
+     struct loop_info *loop_info;
+     rtx *initial_value, *final_value, *increment;
 {
 
-  if (loop_n_iterations > 0)
+  if (loop_info->n_iterations > 0)
     {
       *initial_value = const0_rtx;
       *increment = const1_rtx;
-      *final_value = GEN_INT (loop_n_iterations);
+      *final_value = GEN_INT (loop_info->n_iterations);
 
       if (loop_dump_stream)
        {
          fputs ("Preconditioning: Success, number of iterations known, ",
                 loop_dump_stream);
          fprintf (loop_dump_stream, HOST_WIDE_INT_PRINT_DEC,
-                  loop_n_iterations);
+                  loop_info->n_iterations);
          fputs (".\n", loop_dump_stream);
        }
       return 1;
     }
 
-  if (loop_initial_value == 0)
+  if (loop_info->initial_value == 0)
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
                 "Preconditioning: Could not find initial value.\n");
       return 0;
     }
-  else if (loop_increment == 0)
+  else if (loop_info->increment == 0)
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
                 "Preconditioning: Could not find increment value.\n");
       return 0;
     }
-  else if (GET_CODE (loop_increment) != CONST_INT)
+  else if (GET_CODE (loop_info->increment) != CONST_INT)
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
                 "Preconditioning: Increment not a constant.\n");
       return 0;
     }
-  else if ((exact_log2 (INTVAL (loop_increment)) < 0)
-          && (exact_log2 (- INTVAL (loop_increment)) < 0))
+  else if ((exact_log2 (INTVAL (loop_info->increment)) < 0)
+          && (exact_log2 (- INTVAL (loop_info->increment)) < 0))
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
@@ -1374,7 +1370,7 @@ precondition_loop_p (initial_value, final_value, increment, loop_start)
   /* Unsigned_compare and compare_dir can be ignored here, since they do
      not matter for preconditioning.  */
 
-  if (loop_final_value == 0)
+  if (loop_info->final_value == 0)
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
@@ -1387,11 +1383,11 @@ precondition_loop_p (initial_value, final_value, increment, loop_start)
      to make sure that the register is in the range covered by invariant_p.
      If it isn't, then it is most likely a biv/giv which by definition are
      not invariant.  */
-  if ((GET_CODE (loop_final_value) == REG
-       && REGNO (loop_final_value) >= max_reg_before_loop)
-      || (GET_CODE (loop_final_value) == PLUS
-         && REGNO (XEXP (loop_final_value, 0)) >= max_reg_before_loop)
-      || ! invariant_p (loop_final_value))
+  if ((GET_CODE (loop_info->final_value) == REG
+       && REGNO (loop_info->final_value) >= max_reg_before_loop)
+      || (GET_CODE (loop_info->final_value) == PLUS
+         && REGNO (XEXP (loop_info->final_value, 0)) >= max_reg_before_loop)
+      || ! invariant_p (loop_info->final_value))
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
@@ -1401,8 +1397,8 @@ precondition_loop_p (initial_value, final_value, increment, loop_start)
 
   /* Fail for floating point values, since the caller of this function
      does not have code to deal with them.  */
-  if (GET_MODE_CLASS (GET_MODE (loop_final_value)) == MODE_FLOAT
-      || GET_MODE_CLASS (GET_MODE (loop_initial_value)) == MODE_FLOAT)
+  if (GET_MODE_CLASS (GET_MODE (loop_info->final_value)) == MODE_FLOAT
+      || GET_MODE_CLASS (GET_MODE (loop_info->initial_value)) == MODE_FLOAT)
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
@@ -1410,10 +1406,10 @@ precondition_loop_p (initial_value, final_value, increment, loop_start)
       return 0;
     }
 
-  /* Fail if loop_iteration_var is not live before loop_start, since we need
-     to test its value in the preconditioning code.  */
+  /* Fail if loop_info->iteration_var is not live before loop_start,
+     since we need to test its value in the preconditioning code.  */
 
-  if (uid_luid[REGNO_FIRST_UID (REGNO (loop_iteration_var))]
+  if (uid_luid[REGNO_FIRST_UID (REGNO (loop_info->iteration_var))]
       > INSN_LUID (loop_start))
     {
       if (loop_dump_stream)
@@ -1430,9 +1426,9 @@ precondition_loop_p (initial_value, final_value, increment, loop_start)
      Also note that the absolute values of initial_value and
      final_value are unimportant as only their difference is used for
      calculating the number of loop iterations.  */
-  *initial_value = loop_initial_value;
-  *increment = loop_increment;
-  *final_value = loop_final_value;
+  *initial_value = loop_info->initial_value;
+  *increment = loop_info->increment;
+  *final_value = loop_info->final_value;
 
   /* Success! */
   if (loop_dump_stream)
@@ -2361,7 +2357,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
 
   /* Reject iteration variables larger than the host wide int size, since they
      could result in a number of iterations greater than the range of our
-     `unsigned HOST_WIDE_INT' variable loop_n_iterations.  */
+     `unsigned HOST_WIDE_INT' variable loop_info->n_iterations.  */
   else if ((GET_MODE_BITSIZE (GET_MODE (iteration_var))
            > HOST_BITS_PER_WIDE_INT))
     {
@@ -2506,11 +2502,12 @@ approx_final_value (comparison_code, comparison_value, unsigned_p, compare_dir)
 
 static int
 find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
-                    unroll_number)
+                    unroll_number, n_iterations)
      enum unroll_types unroll_type;
      rtx loop_start, loop_end;
      rtx end_insert_before;
      int unroll_number;
+     unsigned HOST_WIDE_INT n_iterations;
 {
   struct iv_class *bl;
   struct induction *v;
@@ -2548,7 +2545,8 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
              || (uid_luid[REGNO_FIRST_UID (bl->regno)]
                  < INSN_LUID (bl->init_insn))
              || reg_mentioned_p (bl->biv->dest_reg, SET_SRC (bl->init_set)))
-         && ! (biv_final_value = final_biv_value (bl, loop_start, loop_end)))
+         && ! (biv_final_value = final_biv_value (bl, loop_start, loop_end,
+                                                  n_iterations)))
        biv_splittable = 0;
 
       /* If any of the insns setting the BIV don't do so with a simple
@@ -3201,9 +3199,10 @@ reg_dead_after_loop (reg, loop_start, loop_end)
    the end of the loop.  If we can do it, return that value.  */
   
 rtx
-final_biv_value (bl, loop_start, loop_end)
+final_biv_value (bl, loop_start, loop_end, n_iterations)
      struct iv_class *bl;
      rtx loop_start, loop_end;
+     unsigned HOST_WIDE_INT n_iterations;
 {
   rtx increment, tem;
 
@@ -3231,7 +3230,7 @@ final_biv_value (bl, loop_start, loop_end)
      it may not have its final value when the loop exits), and the initial
      value of the biv must be invariant.  */
 
-  if (loop_n_iterations != 0
+  if (n_iterations != 0
       && ! loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]]
       && invariant_p (bl->initial_value))
     {
@@ -3248,7 +3247,7 @@ final_biv_value (bl, loop_start, loop_end)
          /* Make sure loop_end is not the last insn.  */
          if (NEXT_INSN (loop_end) == 0)
            emit_note_after (NOTE_INSN_DELETED, loop_end);
-         emit_iv_add_mult (increment, GEN_INT (loop_n_iterations),
+         emit_iv_add_mult (increment, GEN_INT (n_iterations),
                            bl->initial_value, tem, NEXT_INSN (loop_end));
 
          if (loop_dump_stream)
@@ -3277,9 +3276,10 @@ final_biv_value (bl, loop_start, loop_end)
    the end of the loop.  If we can do it, return that value.  */
 
 rtx
-final_giv_value (v, loop_start, loop_end)
+final_giv_value (v, loop_start, loop_end, n_iterations)
      struct induction *v;
      rtx loop_start, loop_end;
+     unsigned HOST_WIDE_INT n_iterations;
 {
   struct iv_class *bl;
   rtx insn;
@@ -3310,7 +3310,7 @@ final_giv_value (v, loop_start, loop_end)
      only one exit for this to work, but the loop iterations does not need
      to be known.  */
 
-  if (loop_n_iterations != 0
+  if (n_iterations != 0
       && ! loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]])
     {
       /* ?? It is tempting to use the biv's value here since these insns will
@@ -3330,7 +3330,7 @@ final_giv_value (v, loop_start, loop_end)
          && invariant_p (bl->initial_value))
        {
          /* Can calculate the loop exit value of its biv as
-            (loop_n_iterations * increment) + initial_value */
+            (n_iterations * increment) + initial_value */
              
          /* The loop exit value of the giv is then
             (final_biv_value - extra increments) * mult_val + add_val.
@@ -3344,7 +3344,7 @@ final_giv_value (v, loop_start, loop_end)
          /* Put the final biv value in tem.  */
          tem = gen_reg_rtx (bl->biv->mode);
          record_base_value (REGNO (tem), bl->biv->add_val, 0);
-         emit_iv_add_mult (increment, GEN_INT (loop_n_iterations),
+         emit_iv_add_mult (increment, GEN_INT (n_iterations),
                            bl->initial_value, tem, insert_before);
 
          /* Subtract off extra increments as we find them.  */
@@ -3402,8 +3402,9 @@ final_giv_value (v, loop_start, loop_end)
    iterations if it can be calculated, otherwise returns zero.  */
 
 unsigned HOST_WIDE_INT
-loop_iterations (loop_start, loop_end)
+loop_iterations (loop_start, loop_end, loop_info)
      rtx loop_start, loop_end;
+     struct loop_info *loop_info;
 {
   rtx comparison, comparison_value;
   rtx iteration_var, initial_value, increment, final_value;
@@ -3418,10 +3419,11 @@ loop_iterations (loop_start, loop_end)
      branch, and the insn before tests a register value, make that the
      iteration variable.  */
   
-  loop_initial_value = 0;
-  loop_increment = 0;
-  loop_final_value = 0;
-  loop_iteration_var = 0;
+  loop_info->initial_value = 0;
+  loop_info->increment = 0;
+  loop_info->final_value = 0;
+  loop_info->iteration_var = 0;
+  loop_info->unroll_number = 2;
 
   /* We used to use pren_nonnote_insn here, but that fails because it might
      accidentally get the branch for a contained loop if the branch for this
@@ -3508,11 +3510,11 @@ loop_iterations (loop_start, loop_end)
      recalculated inside precondition_loop_p because strength reduction
      optimizations may obscure the loop's structure.  */
 
-  loop_iteration_var = iteration_var;
-  loop_initial_value = initial_value;
-  loop_increment = increment;
-  loop_final_value = final_value;
-  loop_comparison_code = comparison_code;
+  loop_info->iteration_var = iteration_var;
+  loop_info->initial_value = initial_value;
+  loop_info->increment = increment;
+  loop_info->final_value = final_value;
+  loop_info->comparison_code = comparison_code;
 
   if (increment == 0)
     {
@@ -3617,7 +3619,7 @@ loop_iterations (loop_start, loop_end)
     }
 
   /* Calculate the number of iterations, final_value is only an approximation,
-     so correct for that.  Note that tempu and loop_n_iterations are
+     so correct for that.  Note that tempu and loop_info->n_iterations are
      unsigned, because they can be as large as 2^n - 1.  */
 
   i = INTVAL (increment);