2000-01-26 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
authorm.hayes <m.hayes@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 25 Jan 2000 22:49:56 +0000 (22:49 +0000)
committerm.hayes <m.hayes@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 25 Jan 2000 22:49:56 +0000 (22:49 +0000)
* loop.c (current_loop_info): Delete.
(consec_sets_invariant_p): Add loop argument, update callers.
(get_condition_for_loop): Likewise.
(count_nonfixed_reads, update_giv_derive): Likewise.
(simplify_giv_expr, general_induction_var): Likewise.
(consec_sets_giv, recombine_givs): Likewise.
(move_movables): Delete loop_start and loop_end arguments,
add loop argument, and update callers.
(find_mem_givs, check_final_value): Likewise.
(record_giv, maybe_eliminate_biv, maybe_eliminate_biv_1): Likewise.
(loop_invariant_p): Rename from invariant_p, add loop argument, and
update callers.
(basic_induction_var): Add loop argument, delete loop_level argument,
and update callers.
* unroll.c (iteration_info): Delete loop_start and loop_end arguments,
add loop argument, and update callers.
(find_splittable_regs, find_splittable_givs): Likewise.
(reg_dead_after_loop, loop_find_equiv_value): Likewise.
(final_biv_value, final_giv_value, back_branch_in_range_p): Likewise.
(biv_total_increment): Delete loop_start and loop_end arguments;
update callers.
(precondition_loop_p): Delete loop_start and loop_info arguments;
update callers.
* loop.h (get_condition_for_loop): Add loop argument.
(biv_total_increment): Delete loop_start and loop_end arguments.
(precondition_loop_p): Delete loop_start and loop_info arguments;
add loop argument.
(final_biv_value): Delete loop_start and loop_end arguments;
add loop argument.
(final_giv_value, back_branch_in_range_p): Likewise.

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

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

index f0c10d9..f3c6842 100644 (file)
@@ -1,3 +1,36 @@
+2000-01-26  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>
+
+       * loop.c (current_loop_info): Delete.
+       (consec_sets_invariant_p): Add loop argument, update callers.
+       (get_condition_for_loop): Likewise.
+       (count_nonfixed_reads, update_giv_derive): Likewise.
+       (simplify_giv_expr, general_induction_var): Likewise.
+       (consec_sets_giv, recombine_givs): Likewise.
+       (move_movables): Delete loop_start and loop_end arguments,
+       add loop argument, and update callers.
+       (find_mem_givs, check_final_value): Likewise.
+       (record_giv, maybe_eliminate_biv, maybe_eliminate_biv_1): Likewise.
+       (loop_invariant_p): Rename from invariant_p, add loop argument, and
+       update callers.
+       (basic_induction_var): Add loop argument, delete loop_level argument,
+       and update callers.
+       * unroll.c (iteration_info): Delete loop_start and loop_end arguments,
+       add loop argument, and update callers.
+       (find_splittable_regs, find_splittable_givs): Likewise.
+       (reg_dead_after_loop, loop_find_equiv_value): Likewise.
+       (final_biv_value, final_giv_value, back_branch_in_range_p): Likewise.
+       (biv_total_increment): Delete loop_start and loop_end arguments;
+       update callers.
+       (precondition_loop_p): Delete loop_start and loop_info arguments;
+       update callers.
+       * loop.h (get_condition_for_loop): Add loop argument.
+       (biv_total_increment): Delete loop_start and loop_end arguments.
+       (precondition_loop_p): Delete loop_start and loop_info arguments;
+       add loop argument.
+       (final_biv_value): Delete loop_start and loop_end arguments;
+       add loop argument.
+       (final_giv_value, back_branch_in_range_p): Likewise.
+
 2000-01-25  Gavin Romig-Koch  <gavin@cygnus.com>
 
        * config/mips/mips.h (LEGITIMATE_CONSTANT_P): Fix for mips16.
index b297504..283e219 100644 (file)
@@ -53,11 +53,6 @@ Boston, MA 02111-1307, USA.  */
 #include "except.h"
 #include "toplev.h"
 
-/* Information about the current loop being processed used to compute
-   the number of loop iterations for loop unrolling and doloop
-   optimization.  */
-static struct loop_info *current_loop_info;
-
 /* Vector mapping INSN_UIDs to luids.
    The luids are like uids but increase monotonically always.
    We use them to see whether a jump comes from outside a given loop.  */
@@ -239,12 +234,13 @@ static void find_and_verify_loops PARAMS ((rtx, struct loops *));
 static void mark_loop_jump PARAMS ((rtx, struct loop *));
 static void prescan_loop PARAMS ((struct loop *));
 static int reg_in_basic_block_p PARAMS ((rtx, rtx));
-static int consec_sets_invariant_p PARAMS ((rtx, int, rtx));
+static int consec_sets_invariant_p PARAMS ((const struct loop *,
+                                           rtx, int, rtx));
 static int labels_in_range_p PARAMS ((rtx, int));
 static void count_one_set PARAMS ((rtx, rtx, varray_type, rtx *));
 
 static void count_loop_regs_set PARAMS ((rtx, rtx, varray_type, varray_type,
-                                      int *, int)); 
+                                        int *, int)); 
 static void note_addr_stored PARAMS ((rtx, rtx, void *));
 static void note_set_pseudo_multiple_uses PARAMS ((rtx, rtx, void *));
 static int loop_reg_used_before_p PARAMS ((const struct loop *, rtx, rtx));
@@ -260,37 +256,49 @@ static void combine_movables PARAMS ((struct movable *, int));
 static int regs_match_p PARAMS ((rtx, rtx, struct movable *));
 static int rtx_equal_for_loop_p PARAMS ((rtx, rtx, struct movable *));
 static void add_label_notes PARAMS ((rtx, rtx));
-static void move_movables PARAMS ((struct movable *, int, int, rtx, rtx, int));
-static int count_nonfixed_reads PARAMS ((rtx));
+static void move_movables PARAMS ((struct loop *loop, struct movable *, 
+                                  int, int, int));
+static int count_nonfixed_reads PARAMS ((const struct loop *, rtx));
 static void strength_reduce PARAMS ((struct loop *, int, int, int));
 static void find_single_use_in_loop PARAMS ((rtx, rtx, varray_type));
 static int valid_initial_value_p PARAMS ((rtx, rtx, int, rtx));
-static void find_mem_givs PARAMS ((rtx, rtx, int, int, rtx, rtx));
-static void record_biv PARAMS ((struct induction *, rtx, rtx, rtx, rtx, rtx *, int, int, int));
-static void check_final_value PARAMS ((struct induction *, rtx, rtx, 
-                                    unsigned HOST_WIDE_INT));
-static void record_giv PARAMS ((struct induction *, rtx, rtx, rtx, rtx, rtx, int, enum g_types, int, int, rtx *, rtx, rtx));
-static void update_giv_derive PARAMS ((rtx));
-static int basic_induction_var PARAMS ((rtx, enum machine_mode, rtx, rtx, int, rtx *, rtx *, rtx **, int *));
-static rtx simplify_giv_expr PARAMS ((rtx, int *));
-static int general_induction_var PARAMS ((rtx, rtx *, rtx *, rtx *, int, int *));
-static int consec_sets_giv PARAMS ((int, rtx, rtx, rtx, rtx *, rtx *, rtx *));
+static void find_mem_givs PARAMS ((const struct loop *, rtx, rtx, int, int));
+static void record_biv PARAMS ((struct induction *, rtx, rtx, rtx, rtx, rtx *, 
+                               int, int, int));
+static void check_final_value PARAMS ((const struct loop *,
+                                      struct induction *));
+static void record_giv PARAMS ((const struct loop *, struct induction *, 
+                               rtx, rtx, rtx, rtx, rtx, int, enum g_types, 
+                               int, int, rtx *));
+static void update_giv_derive PARAMS ((const struct loop *, rtx));
+static int basic_induction_var PARAMS ((const struct loop *, rtx, 
+                                       enum machine_mode, rtx, rtx,
+                                       rtx *, rtx *, rtx **, int *));
+static rtx simplify_giv_expr PARAMS ((const struct loop *, rtx, int *));
+static int general_induction_var PARAMS ((const struct loop *loop, rtx, rtx *,
+                                         rtx *, rtx *, int, int *));
+static int consec_sets_giv PARAMS ((const struct loop *, int, rtx,
+                                   rtx, rtx, rtx *, rtx *, rtx *));
 static int check_dbra_loop PARAMS ((struct loop *, int));
 static rtx express_from_1 PARAMS ((rtx, rtx, rtx));
 static rtx combine_givs_p PARAMS ((struct induction *, struct induction *));
 static void combine_givs PARAMS ((struct iv_class *));
 struct recombine_givs_stats;
-static int find_life_end PARAMS ((rtx, struct recombine_givs_stats *, rtx, rtx));
-static void recombine_givs PARAMS ((struct iv_class *, rtx, rtx, int));
+static int find_life_end PARAMS ((rtx, struct recombine_givs_stats *,
+                                 rtx, rtx));
+static void recombine_givs PARAMS ((const struct loop *, struct iv_class *,
+                                   int));
 static int product_cheap_p PARAMS ((rtx, rtx));
-static int maybe_eliminate_biv PARAMS ((struct iv_class *, rtx, rtx, int, int, int));
-static int maybe_eliminate_biv_1 PARAMS ((rtx, rtx, struct iv_class *, int, rtx));
+static int maybe_eliminate_biv PARAMS ((const struct loop *, struct iv_class *,
+                                       int, int, int));
+static int maybe_eliminate_biv_1 PARAMS ((const struct loop *, rtx, rtx, 
+                                         struct iv_class *, int, rtx));
 static int last_use_this_basic_block PARAMS ((rtx, rtx));
 static void record_initial PARAMS ((rtx, rtx, void *));
 static void update_reg_last_use PARAMS ((rtx, rtx));
 static rtx next_insn_in_loop PARAMS ((const struct loop *, rtx));
 static void load_mems_and_recount_loop_regs_set PARAMS ((const struct loop*,
-                                                      int *));
+                                                        int *));
 static void load_mems PARAMS ((const struct loop *));
 static int insert_loop_mem PARAMS ((rtx *, void *));
 static int replace_loop_mem PARAMS ((rtx *, void *));
@@ -546,7 +554,7 @@ loop_optimize (f, dumpfile, unroll_p, bct_p)
 \f
 /* Returns the next insn, in execution order, after INSN.  START and
    END are the NOTE_INSN_LOOP_BEG and NOTE_INSN_LOOP_END for the loop,
-   respectively.  LOOP_TOP, if non-NULL, is the top of the loop in the
+   respectively.  LOOP->TOP, if non-NULL, is the top of the loop in the
    insn-stream; it is used with loops that are entered near the
    bottom.  */
 
@@ -590,6 +598,9 @@ scan_loop (loop, unroll_p, bct_p)
   register int i;
   rtx loop_start = loop->start;
   rtx loop_end = loop->end;
+  /* Additional information about the current loop being processed
+     that is used to compute the number of loop iterations for loop
+     unrolling and doloop optimization.  */
   struct loop_info *loop_info = LOOP_INFO (loop);
   rtx p;
   /* 1 if we are scanning insns that could be executed zero times.  */
@@ -619,7 +630,6 @@ scan_loop (loop, unroll_p, bct_p)
   int loop_depth = 0;
   int nregs;
 
-  current_loop_info = loop_info;
   loop->top = 0;
 
   /* Determine whether this loop starts with a jump down to a test at
@@ -827,14 +837,14 @@ scan_loop (loop, unroll_p, bct_p)
               which was not created by the user and not used in an exit test.
               That behavior is incorrect and was removed.  */
            ;
-         else if ((tem = invariant_p (src))
+         else if ((tem = loop_invariant_p (loop, src))
                   && (dependencies == 0
-                      || (tem2 = invariant_p (dependencies)) != 0)
+                      || (tem2 = loop_invariant_p (loop, dependencies)) != 0)
                   && (VARRAY_INT (set_in_loop, 
                                   REGNO (SET_DEST (set))) == 1
                       || (tem1
                           = consec_sets_invariant_p 
-                          (SET_DEST (set),
+                          (loop, SET_DEST (set),
                            VARRAY_INT (set_in_loop, REGNO (SET_DEST (set))),
                            p)))
                   /* If the insn can cause a trap (such as divide by zero),
@@ -1109,8 +1119,7 @@ scan_loop (loop, unroll_p, bct_p)
      optimizing for code size.  */
 
   if (! optimize_size)
-    move_movables (movables, threshold,
-                  insn_count, loop_start, loop_end, nregs);
+    move_movables (loop, movables, threshold, insn_count, nregs);
 
   /* Now candidates that still are negative are those not moved.
      Change set_in_loop to indicate that those are not actually invariant.  */
@@ -1123,7 +1132,8 @@ scan_loop (loop, unroll_p, bct_p)
   load_mems_and_recount_loop_regs_set (loop, &insn_count);
 
   for (update_start = loop_start;
-       PREV_INSN (update_start) && GET_CODE (PREV_INSN (update_start)) != CODE_LABEL;
+       PREV_INSN (update_start)
+        && GET_CODE (PREV_INSN (update_start)) != CODE_LABEL;
        update_start = PREV_INSN (update_start))
     ;
   update_end = NEXT_INSN (loop_end);
@@ -1702,17 +1712,18 @@ add_label_notes (x, insns)
    other throughout.  */
 
 static void
-move_movables (movables, threshold, insn_count, loop_start, end, nregs)
+move_movables (loop, movables, threshold, insn_count, nregs)
+     struct loop *loop;
      struct movable *movables;
      int threshold;
      int insn_count;
-     rtx loop_start;
-     rtx end;
      int nregs;
 {
   rtx new_start = 0;
   register struct movable *m;
   register rtx p;
+  rtx loop_start = loop->start;
+  rtx loop_end = loop->end;
   /* Map of pseudo-register replacements to handle combining
      when we move several insns that load the same value
      into different pseudo-registers.  */
@@ -1757,11 +1768,11 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
 
       if (!m->done
          && (! m->cond
-             || (1 == invariant_p (m->set_src)
+             || (1 == loop_invariant_p (loop, m->set_src)
                  && (m->dependencies == 0
-                     || 1 == invariant_p (m->dependencies))
+                     || 1 == loop_invariant_p (loop, m->dependencies))
                  && (m->consec == 0
-                     || 1 == consec_sets_invariant_p (m->set_dest,
+                     || 1 == consec_sets_invariant_p (loop, m->set_dest,
                                                       m->consec + 1,
                                                       m->insn))))
          && (! m->forces || m->forces->done))
@@ -2062,7 +2073,7 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
                             like this as a result of record_jump_cond.  */
                      
                          if ((temp = find_reg_note (i1, REG_EQUAL, NULL_RTX))
-                             && ! invariant_p (XEXP (temp, 0)))
+                             && ! loop_invariant_p (loop, XEXP (temp, 0)))
                            remove_note (i1, temp);
                        }
 
@@ -2123,8 +2134,8 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
                   We can't use the moved insn because it is out of range
                   in uid_luid.  Only the old insns have luids.  */
                REGNO_FIRST_UID (regno) = INSN_UID (loop_start);
-             if (uid_luid[REGNO_LAST_UID (regno)] < INSN_LUID (end))
-               REGNO_LAST_UID (regno) = INSN_UID (end);
+             if (uid_luid[REGNO_LAST_UID (regno)] < INSN_LUID (loop_end))
+               REGNO_LAST_UID (regno) = INSN_UID (loop_end);
 
              /* Combine with this moved insn any other matching movables.  */
 
@@ -2192,7 +2203,7 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
 
   /* Go through all the instructions in the loop, making
      all the register substitutions scheduled in REG_MAP.  */
-  for (p = new_start; p != end; p = NEXT_INSN (p))
+  for (p = new_start; p != loop_end; p = NEXT_INSN (p))
     if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN
        || GET_CODE (p) == CALL_INSN)
       {
@@ -2274,7 +2285,8 @@ replace_call_address (x, reg, addr)
    in the rtx X.  */
 
 static int
-count_nonfixed_reads (x)
+count_nonfixed_reads (loop, x)
+     const struct loop *loop;
      rtx x;
 {
   register enum rtx_code code;
@@ -2299,8 +2311,8 @@ count_nonfixed_reads (x)
       return 0;
 
     case MEM:
-      return ((invariant_p (XEXP (x, 0)) != 1)
-             + count_nonfixed_reads (XEXP (x, 0)));
+      return ((loop_invariant_p (loop, XEXP (x, 0)) != 1)
+             + count_nonfixed_reads (loop, XEXP (x, 0)));
       
     default:
       break;
@@ -2311,12 +2323,12 @@ count_nonfixed_reads (x)
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     {
       if (fmt[i] == 'e')
-       value += count_nonfixed_reads (XEXP (x, i));
-      else if (fmt[i] == 'E')
+       value += count_nonfixed_reads (loop, XEXP (x, i));
+      if (fmt[i] == 'E')
        {
          register int j;
          for (j = 0; j < XVECLEN (x, i); j++)
-           value += count_nonfixed_reads (XVECEXP (x, i, j));
+           value += count_nonfixed_reads (loop, XVECEXP (x, i, j));
        }
     }
   return value;
@@ -3189,7 +3201,8 @@ note_set_pseudo_multiple_uses (x, y, data)
    anything stored in `loop_store_mems'.  */
 
 int
-invariant_p (x)
+loop_invariant_p (loop, x)
+     const struct loop *loop;
      register rtx x;
 {
   register int i;
@@ -3238,7 +3251,7 @@ invariant_p (x)
          && ! current_function_has_nonlocal_goto)
        return 1;
 
-      if (current_loop_info->has_call
+      if (LOOP_INFO (loop)->has_call
          && REGNO (x) < FIRST_PSEUDO_REGISTER && call_used_regs[REGNO (x)])
        return 0;
 
@@ -3292,7 +3305,7 @@ invariant_p (x)
     {
       if (fmt[i] == 'e')
        {
-         int tem = invariant_p (XEXP (x, i));
+         int tem = loop_invariant_p (loop, XEXP (x, i));
          if (tem == 0)
            return 0;
          if (tem == 2)
@@ -3303,7 +3316,7 @@ invariant_p (x)
          register int j;
          for (j = 0; j < XVECLEN (x, i); j++)
            {
-             int tem = invariant_p (XVECEXP (x, i, j));
+             int tem = loop_invariant_p (loop, XVECEXP (x, i, j));
              if (tem == 0)
                return 0;
              if (tem == 2)
@@ -3328,7 +3341,8 @@ invariant_p (x)
    and that its source is invariant.  */
 
 static int
-consec_sets_invariant_p (reg, n_sets, insn)
+consec_sets_invariant_p (loop, reg, n_sets, insn)
+     const struct loop *loop;
      int n_sets;
      rtx reg, insn;
 {
@@ -3365,7 +3379,7 @@ consec_sets_invariant_p (reg, n_sets, insn)
          && GET_CODE (SET_DEST (set)) == REG
          && REGNO (SET_DEST (set)) == regno)
        {
-         this = invariant_p (SET_SRC (set));
+         this = loop_invariant_p (loop, SET_SRC (set));
          if (this != 0)
            value |= this;
          else if ((temp = find_reg_note (p, REG_EQUAL, NULL_RTX)))
@@ -3375,7 +3389,7 @@ consec_sets_invariant_p (reg, n_sets, insn)
                 notes are OK.  */
              this = (CONSTANT_P (XEXP (temp, 0))
                      || (find_reg_note (p, REG_RETVAL, NULL_RTX)
-                         && invariant_p (XEXP (temp, 0))));
+                         && loop_invariant_p (loop, XEXP (temp, 0))));
              if (this != 0)
                value |= this;
            }
@@ -3390,7 +3404,7 @@ consec_sets_invariant_p (reg, n_sets, insn)
     }
 
   VARRAY_INT (set_in_loop, regno) = old;
-  /* If invariant_p ever returned 2, we return 2.  */
+  /* If loop_invariant_p ever returned 2, we return 2.  */
   return 1 + (value & 2);
 }
 
@@ -3420,7 +3434,7 @@ all_sets_invariant_p (reg, insn, table)
          && GET_CODE (SET_DEST (PATTERN (p))) == REG
          && REGNO (SET_DEST (PATTERN (p))) == regno)
        {
-         if (!invariant_p (SET_SRC (PATTERN (p)), table))
+         if (! loop_invariant_p (loop, SET_SRC (PATTERN (p)), table))
            return 0;
        }
     }
@@ -3575,11 +3589,10 @@ count_loop_regs_set (from, to, may_not_move, single_usage, count_ptr, nregs)
   free (last_set);
 }
 \f
-/* Given a loop that is bounded by LOOP_START and LOOP_END
-   and that is entered at LOOP_SCAN_START,
-   return 1 if the register set in SET contained in insn INSN is used by
-   any insn that precedes INSN in cyclic order starting
-   from the loop entry point.
+/* Given a loop that is bounded by LOOP->START and LOOP->END and that
+   is entered at LOOP->SCAN_START, return 1 if the register set in SET
+   contained in insn INSN is used by any insn that precedes INSN in
+   cyclic order starting from the loop entry point.
 
    We don't want to use INSN_LUID here because if we restrict INSN to those
    that have a valid INSN_LUID, it means we cannot move an invariant out
@@ -3685,13 +3698,7 @@ static rtx addr_placeholder;
    valid index in several tables including n_times_set and regno_last_uid.
    This does not cause a problem here, because the added registers cannot be
    givs outside of their loop, and hence will never be reconsidered.
-   But scan_loop must check regnos to make sure they are in bounds. 
-   
-   LOOP_SCAN_START is the first instruction in the loop, as the loop would
-   actually be executed.  END is the NOTE_INSN_LOOP_END.  LOOP_TOP is
-   the first instruction in the loop, as it is layed out in the
-   instruction stream.  LOOP_START is the NOTE_INSN_LOOP_BEG.
-   LOOP_CONT is the NOTE_INSN_LOOP_CONT.  */
+   But scan_loop must check regnos to make sure they are in bounds.   */
 
 static void
 strength_reduce (loop, insn_count, unroll_p, bct_p)
@@ -3741,7 +3748,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
   /* If loop_scan_start points to the loop exit test, we have to be wary of
      subversive use of gotos inside expression statements.  */
   if (prev_nonnote_insn (loop_scan_start) != prev_nonnote_insn (loop_start))
-    maybe_multiple = back_branch_in_range_p (loop_scan_start, loop_start, loop_end);
+    maybe_multiple = back_branch_in_range_p (loop, loop_scan_start);
 
   VARRAY_INT_INIT (reg_iv_type, max_reg_before_loop, "reg_iv_type");
   VARRAY_GENERIC_PTR_INIT (reg_iv_info, max_reg_before_loop, "reg_iv_info");
@@ -3780,9 +3787,9 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
            {
              int multi_insn_incr = 0;
 
-             if (basic_induction_var (SET_SRC (set), GET_MODE (SET_SRC (set)),
-                                      dest_reg, p, loop->level,
-                                      &inc_val, &mult_val,
+             if (basic_induction_var (loop, SET_SRC (set),
+                                      GET_MODE (SET_SRC (set)),
+                                      dest_reg, p, &inc_val, &mult_val,
                                       &location, &multi_insn_incr))
                {
                  /* It is a possible basic induction variable.
@@ -3860,9 +3867,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
             matter.  Check to see if the target of this branch is on the
             loop->exits_labels list.  */
             
-         for (label = uid_loop[INSN_UID (loop_start)]->exit_labels;
-              label;
-              label = LABEL_NEXTREF (label))
+         for (label = loop->exit_labels; label; label = LABEL_NEXTREF (label))
            if (XEXP (label, 0) == JUMP_LABEL (p))
              break;
 
@@ -3999,7 +4004,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
       if (GET_CODE (p) == JUMP_INSN
          && JUMP_LABEL (p) != 0
          && next_real_insn (JUMP_LABEL (p)) == next_real_insn (loop_end)
-         && (test = get_condition_for_loop (p)) != 0
+         && (test = get_condition_for_loop (loop, p)) != 0
          && GET_CODE (XEXP (test, 0)) == REG
          && REGNO (XEXP (test, 0)) < max_reg_before_loop
          && (bl = reg_biv_class[REGNO (XEXP (test, 0))]) != 0
@@ -4080,8 +4085,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
              && GET_CODE (src) == PLUS
              && GET_CODE (XEXP (src, 0)) == REG
              && CONSTANT_P (XEXP (src, 1))
-             && ((increment = biv_total_increment (bl, loop_start, loop_end))
-                 != NULL_RTX))
+             && ((increment = biv_total_increment (bl)) != NULL_RTX))
            {
              int regno = REGNO (XEXP (src, 0));
 
@@ -4093,8 +4097,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
          /* Now, can we transform this biv into a giv?  */
          if (bl2
              && bl2->biv_count == 1
-             && rtx_equal_p (increment,
-                             biv_total_increment (bl2, loop_start, loop_end))
+             && rtx_equal_p (increment, biv_total_increment (bl2))
              /* init_insn is only set to insns that are before loop_start
                 without any intervening labels.  */
              && ! reg_set_between_p (bl2->biv->src_reg,
@@ -4114,7 +4117,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
                                  &SET_SRC (single_set (bl->biv->insn)),
                                  copy_rtx (src), 0))
            {
-             rtx dominator = uid_loop[INSN_UID (loop_start)]->cont_dominator;
+             rtx dominator = loop->cont_dominator;
              rtx giv = bl->biv->src_reg;
              rtx giv_insn = bl->biv->insn;
              rtx after_giv = NEXT_INSN (giv_insn);
@@ -4467,11 +4470,11 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
            continue;
 
          if (/* SET_SRC is a giv.  */
-             (general_induction_var (SET_SRC (set), &src_reg, &add_val,
+             (general_induction_var (loop, SET_SRC (set), &src_reg, &add_val,
                                      &mult_val, 0, &benefit)
               /* Equivalent expression is a giv.  */
               || ((regnote = find_reg_note (p, REG_EQUAL, NULL_RTX))
-                  && general_induction_var (XEXP (regnote, 0), &src_reg,
+                  && general_induction_var (loop, XEXP (regnote, 0), &src_reg,
                                             &add_val, &mult_val, 0,
                                             &benefit)))
              /* Don't try to handle any regs made by loop optimization.
@@ -4482,7 +4485,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
              /* This must be the only place where the register is set.  */
              && (VARRAY_INT (n_times_set, REGNO (dest_reg)) == 1
                  /* or all sets must be consecutive and make a giv.  */
-                 || (benefit = consec_sets_giv (benefit, p,
+                 || (benefit = consec_sets_giv (loop, benefit, p,
                                                 src_reg, dest_reg,
                                                 &add_val, &mult_val,
                                                 &last_consec_insn))))
@@ -4498,9 +4501,9 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
              if (VARRAY_INT (n_times_set, REGNO (dest_reg)) != 1)
                p = last_consec_insn;
 
-             record_giv (v, p, src_reg, dest_reg, mult_val, add_val, benefit,
-                         DEST_REG, not_every_iteration, maybe_multiple,
-                         NULL_PTR, loop_start, loop_end);
+             record_giv (loop, v, p, src_reg, dest_reg, mult_val, add_val,
+                         benefit, DEST_REG, not_every_iteration,
+                         maybe_multiple, NULL_PTR);
 
            }
        }
@@ -4510,15 +4513,15 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
       /* This resulted in worse code on a VAX 8600.  I wonder if it
         still does.  */
       if (GET_CODE (p) == INSN)
-       find_mem_givs (PATTERN (p), p, not_every_iteration, maybe_multiple,
-                      loop_start, loop_end);
+       find_mem_givs (loop, PATTERN (p), p, not_every_iteration,
+                      maybe_multiple);
 #endif
 
       /* Update the status of whether giv can derive other givs.  This can
         change when we pass a label or an insn that updates a biv.  */
       if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN
        || GET_CODE (p) == CODE_LABEL)
-       update_giv_derive (p);
+       update_giv_derive (loop, p);
 
       /* Past CODE_LABEL, we get to insns that may be executed multiple
         times.  The only way we can be sure that they can't is if every
@@ -4582,9 +4585,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
             matter.  Check to see if the target of this branch is on the
             loop->exits_labels list.  */
             
-         for (label = uid_loop[INSN_UID (loop_start)]->exit_labels;
-              label;
-              label = LABEL_NEXTREF (label))
+         for (label = loop->exit_labels; label; label = LABEL_NEXTREF (label))
            if (XEXP (label, 0) == JUMP_LABEL (p))
              break;
 
@@ -4643,7 +4644,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
 
       for (v = bl->giv; v; v = v->next_iv)
        if (! v->replaceable && ! v->not_replaceable)
-         check_final_value (v, loop_start, loop_end, loop_info->n_iterations);
+         check_final_value (loop, v);
     }
 
   /* Try to prove that the loop counter variable (if any) is always
@@ -4692,14 +4693,13 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
           && ! 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, 
-                                             loop_info->n_iterations))
+         || ((final_value = final_biv_value (loop, bl))
 #ifdef HAVE_decrement_and_branch_until_zero
              && ! bl->nonneg
 #endif
              ))
-       bl->eliminable = maybe_eliminate_biv (bl, loop_start, loop_end, 0,
-                                             threshold, insn_count);
+       bl->eliminable = maybe_eliminate_biv (loop, bl, 0, threshold, 
+                                             insn_count);
       else
        {
          if (loop_dump_stream)
@@ -4863,7 +4863,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
          VARRAY_GROW (reg_iv_type, nregs);
          VARRAY_GROW (reg_iv_info, nregs);
        }
-      recombine_givs (bl, loop_start, loop_end, unroll_p);
+      recombine_givs (loop, bl, unroll_p);
 
       /* Reduce each giv that we decided to reduce.  */
 
@@ -5096,7 +5096,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
                 loop to ensure that it will always be executed no matter
                 how the loop exits.  Otherwise, emit the insn after the loop,
                 since this is slightly more efficient.  */
-             if (uid_loop[INSN_UID (loop_start)]->exit_count)
+             if (loop->exit_count)
                insert_before = loop_start;
              else
                insert_before = end_insert_before;
@@ -5164,9 +5164,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
         doing so in the rare cases where it can occur.  */
 
       if (all_reduced == 1 && bl->eliminable
-         && maybe_eliminate_biv (bl, loop_start, loop_end, 1,
-                                 threshold, insn_count))
-
+         && maybe_eliminate_biv (loop, bl, 1, threshold, insn_count))
        {
          /* ?? If we created a new test to bypass the loop entirely,
             or otherwise drop straight in, based on this test, then
@@ -5188,7 +5186,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
                 loop to ensure that it will always be executed no matter
                 how the loop exits.  Otherwise, emit the insn after the
                 loop, since this is slightly more efficient.  */
-             if (uid_loop[INSN_UID (loop_start)]->exit_count)
+             if (loop->exit_count)
                insert_before = loop_start;
              else
                insert_before = end_insert_before;
@@ -5328,12 +5326,11 @@ valid_initial_value_p (x, insn, call_seen, loop_start)
    more thanonce in each loop iteration.  */
 
 static void
-find_mem_givs (x, insn, not_every_iteration, maybe_multiple, loop_start,
-              loop_end)
+find_mem_givs (loop, x, insn, not_every_iteration, maybe_multiple)
+     const struct loop *loop;
      rtx x;
      rtx insn;
      int not_every_iteration, maybe_multiple;
-     rtx loop_start, loop_end;
 {
   register int i, j;
   register enum rtx_code code;
@@ -5371,16 +5368,16 @@ find_mem_givs (x, insn, not_every_iteration, maybe_multiple, loop_start,
           it comes time to combine a set of related DEST_ADDR GIVs, since
           this one would not be seen.   */
 
-       if (general_induction_var (XEXP (x, 0), &src_reg, &add_val,
+       if (general_induction_var (loop, XEXP (x, 0), &src_reg, &add_val,
                                   &mult_val, 1, &benefit))
          {
            /* Found one; record it.  */
            struct induction *v
              = (struct induction *) oballoc (sizeof (struct induction));
 
-           record_giv (v, insn, src_reg, addr_placeholder, mult_val,
+           record_giv (loop, v, insn, src_reg, addr_placeholder, mult_val,
                        add_val, benefit, DEST_ADDR, not_every_iteration,
-                       maybe_multiple, &XEXP (x, 0), loop_start, loop_end);
+                       maybe_multiple, &XEXP (x, 0));
 
            v->mem_mode = GET_MODE (x);
          }
@@ -5396,12 +5393,12 @@ find_mem_givs (x, insn, not_every_iteration, maybe_multiple, loop_start,
   fmt = GET_RTX_FORMAT (code);
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     if (fmt[i] == 'e')
-      find_mem_givs (XEXP (x, i), insn, not_every_iteration, maybe_multiple,
-                    loop_start, loop_end);
+      find_mem_givs (loop, XEXP (x, i), insn, not_every_iteration,
+                    maybe_multiple);
     else if (fmt[i] == 'E')
       for (j = 0; j < XVECLEN (x, i); j++)
-       find_mem_givs (XVECEXP (x, i, j), insn, not_every_iteration,
-                      maybe_multiple, loop_start, loop_end);
+       find_mem_givs (loop, XVECEXP (x, i, j), insn, not_every_iteration,
+                      maybe_multiple);
 }
 \f
 /* Fill in the data about one biv update.
@@ -5524,9 +5521,9 @@ record_biv (v, insn, dest_reg, inc_val, mult_val, location,
    LOCATION points to the place where this giv's value appears in INSN.  */
 
 static void
-record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
-           type, not_every_iteration, maybe_multiple, location, loop_start,
-           loop_end)
+record_giv (loop, v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
+           type, not_every_iteration, maybe_multiple, location)
+     const struct loop *loop;
      struct induction *v;
      rtx insn;
      rtx src_reg;
@@ -5536,7 +5533,6 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
      enum g_types type;
      int not_every_iteration, maybe_multiple;
      rtx *location;
-     rtx loop_start, loop_end;
 {
   struct induction *b;
   struct iv_class *bl;
@@ -5637,7 +5633,8 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
 
       if (REGNO_FIRST_UID (REGNO (dest_reg)) == INSN_UID (insn)
          /* Previous line always fails if INSN was moved by loop opt.  */
-         && uid_luid[REGNO_LAST_UID (REGNO (dest_reg))] < INSN_LUID (loop_end)
+         && uid_luid[REGNO_LAST_UID (REGNO (dest_reg))] 
+         < INSN_LUID (loop->end)
          && (! not_every_iteration
              || last_use_this_basic_block (dest_reg, insn)))
        {
@@ -5674,7 +5671,7 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
             biv update to before it, then this giv is not replaceable.  */
          if (v->replaceable)
            for (b = bl->biv; b; b = b->next_iv)
-             if (back_branch_in_range_p (b->insn, loop_start, loop_end))
+             if (back_branch_in_range_p (loop, b->insn))
                {
                  v->replaceable = 0;
                  v->not_replaceable = 1;
@@ -5772,10 +5769,9 @@ 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, n_iterations)
+check_final_value (loop, v)
+     const struct loop *loop;
      struct induction *v;
-     rtx loop_start, loop_end;
-     unsigned HOST_WIDE_INT n_iterations;
 {
   struct iv_class *bl;
   rtx final_value = 0;
@@ -5802,7 +5798,7 @@ check_final_value (v, loop_start, loop_end, n_iterations)
   v->replaceable = 0;
 #endif
 
-  if ((final_value = final_giv_value (v, loop_start, loop_end, n_iterations))
+  if ((final_value = final_giv_value (loop, v))
       && (v->always_computable || last_use_this_basic_block (v->dest_reg, v->insn)))
     {
       int biv_increment_seen = 0;
@@ -5834,8 +5830,8 @@ check_final_value (v, loop_start, loop_end, n_iterations)
       while (1)
        {
          p = NEXT_INSN (p);
-         if (p == loop_end)
-           p = NEXT_INSN (loop_start);
+         if (p == loop->end)
+           p = NEXT_INSN (loop->start);
          if (p == v->insn)
            break;
 
@@ -5868,17 +5864,17 @@ check_final_value (v, loop_start, loop_end, n_iterations)
          while (1)
            {
              p = NEXT_INSN (p);
-             if (p == loop_end)
-               p = NEXT_INSN (loop_start);
+             if (p == loop->end)
+               p = NEXT_INSN (loop->start);
              if (p == last_giv_use)
                break;
 
              if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p)
                  && LABEL_NAME (JUMP_LABEL (p))
                  && ((loop_insn_first_p (JUMP_LABEL (p), v->insn)
-                      && loop_insn_first_p (loop_start, JUMP_LABEL (p)))
+                      && loop_insn_first_p (loop->start, JUMP_LABEL (p)))
                      || (loop_insn_first_p (last_giv_use, JUMP_LABEL (p))
-                         && loop_insn_first_p (JUMP_LABEL (p), loop_end))))
+                         && loop_insn_first_p (JUMP_LABEL (p), loop->end))))
                {
                  v->replaceable = 0;
                  v->not_replaceable = 1;
@@ -5914,7 +5910,8 @@ check_final_value (v, loop_start, loop_end, n_iterations)
    The cases we look at are when a label or an update to a biv is passed.  */
 
 static void
-update_giv_derive (p)
+update_giv_derive (loop, p)
+     const  struct loop *loop;
      rtx p;
 {
   struct iv_class *bl;
@@ -5982,14 +5979,16 @@ update_giv_derive (p)
                  tem = 0;
 
                  if (biv->mult_val == const1_rtx)
-                   tem = simplify_giv_expr (gen_rtx_MULT (giv->mode,
+                   tem = simplify_giv_expr (loop,
+                                            gen_rtx_MULT (giv->mode,
                                                           biv->add_val,
                                                           giv->mult_val),
                                             &dummy);
 
                  if (tem && giv->derive_adjustment)
                    tem = simplify_giv_expr
-                     (gen_rtx_PLUS (giv->mode, tem, giv->derive_adjustment),
+                     (loop,
+                      gen_rtx_PLUS (giv->mode, tem, giv->derive_adjustment),
                       &dummy);
 
                  if (tem)
@@ -6042,13 +6041,13 @@ update_giv_derive (p)
    If we cannot find a biv, we return 0.  */
 
 static int
-basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val,
+basic_induction_var (loop, x, mode, dest_reg, p, inc_val, mult_val,
                     location, multi_insn_incr)
+     const struct loop *loop;
      register rtx x;
      enum machine_mode mode;
      rtx dest_reg;
      rtx p;
-     int level;
      rtx *inc_val;
      rtx *mult_val;
      rtx **location;
@@ -6081,7 +6080,7 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val,
        return 0;
 
       arg = *argp;
-      if (invariant_p (arg) != 1)
+      if (loop_invariant_p (loop, arg) != 1)
        return 0;
 
       *inc_val = convert_modes (GET_MODE (dest_reg), GET_MODE (x), arg, 0);
@@ -6093,9 +6092,9 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val,
       /* If this is a SUBREG for a promoted variable, check the inner
         value.  */
       if (SUBREG_PROMOTED_VAR_P (x))
-       return basic_induction_var (SUBREG_REG (x), GET_MODE (SUBREG_REG (x)),
-                                   dest_reg, p, level, 
-                                   inc_val, mult_val, location,
+       return basic_induction_var (loop, SUBREG_REG (x),
+                                   GET_MODE (SUBREG_REG (x)),
+                                   dest_reg, p, inc_val, mult_val, location,
                                    multi_insn_incr);
       return 0;
 
@@ -6124,11 +6123,11 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val,
                   && (GET_MODE_CLASS (GET_MODE (SET_DEST (set)))
                       == MODE_INT)
                   && SUBREG_REG (SET_DEST (set)) == x))
-             && basic_induction_var (SET_SRC (set),
+             && basic_induction_var (loop, SET_SRC (set),
                                      (GET_MODE (SET_SRC (set)) == VOIDmode
                                       ? GET_MODE (x)
                                       : GET_MODE (SET_SRC (set))),
-                                     dest_reg, insn, level,
+                                     dest_reg, insn,
                                      inc_val, mult_val, location,
                                      multi_insn_incr))
            {
@@ -6143,7 +6142,7 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val,
         as a biv of the outer loop,
         causing code to be moved INTO the inner loop.  */
     case MEM:
-      if (invariant_p (x) != 1)
+      if (loop_invariant_p (loop, x) != 1)
        return 0;
     case CONST_INT:
     case SYMBOL_REF:
@@ -6151,7 +6150,7 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val,
       /* convert_modes aborts if we try to convert to or from CCmode, so just
          exclude that case.  It is very unlikely that a condition code value
         would be a useful iterator anyways.  */
-      if (level == 0
+      if (loop->level == 1
          && GET_MODE_CLASS (mode) != MODE_CC
          && GET_MODE_CLASS (GET_MODE (dest_reg)) != MODE_CC)
        {
@@ -6164,9 +6163,9 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val,
        return 0;
 
     case SIGN_EXTEND:
-      return basic_induction_var (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
-                                 dest_reg, p, level, inc_val, mult_val,
-                                 location, multi_insn_incr);
+      return basic_induction_var (loop, XEXP (x, 0), GET_MODE (XEXP (x, 0)),
+                                 dest_reg, p, inc_val, mult_val, location,
+                                 multi_insn_incr);
 
     case ASHIFTRT:
       /* Similar, since this can be a sign extension.  */
@@ -6184,9 +6183,9 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val,
          && INTVAL (XEXP (x, 1)) >= 0
          && GET_CODE (SET_SRC (set)) == ASHIFT
          && XEXP (x, 1) == XEXP (SET_SRC (set), 1)
-         && basic_induction_var (XEXP (SET_SRC (set), 0),
+         && basic_induction_var (loop, XEXP (SET_SRC (set), 0),
                                  GET_MODE (XEXP (x, 0)),
-                                 dest_reg, insn, level, inc_val, mult_val,
+                                 dest_reg, insn, inc_val, mult_val,
                                  location, multi_insn_incr))
        {
          *multi_insn_incr = 1;
@@ -6214,7 +6213,8 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val,
      such that the value of X is biv * mult + add;  */
 
 static int
-general_induction_var (x, src_reg, add_val, mult_val, is_addr, pbenefit)
+general_induction_var (loop, x, src_reg, add_val, mult_val, is_addr, pbenefit)
+     const struct loop *loop;
      rtx x;
      rtx *src_reg;
      rtx *add_val;
@@ -6226,14 +6226,14 @@ general_induction_var (x, src_reg, add_val, mult_val, is_addr, pbenefit)
   char *storage;
 
   /* If this is an invariant, forget it, it isn't a giv.  */
-  if (invariant_p (x) == 1)
+  if (loop_invariant_p (loop, x) == 1)
     return 0;
 
   /* See if the expression could be a giv and get its form.
      Mark our place on the obstack in case we don't find a giv.  */
   storage = (char *) oballoc (0);
   *pbenefit = 0;
-  x = simplify_giv_expr (x, pbenefit);
+  x = simplify_giv_expr (loop, x, pbenefit);
   if (x == 0)
     {
       obfree (storage);
@@ -6336,7 +6336,8 @@ static int cmp_combine_givs_stats PARAMS ((const PTR, const PTR));
 static int cmp_recombine_givs_stats PARAMS ((const PTR, const PTR));
 
 static rtx
-simplify_giv_expr (x, benefit)
+simplify_giv_expr (loop, x, benefit)
+     const struct loop *loop;
      rtx x;
      int *benefit;
 {
@@ -6354,8 +6355,8 @@ simplify_giv_expr (x, benefit)
   switch (GET_CODE (x))
     {
     case PLUS:
-      arg0 = simplify_giv_expr (XEXP (x, 0), benefit);
-      arg1 = simplify_giv_expr (XEXP (x, 1), benefit);
+      arg0 = simplify_giv_expr (loop, XEXP (x, 0), benefit);
+      arg1 = simplify_giv_expr (loop, XEXP (x, 1), benefit);
       if (arg0 == 0 || arg1 == 0)
        return NULL_RTX;
 
@@ -6401,7 +6402,8 @@ simplify_giv_expr (x, benefit)
          case PLUS:
            /* (a + invar_1) + invar_2.  Associate.  */
            return
-             simplify_giv_expr (gen_rtx_PLUS (mode,
+             simplify_giv_expr (loop,
+                                gen_rtx_PLUS (mode,
                                               XEXP (arg0, 0),
                                               gen_rtx_PLUS (mode,
                                                             XEXP (arg0, 1),
@@ -6427,7 +6429,8 @@ simplify_giv_expr (x, benefit)
 
       if (GET_CODE (arg1) == PLUS)
          return
-           simplify_giv_expr (gen_rtx_PLUS (mode,
+           simplify_giv_expr (loop,
+                              gen_rtx_PLUS (mode,
                                             gen_rtx_PLUS (mode, arg0,
                                                           XEXP (arg1, 0)),
                                             XEXP (arg1, 1)),
@@ -6440,7 +6443,8 @@ simplify_giv_expr (x, benefit)
       if (!rtx_equal_p (arg0, arg1))
        return NULL_RTX;
 
-      return simplify_giv_expr (gen_rtx_MULT (mode,
+      return simplify_giv_expr (loop,
+                               gen_rtx_MULT (mode,
                                              XEXP (arg0, 0),
                                              gen_rtx_PLUS (mode,
                                                            XEXP (arg0, 1),
@@ -6449,7 +6453,8 @@ simplify_giv_expr (x, benefit)
 
     case MINUS:
       /* Handle "a - b" as "a + b * (-1)".  */
-      return simplify_giv_expr (gen_rtx_PLUS (mode,
+      return simplify_giv_expr (loop,
+                               gen_rtx_PLUS (mode,
                                              XEXP (x, 0),
                                              gen_rtx_MULT (mode,
                                                            XEXP (x, 1),
@@ -6457,8 +6462,8 @@ simplify_giv_expr (x, benefit)
                                benefit);
 
     case MULT:
-      arg0 = simplify_giv_expr (XEXP (x, 0), benefit);
-      arg1 = simplify_giv_expr (XEXP (x, 1), benefit);
+      arg0 = simplify_giv_expr (loop, XEXP (x, 0), benefit);
+      arg1 = simplify_giv_expr (loop, XEXP (x, 1), benefit);
       if (arg0 == 0 || arg1 == 0)
        return NULL_RTX;
 
@@ -6511,7 +6516,8 @@ simplify_giv_expr (x, benefit)
 
        case MULT:
          /* (a * invar_1) * invar_2.  Associate.  */
-         return simplify_giv_expr (gen_rtx_MULT (mode,
+         return simplify_giv_expr (loop,
+                                   gen_rtx_MULT (mode,
                                                  XEXP (arg0, 0),
                                                  gen_rtx_MULT (mode,
                                                                XEXP (arg0, 1),
@@ -6520,7 +6526,8 @@ simplify_giv_expr (x, benefit)
 
        case PLUS:
          /* (a + invar_1) * invar_2.  Distribute.  */
-         return simplify_giv_expr (gen_rtx_PLUS (mode,
+         return simplify_giv_expr (loop,
+                                   gen_rtx_PLUS (mode,
                                                  gen_rtx_MULT (mode,
                                                                XEXP (arg0, 0),
                                                                arg1),
@@ -6539,7 +6546,8 @@ simplify_giv_expr (x, benefit)
        return 0;
 
       return
-       simplify_giv_expr (gen_rtx_MULT (mode,
+       simplify_giv_expr (loop,
+                          gen_rtx_MULT (mode,
                                         XEXP (x, 0),
                                         GEN_INT ((HOST_WIDE_INT) 1
                                                  << INTVAL (XEXP (x, 1)))),
@@ -6547,12 +6555,14 @@ simplify_giv_expr (x, benefit)
 
     case NEG:
       /* "-a" is "a * (-1)" */
-      return simplify_giv_expr (gen_rtx_MULT (mode, XEXP (x, 0), constm1_rtx),
+      return simplify_giv_expr (loop,
+                               gen_rtx_MULT (mode, XEXP (x, 0), constm1_rtx),
                                benefit);
 
     case NOT:
       /* "~a" is "-a - 1". Silly, but easy.  */
-      return simplify_giv_expr (gen_rtx_MINUS (mode,
+      return simplify_giv_expr (loop,
+                               gen_rtx_MINUS (mode,
                                               gen_rtx_NEG (mode, XEXP (x, 0)),
                                               const1_rtx),
                                benefit);
@@ -6587,14 +6597,14 @@ simplify_giv_expr (x, benefit)
 
            if (v->derive_adjustment)
              tem = gen_rtx_MINUS (mode, tem, v->derive_adjustment);
-           return simplify_giv_expr (tem, benefit);
+           return simplify_giv_expr (loop, tem, benefit);
          }
 
        default:
          /* If it isn't an induction variable, and it is invariant, we
             may be able to simplify things further by looking through
             the bits we just moved outside the loop.  */
-         if (invariant_p (x) == 1)
+         if (loop_invariant_p (loop, x) == 1)
            {
              struct movable *m;
 
@@ -6606,7 +6616,8 @@ simplify_giv_expr (x, benefit)
                    /* If we match another movable, we must use that, as 
                       this one is going away.  */
                    if (m->match)
-                     return simplify_giv_expr (m->match->set_dest, benefit);
+                     return simplify_giv_expr (loop, m->match->set_dest, 
+                                               benefit);
 
                    /* If consec is non-zero, this is a member of a group of
                       instructions that were moved together.  We handle this
@@ -6640,7 +6651,7 @@ simplify_giv_expr (x, benefit)
                            || GET_CODE (tem) == CONST_INT
                            || GET_CODE (tem) == SYMBOL_REF)
                          {
-                           tem = simplify_giv_expr (tem, benefit);
+                           tem = simplify_giv_expr (loop, tem, benefit);
                            if (tem)
                              return tem;
                          }
@@ -6649,7 +6660,8 @@ simplify_giv_expr (x, benefit)
                            && GET_CODE (XEXP (XEXP (tem, 0), 0)) == SYMBOL_REF
                            && GET_CODE (XEXP (XEXP (tem, 0), 1)) == CONST_INT)
                          {
-                           tem = simplify_giv_expr (XEXP (tem, 0), benefit);
+                           tem = simplify_giv_expr (loop, XEXP (tem, 0),
+                                                    benefit);
                            if (tem)
                              return tem;
                          }
@@ -6667,7 +6679,7 @@ simplify_giv_expr (x, benefit)
       if (GET_CODE (x) == USE)
        x = XEXP (x, 0);
 
-      if (invariant_p (x) == 1)
+      if (loop_invariant_p (loop, x) == 1)
        {
          if (GET_CODE (x) == CONST_INT)
            return x;
@@ -6753,8 +6765,9 @@ sge_plus (mode, x, y)
    *MULT_VAL and *ADD_VAL.  */
 
 static int
-consec_sets_giv (first_benefit, p, src_reg, dest_reg,
+consec_sets_giv (loop, first_benefit, p, src_reg, dest_reg,
                 add_val, mult_val, last_consec_insn)
+     const struct loop *loop;
      int first_benefit;
      rtx p;
      rtx src_reg;
@@ -6803,11 +6816,11 @@ consec_sets_giv (first_benefit, p, src_reg, dest_reg,
          && (set = single_set (p))
          && GET_CODE (SET_DEST (set)) == REG
          && SET_DEST (set) == dest_reg
-         && (general_induction_var (SET_SRC (set), &src_reg,
+         && (general_induction_var (loop, SET_SRC (set), &src_reg,
                                     add_val, mult_val, 0, &benefit)
              /* Giv created by equivalent expression.  */
              || ((temp = find_reg_note (p, REG_EQUAL, NULL_RTX))
-                 && general_induction_var (XEXP (temp, 0), &src_reg,
+                 && general_induction_var (loop, XEXP (temp, 0), &src_reg,
                                            add_val, mult_val, 0, &benefit)))
          && src_reg == v->src_reg)
        {
@@ -7380,9 +7393,9 @@ find_life_end (x, stats, insn, biv)
    This tends to shorten giv lifetimes, and helps the next step:
    try to derive givs from other givs.  */
 static void
-recombine_givs (bl, loop_start, loop_end, unroll_p)
+recombine_givs (loop, bl, unroll_p)
+     const struct loop *loop;
      struct iv_class *bl;
-     rtx loop_start, loop_end;
      int unroll_p;
 {
   struct induction *v, **giv_array, *last_giv;
@@ -7535,7 +7548,7 @@ recombine_givs (bl, loop_start, loop_end, unroll_p)
              else
                {
                  stats[i].end_luid = uid_luid[REGNO_LAST_UID (regno)];
-                 if (stats[i].end_luid > INSN_LUID (loop_end))
+                 if (stats[i].end_luid > INSN_LUID (loop->end))
                    {
                      stats[i].end_luid = -1;
                      ends_need_computing++;
@@ -7550,12 +7563,12 @@ recombine_givs (bl, loop_start, loop_end, unroll_p)
   if (ends_need_computing)
     {
       rtx biv = bl->biv->src_reg;
-      rtx p = loop_end;
+      rtx p = loop->end;
 
       do
        {
-         if (p == loop_start)
-           p = loop_end;
+         if (p == loop->start)
+           p = loop->end;
          p = PREV_INSN (p);
          if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
            continue;
@@ -7641,8 +7654,8 @@ recombine_givs (bl, loop_start, loop_end, unroll_p)
                  derived giv would defeat the purpose of reducing register
                  pressure.
                  ??? We could arrange to move the insn.  */
-             && ((unsigned) stats[i].end_luid - INSN_LUID (loop_start)
-                  > (unsigned) stats[i].start_luid - INSN_LUID (loop_start))
+             && ((unsigned) stats[i].end_luid - INSN_LUID (loop->start)
+                  > (unsigned) stats[i].start_luid - INSN_LUID (loop->start))
              && rtx_equal_p (last_giv->mult_val, v->mult_val)
              /* ??? Could handle libcalls, but would need more logic.  */
              && ! find_reg_note (v->insn, REG_RETVAL, NULL_RTX)
@@ -7860,7 +7873,7 @@ check_dbra_loop (loop, insn_count)
      register value, try to optimize it.  Otherwise, we can't do anything.  */
 
   jump = PREV_INSN (loop_end);
-  comparison = get_condition_for_loop (jump);
+  comparison = get_condition_for_loop (loop, jump);
   if (comparison == 0)
     return 0;
 
@@ -7931,7 +7944,7 @@ check_dbra_loop (loop, insn_count)
          if (GET_CODE (p) != JUMP_INSN)
            continue;
 
-         before_comparison = get_condition_for_loop (p);
+         before_comparison = get_condition_for_loop (loop, p);
          if (before_comparison
              && XEXP (before_comparison, 0) == bl->biv->dest_reg
              && GET_CODE (before_comparison) == LT
@@ -7969,8 +7982,7 @@ check_dbra_loop (loop, insn_count)
         which is reversible.  */
       int reversible_mem_store = 1;
 
-      if (bl->giv_count == 0
-         && ! uid_loop[INSN_UID (loop_start)]->exit_count)
+      if (bl->giv_count == 0 && ! loop->exit_count)
        {
          rtx bivreg = regno_reg_rtx[bl->regno];
 
@@ -8018,7 +8030,7 @@ check_dbra_loop (loop, insn_count)
        {
          for (p = loop_start; p != loop_end; p = NEXT_INSN (p))
            if (GET_RTX_CLASS (GET_CODE (p)) == 'i')
-             num_nonfixed_reads += count_nonfixed_reads (PATTERN (p));
+             num_nonfixed_reads += count_nonfixed_reads (loop, PATTERN (p));
 
          /* If the loop has a single store, and the destination address is
             invariant, then we can't reverse the loop, because this address
@@ -8033,7 +8045,9 @@ check_dbra_loop (loop, insn_count)
              reversible_mem_store
                = (! unknown_address_altered
                   && ! unknown_constant_address_altered
-                  && ! invariant_p (XEXP (XEXP (loop_store_mems, 0), 0)));
+                  && ! loop_invariant_p (loop,
+                                         XEXP (XEXP (loop_store_mems, 0),
+                                               0)));
 
              /* If the store depends on a register that is set after the
                 store, it depends on the initial value, and is thus not
@@ -8115,7 +8129,7 @@ check_dbra_loop (loop, insn_count)
                 ??? If the insns which initialize the comparison value as
                 a whole compute an invariant result, then we could move
                 them out of the loop and proceed with loop reversal.  */
-             if (!invariant_p (comparison_value))
+             if (! loop_invariant_p (loop, comparison_value))
                return 0;
 
              if (GET_CODE (comparison_value) == CONST_INT)
@@ -8403,7 +8417,6 @@ check_dbra_loop (loop, insn_count)
 \f
 /* Verify whether the biv BL appears to be eliminable,
    based on the insns in the loop that refer to it.
-   LOOP_START is the first insn of the loop, and END is the end insn.
 
    If ELIMINATE_P is non-zero, actually do the elimination.
 
@@ -8412,15 +8425,15 @@ check_dbra_loop (loop, insn_count)
    start of the loop.  */
 
 static int
-maybe_eliminate_biv (bl, loop_start, loop_end, eliminate_p, threshold,
-                    insn_count)
+maybe_eliminate_biv (loop, bl, eliminate_p, threshold, insn_count)
+     const struct loop *loop;
      struct iv_class *bl;
-     rtx loop_start;
-     rtx loop_end;
      int eliminate_p;
      int threshold, insn_count;
 {
   rtx reg = bl->biv->dest_reg;
+  rtx loop_start = loop->start;
+  rtx loop_end = loop->end;
   rtx p;
 
   /* Scan all insns in the loop, stopping if we find one that uses the
@@ -8454,7 +8467,8 @@ maybe_eliminate_biv (bl, loop_start, loop_end, eliminate_p, threshold,
        }
       if ((code == INSN || code == JUMP_INSN || code == CALL_INSN)
          && reg_mentioned_p (reg, PATTERN (p))
-         && ! maybe_eliminate_biv_1 (PATTERN (p), p, bl, eliminate_p, where))
+         && ! maybe_eliminate_biv_1 (loop, PATTERN (p), p, bl,
+                                     eliminate_p, where))
        {
          if (loop_dump_stream)
            fprintf (loop_dump_stream,
@@ -8558,7 +8572,8 @@ biv_elimination_giv_has_0_offset (biv, giv, insn)
    the loop.  */
 
 static int
-maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where)
+maybe_eliminate_biv_1 (loop, x, insn, bl, eliminate_p, where)
+     const struct loop *loop;
      rtx x, insn;
      struct iv_class *bl;
      int eliminate_p;
@@ -8777,7 +8792,7 @@ maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where)
        }
       else if (GET_CODE (arg) == REG || GET_CODE (arg) == MEM)
        {
-         if (invariant_p (arg) == 1)
+         if (loop_invariant_p (loop, arg) == 1)
            {
              /* Look for giv with constant positive mult_val and nonconst
                 add_val. Insert insns to compute new compare value. 
@@ -8884,14 +8899,14 @@ maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where)
       switch (fmt[i])
        {
        case 'e':
-         if (! maybe_eliminate_biv_1 (XEXP (x, i), insn, bl, 
+         if (! maybe_eliminate_biv_1 (loop, XEXP (x, i), insn, bl, 
                                       eliminate_p, where))
            return 0;
          break;
 
        case 'E':
          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-           if (! maybe_eliminate_biv_1 (XVECEXP (x, i, j), insn, bl,
+           if (! maybe_eliminate_biv_1 (loop, XVECEXP (x, i, j), insn, bl,
                                         eliminate_p, where))
              return 0;
          break;
@@ -9250,14 +9265,15 @@ get_condition (jump, earliest)
    unless both operands are invariants.  */
 
 rtx
-get_condition_for_loop (x)
+get_condition_for_loop (loop, x)
+     const struct loop *loop;
      rtx x;
 {
   rtx comparison = get_condition (x, NULL_PTR);
 
   if (comparison == 0
-      || ! invariant_p (XEXP (comparison, 0))
-      || invariant_p (XEXP (comparison, 1)))
+      || ! loop_invariant_p (loop, XEXP (comparison, 0))
+      || loop_invariant_p (loop, XEXP (comparison, 1)))
     return comparison;
 
   return gen_rtx_fmt_ee (swap_condition (GET_CODE (comparison)), VOIDmode,
@@ -9762,7 +9778,7 @@ load_mems (loop)
       rtx mem_list_entry;
 
       if (MEM_VOLATILE_P (mem) 
-         || invariant_p (XEXP (mem, 0)) != 1)
+         || loop_invariant_p (loop, XEXP (mem, 0)) != 1)
        /* There's no telling whether or not MEM is modified.  */
        loop_mems[i].optimize = 0;
 
@@ -9874,7 +9890,7 @@ load_mems (loop)
          int j;
          rtx set;
 
-         /* Load the memory immediately before START, which is
+         /* Load the memory immediately before LOOP->START, which is
             the NOTE_LOOP_BEG.  */
          set = gen_move_insn (reg, mem);
          emit_insn_before (set, loop->start);
@@ -9963,8 +9979,7 @@ note_reg_stored (x, setter, arg)
 /* Try to replace every occurrence of pseudo REGNO with REPLACEMENT.
    There must be exactly one insn that sets this pseudo; it will be
    deleted if all replacements succeed and we can prove that the register
-   is not used after the loop.
-   The arguments SCAN_START, LOOP_TOP and END are as in load_mems.  */
+   is not used after the loop.  */
 static void
 try_copy_prop (loop, replacement, regno)
      const struct loop *loop;
index 10a7131..8fbde21 100644 (file)
@@ -230,23 +230,21 @@ extern int first_increment_giv, last_increment_giv;
 
 /* Forward declarations for non-static functions declared in loop.c and
    unroll.c.  */
-int invariant_p PARAMS ((rtx));
-rtx get_condition_for_loop PARAMS ((rtx));
+int loop_invariant_p PARAMS ((const struct loop *, rtx));
+rtx get_condition_for_loop PARAMS ((const struct loop *, rtx));
 void emit_iv_add_mult PARAMS ((rtx, rtx, rtx, rtx, rtx));
 rtx express_from PARAMS ((struct induction *, struct induction *));
 
 void unroll_loop PARAMS ((struct loop *, int, rtx, int));
-rtx biv_total_increment PARAMS ((struct iv_class *, rtx, rtx));
+rtx biv_total_increment PARAMS ((struct iv_class *));
 unsigned HOST_WIDE_INT loop_iterations PARAMS ((struct loop *));
-int precondition_loop_p PARAMS ((rtx, struct loop_info *, 
+int precondition_loop_p PARAMS ((const struct loop *,
                               rtx *, rtx *, rtx *, 
                               enum machine_mode *mode));
-rtx final_biv_value PARAMS ((struct iv_class *, rtx, rtx,
-                          unsigned HOST_WIDE_INT));
-rtx final_giv_value PARAMS ((struct induction *, rtx, rtx,
-                          unsigned HOST_WIDE_INT));
+rtx final_biv_value PARAMS ((const struct loop *, struct iv_class *));
+rtx final_giv_value PARAMS ((const struct loop *, struct induction *));
 void emit_unrolled_add PARAMS ((rtx, rtx, rtx));
-int back_branch_in_range_p PARAMS ((rtx, rtx, rtx));
+int back_branch_in_range_p PARAMS ((const struct loop *, rtx));
 
 int loop_insn_first_p PARAMS ((rtx, rtx));
 
index f325cea..7f3658e 100644 (file)
@@ -200,26 +200,27 @@ static rtx initial_reg_note_copy PARAMS ((rtx, struct inline_remap *));
 static void final_reg_note_copy PARAMS ((rtx, struct inline_remap *));
 static void copy_loop_body PARAMS ((rtx, rtx, struct inline_remap *, rtx, int,
                                  enum unroll_types, rtx, rtx, rtx, rtx));
-static void iteration_info PARAMS ((rtx, rtx *, rtx *, rtx, rtx));
-static int find_splittable_regs PARAMS ((enum unroll_types, rtx, rtx, rtx, int,
-                                      unsigned HOST_WIDE_INT));
-static int find_splittable_givs PARAMS ((struct iv_class *, enum unroll_types,
-                                      rtx, rtx, rtx, int));
-static int reg_dead_after_loop PARAMS ((rtx, rtx, rtx));
+static void iteration_info PARAMS ((const struct loop *, rtx, rtx *, rtx *));
+static int find_splittable_regs PARAMS ((const struct loop *,
+                                        enum unroll_types, rtx, int));
+static int find_splittable_givs PARAMS ((const struct loop *, 
+                                        struct iv_class *, enum unroll_types,
+                                        rtx, int));
+static int reg_dead_after_loop PARAMS ((const struct loop *, rtx));
 static rtx fold_rtx_mult_add PARAMS ((rtx, rtx, rtx, enum machine_mode));
 static int verify_addresses PARAMS ((struct induction *, rtx, int));
 static rtx remap_split_bivs PARAMS ((rtx));
 static rtx find_common_reg_term PARAMS ((rtx, rtx));
 static rtx subtract_reg_term PARAMS ((rtx, rtx));
-static rtx loop_find_equiv_value PARAMS ((rtx, rtx));
+static rtx loop_find_equiv_value PARAMS ((const struct loop *, rtx));
 
 /* Try to unroll one loop and split induction variables in the loop.
 
-   The loop is described by the arguments LOOP_END, INSN_COUNT, and
-   LOOP_START.  END_INSERT_BEFORE indicates where insns should be added
-   which need to be executed when the loop falls through.  STRENGTH_REDUCTION_P
-   indicates whether information generated in the strength reduction pass
-   is available.
+   The loop is described by the arguments LOOP and INSN_COUNT.
+   END_INSERT_BEFORE indicates where insns should be added which need
+   to be executed when the loop falls through.  STRENGTH_REDUCTION_P
+   indicates whether information generated in the strength reduction
+   pass is available.
 
    This function is intended to be called from within `strength_reduce'
    in loop.c.  */
@@ -894,7 +895,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
       rtx initial_value, final_value, increment;
       enum machine_mode mode;
 
-      if (precondition_loop_p (loop_start, loop_info,
+      if (precondition_loop_p (loop,
                               &initial_value, &final_value, &increment,
                               &mode))
        {
@@ -1158,9 +1159,8 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
   if (splitting_not_safe)
     temp = 0;
   else
-    temp = find_splittable_regs (unroll_type, loop_start, loop_end,
-                                end_insert_before, unroll_number,
-                                loop_info->n_iterations);
+    temp = find_splittable_regs (loop, unroll_type,
+                                end_insert_before, unroll_number);
 
   /* find_splittable_regs may have created some new registers, so must
      reallocate the reg_map with the new larger size, and must realloc
@@ -1356,13 +1356,13 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
    reflected in RTX_COST.  */
 
 int
-precondition_loop_p (loop_start, loop_info,
-                    initial_value, final_value, increment, mode)
-     rtx loop_start;
-     struct loop_info *loop_info;
+precondition_loop_p (loop, initial_value, final_value, increment, mode)
+     const struct loop *loop;
      rtx *initial_value, *final_value, *increment;
      enum machine_mode *mode;
 {
+  rtx loop_start = loop->start;
+  struct loop_info *loop_info = LOOP_INFO (loop);
 
   if (loop_info->n_iterations > 0)
     {
@@ -1423,16 +1423,16 @@ precondition_loop_p (loop_start, loop_info,
       return 0;
     }
 
-  /* Must ensure that final_value is invariant, so call invariant_p to
-     check.  Before doing so, must check regno against max_reg_before_loop
-     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.  */
+  /* Must ensure that final_value is invariant, so call
+     loop_invariant_p to check.  Before doing so, must check regno
+     against max_reg_before_loop to make sure that the register is in
+     the range covered by loop_invariant_p.  If it isn't, then it is
+     most likely a biv/giv which by definition are not invariant.  */
   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))
+      || ! loop_invariant_p (loop, loop_info->final_value))
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
@@ -2288,21 +2288,23 @@ emit_unrolled_add (dest_reg, src_reg, increment)
     emit_move_insn (dest_reg, result);
 }
 \f
-/* Searches the insns between INSN and LOOP_END.  Returns 1 if there
+/* Searches the insns between INSN and LOOP->END.  Returns 1 if there
    is a backward branch in that range that branches to somewhere between
-   LOOP_START and INSN.  Returns 0 otherwise.  */
+   LOOP->START and INSN.  Returns 0 otherwise.  */
 
 /* ??? This is quadratic algorithm.  Could be rewritten to be linear.
    In practice, this is not a problem, because this function is seldom called,
    and uses a negligible amount of CPU time on average.  */
 
 int
-back_branch_in_range_p (insn, loop_start, loop_end)
+back_branch_in_range_p (loop, insn)
+     const struct loop *loop;
      rtx insn;
-     rtx loop_start, loop_end;
 {
   rtx p, q, target_insn;
-  rtx orig_loop_end = loop_end;
+  rtx loop_start = loop->start;
+  rtx loop_end = loop->end;
+  rtx orig_loop_end = loop->end;
 
   /* Stop before we get to the backward branch at the end of the loop.  */
   loop_end = prev_nonnote_insn (loop_end);
@@ -2392,9 +2394,8 @@ fold_rtx_mult_add (mult1, mult2, add1, mode)
    if it can be calculated.  Otherwise, returns 0.  */
 
 rtx
-biv_total_increment (bl, loop_start, loop_end)
+biv_total_increment (bl)
      struct iv_class *bl;
-     rtx loop_start ATTRIBUTE_UNUSED, loop_end ATTRIBUTE_UNUSED;
 {
   struct induction *v;
   rtx result;
@@ -2427,14 +2428,11 @@ biv_total_increment (bl, loop_start, loop_end)
    be calculated.  */
 
 static void
-iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
+iteration_info (loop, iteration_var, initial_value, increment)
+     const struct loop *loop;
      rtx iteration_var, *initial_value, *increment;
-     rtx loop_start, loop_end;
 {
   struct iv_class *bl;
-#if 0
-  struct induction *v;
-#endif
 
   /* Clear the result values, in case no answer can be found.  */
   *initial_value = 0;
@@ -2484,7 +2482,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
       bl = reg_biv_class[REGNO (iteration_var)];
       *initial_value = bl->initial_value;
 
-      *increment = biv_total_increment (bl, loop_start, loop_end);
+      *increment = biv_total_increment (bl);
     }
   else if (REG_IV_TYPE (REGNO (iteration_var)) == GENERAL_INDUCT)
     {
@@ -2498,7 +2496,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
 
       /* Increment value is mult_val times the increment value of the biv.  */
 
-      *increment = biv_total_increment (bl, loop_start, loop_end);
+      *increment = biv_total_increment (bl);
       if (*increment)
        {
          struct induction *biv_inc;
@@ -2564,13 +2562,11 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
    times, since multiplies by small integers (1,2,3,4) are very cheap.  */
 
 static int
-find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
-                    unroll_number, n_iterations)
+find_splittable_regs (loop, unroll_type, end_insert_before, unroll_number)
+     const struct loop *loop;
      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;
@@ -2578,13 +2574,15 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
   rtx biv_final_value;
   int biv_splittable;
   int result = 0;
+  rtx loop_start = loop->start;
+  rtx loop_end = loop->end;
 
   for (bl = loop_iv_list; bl; bl = bl->next)
     {
       /* Biv_total_increment must return a constant value,
         otherwise we can not calculate the split values.  */
 
-      increment = biv_total_increment (bl, loop_start, loop_end);
+      increment = biv_total_increment (bl);
       if (! increment || GET_CODE (increment) != CONST_INT)
        continue;
 
@@ -2600,16 +2598,14 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
       biv_splittable = 1;
       biv_final_value = 0;
       if (unroll_type != UNROLL_COMPLETELY
-         && (uid_loop[INSN_UID (loop_start)]->exit_count
-             || unroll_type == UNROLL_NAIVE)
+         && (loop->exit_count || unroll_type == UNROLL_NAIVE)
          && (uid_luid[REGNO_LAST_UID (bl->regno)] >= INSN_LUID (loop_end)
              || ! bl->init_insn
              || INSN_UID (bl->init_insn) >= max_uid_for_loop
              || (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,
-                                                  n_iterations)))
+         && ! (biv_final_value = final_biv_value (loop, bl)))
        biv_splittable = 0;
 
       /* If any of the insns setting the BIV don't do so with a simple
@@ -2641,7 +2637,7 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
              if (GET_CODE (bl->initial_value) == REG
                  && (REGNO (bl->initial_value) == bl->regno
                      || REGNO (bl->initial_value) < FIRST_PSEUDO_REGISTER
-                     || ! invariant_p (bl->initial_value)))
+                     || ! loop_invariant_p (loop, bl->initial_value)))
                {
                  rtx tem = gen_reg_rtx (bl->biv->mode);
 
@@ -2677,8 +2673,8 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
         depend on it may be splittable if the biv is live outside the
         loop, and the givs aren't.  */
 
-      result += find_splittable_givs (bl, unroll_type, loop_start, loop_end,
-                                    increment, unroll_number);
+      result += find_splittable_givs (loop, bl, unroll_type, increment, 
+                                     unroll_number);
 
       /* If final value is non-zero, then must emit an instruction which sets
         the value of the biv to the proper value.  This is done after
@@ -2690,7 +2686,7 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
             loop to ensure that it will always be executed no matter
             how the loop exits.  Otherwise emit the insn after the loop,
             since this is slightly more efficient.  */
-         if (! uid_loop[INSN_UID (loop_start)]->exit_count)
+         if (! loop->exit_count)
            emit_insn_before (gen_move_insn (bl->biv->src_reg,
                                             biv_final_value),
                              end_insert_before);
@@ -2758,11 +2754,10 @@ verify_addresses (v, giv_inc, unroll_number)
    Return the number of instructions that set splittable registers.  */
 
 static int
-find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
-                     unroll_number)
+find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
+     const struct loop *loop;
      struct iv_class *bl;
      enum unroll_types unroll_type;
-     rtx loop_start, loop_end;
      rtx increment;
      int unroll_number;
 {
@@ -2796,7 +2791,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
         won't reach here if they aren't.  */
       if (v->giv_type != DEST_ADDR
          && (! v->always_computable
-             || back_branch_in_range_p (v->insn, loop_start, loop_end)))
+             || back_branch_in_range_p (loop, v->insn)))
        continue;
 
       /* The giv increment value must be a constant.  */
@@ -2817,8 +2812,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
 
       final_value = 0;
       if (unroll_type != UNROLL_COMPLETELY
-         && (uid_loop[INSN_UID (loop_start)]->exit_count
-             || unroll_type == UNROLL_NAIVE)
+         && (loop->exit_count || unroll_type == UNROLL_NAIVE)
          && v->giv_type != DEST_ADDR
          /* The next part is true if the pseudo is used outside the loop.
             We assume that this is true for any pseudo created after loop
@@ -2833,7 +2827,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
                          != INSN_UID (XEXP (tem, 0)))))
              /* Line above always fails if INSN was moved by loop opt.  */
              || (uid_luid[REGNO_LAST_UID (REGNO (v->dest_reg))]
-                 >= INSN_LUID (loop_end)))
+                 >= INSN_LUID (loop->end)))
          /* Givs made from biv increments are missed by the above test, so
             test explicitly for them.  */
          && (REGNO (v->dest_reg) < first_increment_giv
@@ -2891,7 +2885,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
 
              record_base_value (REGNO (tem), bl->biv->add_val, 0);
              emit_insn_before (gen_move_insn (tem, bl->biv->src_reg),
-                               loop_start);
+                               loop->start);
              biv_initial_value = tem;
            }
          value = fold_rtx_mult_add (v->mult_val, biv_initial_value,
@@ -2933,7 +2927,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
                  rtx tem = gen_reg_rtx (v->mode);
                  record_base_value (REGNO (tem), v->add_val, 0);
                  emit_iv_add_mult (bl->initial_value, v->mult_val,
-                                   v->add_val, tem, loop_start);
+                                   v->add_val, tem, loop->start);
                  value = tem;
                }
 
@@ -3082,8 +3076,8 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
                     to calculate the value from scratch.  */
                  emit_insn_before (gen_rtx_SET (VOIDmode, tem,
                                                 copy_rtx (v->new_reg)),
-                                   loop_start);
-                 if (recog_memoized (PREV_INSN (loop_start)) < 0)
+                                   loop->start);
+                 if (recog_memoized (PREV_INSN (loop->start)) < 0)
                    {
                      rtx sequence, ret;
 
@@ -3091,7 +3085,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
                         value, because the loop may have been preconditioned.
                         We must calculate it from NEW_REG.  Try using
                         force_operand instead of emit_iv_add_mult.  */
-                     delete_insn (PREV_INSN (loop_start));
+                     delete_insn (PREV_INSN (loop->start));
 
                      start_sequence ();
                      ret = force_operand (v->new_reg, tem);
@@ -3099,7 +3093,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
                        emit_move_insn (tem, ret);
                      sequence = gen_sequence ();
                      end_sequence ();
-                     emit_insn_before (sequence, loop_start);
+                     emit_insn_before (sequence, loop->start);
 
                      if (loop_dump_stream)
                        fprintf (loop_dump_stream,
@@ -3238,14 +3232,14 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
    it can search past if statements and other similar structures.  */
 
 static int
-reg_dead_after_loop (reg, loop_start, loop_end)
-     rtx reg, loop_start, loop_end;
+reg_dead_after_loop (loop, reg)
+     const struct loop *loop;
+     rtx reg;
 {
   rtx insn, label;
   enum rtx_code code;
   int jump_count = 0;
   int label_count = 0;
-  struct loop *loop = uid_loop[INSN_UID (loop_start)];
 
   /* In addition to checking all exits of this loop, we must also check
      all exits of inner nested loops that would exit this loop.  We don't
@@ -3259,9 +3253,9 @@ reg_dead_after_loop (reg, loop_start, loop_end)
     return 0;
 
   /* HACK: Must also search the loop fall through exit, create a label_ref
-     here which points to the loop_end, and append the loop_number_exit_labels
+     here which points to the loop->end, and append the loop_number_exit_labels
      list to it.  */
-  label = gen_rtx_LABEL_REF (VOIDmode, loop_end);
+  label = gen_rtx_LABEL_REF (VOIDmode, loop->end);
   LABEL_NEXTREF (label) = loop->exit_labels;
 
   for ( ; label; label = LABEL_NEXTREF (label))
@@ -3310,11 +3304,12 @@ 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, n_iterations)
+final_biv_value (loop, bl)
+     const struct loop *loop;
      struct iv_class *bl;
-     rtx loop_start, loop_end;
-     unsigned HOST_WIDE_INT n_iterations;
 {
+  rtx loop_end = loop->end;
+  unsigned HOST_WIDE_INT n_iterations = LOOP_INFO (loop)->n_iterations;
   rtx increment, tem;
 
   /* ??? This only works for MODE_INT biv's.  Reject all others for now.  */
@@ -3342,12 +3337,12 @@ final_biv_value (bl, loop_start, loop_end, n_iterations)
      value of the biv must be invariant.  */
 
   if (n_iterations != 0
-      && ! uid_loop[INSN_UID (loop_start)]->exit_count
-      && invariant_p (bl->initial_value))
+      && ! loop->exit_count
+      && loop_invariant_p (loop, bl->initial_value))
     {
-      increment = biv_total_increment (bl, loop_start, loop_end);
+      increment = biv_total_increment (bl);
 
-      if (increment && invariant_p (increment))
+      if (increment && loop_invariant_p (loop, increment))
        {
          /* Can calculate the loop exit value, emit insns after loop
             end to calculate this value into a temporary register in
@@ -3370,7 +3365,7 @@ final_biv_value (bl, loop_start, loop_end, n_iterations)
     }
 
   /* Check to see if the biv is dead at all loop exits.  */
-  if (reg_dead_after_loop (bl->biv->src_reg, loop_start, loop_end))
+  if (reg_dead_after_loop (loop, bl->biv->src_reg))
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
@@ -3387,15 +3382,16 @@ final_biv_value (bl, loop_start, loop_end, n_iterations)
    the end of the loop.  If we can do it, return that value.  */
 
 rtx
-final_giv_value (v, loop_start, loop_end, n_iterations)
+final_giv_value (loop, v)
+     const struct loop *loop;
      struct induction *v;
-     rtx loop_start, loop_end;
-     unsigned HOST_WIDE_INT n_iterations;
 {
   struct iv_class *bl;
   rtx insn;
   rtx increment, tem;
   rtx insert_before, seq;
+  rtx loop_end = loop->end;
+  unsigned HOST_WIDE_INT n_iterations = LOOP_INFO (loop)->n_iterations;
 
   bl = reg_biv_class[REGNO (v->src_reg)];
 
@@ -3422,7 +3418,7 @@ final_giv_value (v, loop_start, loop_end, n_iterations)
      to be known.  */
 
   if (n_iterations != 0
-      && ! uid_loop[INSN_UID (loop_start)]->exit_count)
+      && ! loop->exit_count)
     {
       /* ?? It is tempting to use the biv's value here since these insns will
         be put after the loop, and hence the biv will have its final value
@@ -3435,10 +3431,10 @@ final_giv_value (v, loop_start, loop_end, n_iterations)
         sure that bl->initial_value is still valid then.  It will still
         be valid if it is invariant.  */
 
-      increment = biv_total_increment (bl, loop_start, loop_end);
+      increment = biv_total_increment (bl);
 
-      if (increment && invariant_p (increment)
-         && invariant_p (bl->initial_value))
+      if (increment && loop_invariant_p (loop, increment)
+         && loop_invariant_p (loop, bl->initial_value))
        {
          /* Can calculate the loop exit value of its biv as
             (n_iterations * increment) + initial_value */
@@ -3495,7 +3491,7 @@ final_giv_value (v, loop_start, loop_end, n_iterations)
     abort ();
 
   /* Check to see if the biv is dead at all loop exits.  */
-  if (reg_dead_after_loop (v->dest_reg, loop_start, loop_end))
+  if (reg_dead_after_loop (loop, v->dest_reg))
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
@@ -3509,15 +3505,16 @@ final_giv_value (v, loop_start, loop_end, n_iterations)
 }
 
 
-/* Look back before LOOP_START for then insn that sets REG and return
+/* Look back before LOOP->START for then insn that sets REG and return
    the equivalent constant if there is a REG_EQUAL note otherwise just
    the SET_SRC of REG.  */
 
 static rtx
-loop_find_equiv_value (loop_start, reg)
-     rtx loop_start;
+loop_find_equiv_value (loop, reg)
+     const struct loop *loop;
      rtx reg;
 {
+  rtx loop_start = loop->start;
   rtx insn, set;
   rtx ret;
 
@@ -3678,7 +3675,7 @@ loop_iterations (loop)
      branch, and the insn before tests a register value, make that the
      iteration variable.  */
 
-  comparison = get_condition_for_loop (last_loop_insn);
+  comparison = get_condition_for_loop (loop, last_loop_insn);
   if (comparison == 0)
     {
       if (loop_dump_stream)
@@ -3712,8 +3709,8 @@ loop_iterations (loop)
       && ! REG_USERVAR_P (iteration_var))
     abort ();
 
-  iteration_info (iteration_var, &initial_value, &increment,
-                 loop->start, loop->end);
+  iteration_info (loop, iteration_var, &initial_value, &increment);
+
   if (initial_value == 0)
     /* iteration_info already printed a message.  */
     return 0;
@@ -3758,12 +3755,14 @@ loop_iterations (loop)
      its value from the insns before the start of the loop.  */
 
   final_value = comparison_value;
-  if (GET_CODE (comparison_value) == REG && invariant_p (comparison_value))
+  if (GET_CODE (comparison_value) == REG 
+      && loop_invariant_p (loop, comparison_value))
     {
-      final_value = loop_find_equiv_value (loop->start, comparison_value);
+      final_value = loop_find_equiv_value (loop, comparison_value);
+
       /* If we don't get an invariant final value, we are better
         off with the original register.  */
-      if (!invariant_p (final_value))
+      if (! loop_invariant_p (loop, final_value))
        final_value = comparison_value;
     }
 
@@ -3820,7 +3819,8 @@ loop_iterations (loop)
 
          /* Find what reg1 is equivalent to.  Hopefully it will
             either be reg2 or reg2 plus a constant.  */
-         temp = loop_find_equiv_value (loop->start, reg1);
+         temp = loop_find_equiv_value (loop, reg1);
+
          if (find_common_reg_term (temp, reg2))
            initial_value = temp;
          else
@@ -3828,7 +3828,8 @@ loop_iterations (loop)
              /* Find what reg2 is equivalent to.  Hopefully it will
                 either be reg1 or reg1 plus a constant.  Let's ignore
                 the latter case for now since it is not so common.  */
-             temp = loop_find_equiv_value (loop->start, reg2);
+             temp = loop_find_equiv_value (loop, reg2);
+
              if (temp == loop_info->iteration_var)
                temp = initial_value;
              if (temp == reg1)
@@ -3847,10 +3848,12 @@ loop_iterations (loop)
              where temp2 = init + const.  If the loop has a vtop we
              can replace initial_value with const.  */
 
-         temp = loop_find_equiv_value (loop->start, reg1);
+         temp = loop_find_equiv_value (loop, reg1);
+
          if (GET_CODE (temp) == MINUS && REG_P (XEXP (temp, 0)))
            {
-             rtx temp2 = loop_find_equiv_value (loop->start, XEXP (temp, 0));
+             rtx temp2 = loop_find_equiv_value (loop, XEXP (temp, 0));
+
              if (GET_CODE (temp2) == PLUS
                  && XEXP (temp2, 0) == XEXP (temp, 1))
                initial_value = XEXP (temp2, 1);
@@ -3897,7 +3900,7 @@ loop_iterations (loop)
       /* ??? Other RTL, such as (neg (reg)) is possible here, but it isn't
         clear if it is worthwhile to try to handle such RTL.  */
       if (GET_CODE (increment) == REG || GET_CODE (increment) == SUBREG)
-       increment = loop_find_equiv_value (loop->start, increment);
+       increment = loop_find_equiv_value (loop, increment);
 
       if (GET_CODE (increment) != CONST_INT)
        {