OSDN Git Service

update copyrights
[pf3gnuchains/gcc-fork.git] / gcc / unroll.c
index 24a39f8..b22d01f 100644 (file)
@@ -1,6 +1,6 @@
 /* Try to unroll loops, and split induction variables.
-   Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998,
-   1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000
+   Free Software Foundation, Inc.
    Contributed by James E. Wilson, Cygnus Support/UC Berkeley.
 
 This file is part of GNU CC.
@@ -140,12 +140,17 @@ Boston, MA 02111-1307, USA.  */
 
 #define NUM_FACTORS 4
 
-struct _factor { int factor, count; } factors[NUM_FACTORS]
-  = { {2, 0}, {3, 0}, {5, 0}, {7, 0}};
+struct _factor { int factor, count; }
+factors[NUM_FACTORS] = { {2, 0}, {3, 0}, {5, 0}, {7, 0}};
 
 /* Describes the different types of loop unrolling performed.  */
 
-enum unroll_types { UNROLL_COMPLETELY, UNROLL_MODULO, UNROLL_NAIVE };
+enum unroll_types
+{
+  UNROLL_COMPLETELY,
+  UNROLL_MODULO,
+  UNROLL_NAIVE
+};
 
 #include "config.h"
 #include "system.h"
@@ -185,10 +190,6 @@ static struct induction **addr_combined_regs;
 static rtx *splittable_regs;
 
 /* Indexed by register number, if this is a splittable induction variable,
-   this indicates if it was made from a derived giv.  */
-static char *derived_regs;
-
-/* Indexed by register number, if this is a splittable induction variable,
    then this will hold the number of instructions in the loop that modify
    the induction variable.  Used to ensure that only the last insn modifying
    a split iv will update the original iv of the dest.  */
@@ -206,7 +207,7 @@ static void copy_loop_body PARAMS ((struct loop *, rtx, rtx,
                                    enum unroll_types, rtx, 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 *, 
+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));
@@ -357,7 +358,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
       rtx ujump = ujump_to_loop_cont (loop->start, loop->cont);
       if (ujump)
        delete_insn (ujump);
-       
+
       /* 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.
         Then return, since no other action is needed here.  */
@@ -443,14 +444,12 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
       if (unroll_number == 1)
        {
          if (loop_dump_stream)
-           fprintf (loop_dump_stream,
-                    "Loop unrolling: No factors found.\n");
+           fprintf (loop_dump_stream, "Loop unrolling: No factors found.\n");
        }
       else
        unroll_type = UNROLL_MODULO;
     }
 
-
   /* Default case, calculate number of times to unroll loop based on its
      size.  */
   if (unroll_type == UNROLL_NAIVE)
@@ -466,9 +465,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
   /* Now we know how many times to unroll the loop.  */
 
   if (loop_dump_stream)
-    fprintf (loop_dump_stream,
-            "Unrolling loop %d times.\n", unroll_number);
-
+    fprintf (loop_dump_stream, "Unrolling loop %d times.\n", unroll_number);
 
   if (unroll_type == UNROLL_COMPLETELY || unroll_type == UNROLL_MODULO)
     {
@@ -767,9 +764,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
              for (i = 0; i < len; i++)
                {
                  label = XEXP (XVECEXP (pat, diff_vec_p, i), 0);
-                 set_label_in_map (map,
-                                   CODE_LABEL_NUMBER (label),
-                                   label);
+                 set_label_in_map (map, CODE_LABEL_NUMBER (label), label);
                }
            }
        }
@@ -807,7 +802,6 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
      to access the splittable_regs[] and addr_combined_regs[] arrays.  */
 
   splittable_regs = (rtx *) xcalloc (maxregnum, sizeof (rtx));
-  derived_regs = (char *) xcalloc (maxregnum, sizeof (char));
   splittable_regs_updates = (int *) xcalloc (maxregnum, sizeof (int));
   addr_combined_regs
     = (struct induction **) xcalloc (maxregnum, sizeof (struct induction *));
@@ -828,7 +822,8 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
       /* If we have a target that uses cc0, then we also must not duplicate
         the insn that sets cc0 before the jump insn, if one is present.  */
 #ifdef HAVE_cc0
-      if (GET_CODE (copy_end) == JUMP_INSN && sets_cc0_p (PREV_INSN (copy_end)))
+      if (GET_CODE (copy_end) == JUMP_INSN
+         && sets_cc0_p (PREV_INSN (copy_end)))
        copy_end_luid--;
 #endif
 
@@ -846,9 +841,9 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
         these pseudo registers have valid regno_first_uid info.  */
       for (r = FIRST_PSEUDO_REGISTER; r < max_reg_before_loop; ++r)
        if (REGNO_FIRST_UID (r) > 0 && REGNO_FIRST_UID (r) <= max_uid_for_loop
-           && uid_luid[REGNO_FIRST_UID (r)] >= copy_start_luid
+           && REGNO_FIRST_LUID (r) >= copy_start_luid
            && REGNO_LAST_UID (r) > 0 && REGNO_LAST_UID (r) <= max_uid_for_loop
-           && uid_luid[REGNO_LAST_UID (r)] <= copy_end_luid)
+           && REGNO_LAST_LUID (r) <= copy_end_luid)
          {
            /* However, we must also check for loop-carried dependencies.
               If the value the pseudo has at the end of iteration X is
@@ -872,14 +867,6 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
                           r);
              }
          }
-      /* Givs that have been created from multiple biv increments always have
-        local registers.  */
-      for (r = ivs->first_increment_giv; r <= ivs->last_increment_giv; r++)
-       {
-         local_regno[r] = 1;
-         if (loop_dump_stream)
-           fprintf (loop_dump_stream, "Marked reg %d as local\n", r);
-       }
     }
 
   /* If this loop requires exit tests when unrolled, check to see if we
@@ -913,7 +900,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
                               &initial_value, &final_value, &increment,
                               &mode))
        {
-         register rtx diff ;
+         register rtx diff;
          rtx *labels;
          int abs_inc, neg_inc;
 
@@ -936,7 +923,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
          abs_inc = INTVAL (increment);
          if (abs_inc < 0)
            {
-             abs_inc = - abs_inc;
+             abs_inc = -abs_inc;
              neg_inc = 1;
            }
 
@@ -1071,8 +1058,8 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
            {
              copy_end = PREV_INSN (last_loop_insn);
 #ifdef HAVE_cc0
-             /* The immediately preceding insn may be a compare which we do not
-                want to copy.  */
+             /* The immediately preceding insn may be a compare which
+                we do not want to copy.  */
              if (sets_cc0_p (PREV_INSN (copy_end)))
                copy_end = PREV_INSN (copy_end);
 #endif
@@ -1085,10 +1072,10 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
              emit_label_after (labels[unroll_number - i],
                                PREV_INSN (loop_start));
 
-             bzero ((char *) map->insn_map, max_insnno * sizeof (rtx));
-             bzero ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0),
-                    (VARRAY_SIZE (map->const_equiv_varray)
-                     * sizeof (struct const_equiv_data)));
+             memset ((char *) map->insn_map, 0, max_insnno * sizeof (rtx));
+             memset ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0),
+                     0, (VARRAY_SIZE (map->const_equiv_varray)
+                         * sizeof (struct const_equiv_data)));
              map->const_age = 0;
 
              for (j = 0; j < max_labelno; j++)
@@ -1132,8 +1119,9 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
            {
              insert_before = last_loop_insn;
 #ifdef HAVE_cc0
-             /* The instruction immediately before the JUMP_INSN may be a compare
-                instruction which we do not want to copy or delete.  */
+             /* The instruction immediately before the JUMP_INSN may
+                be a compare instruction which we do not want to copy
+                or delete.  */
              if (sets_cc0_p (PREV_INSN (insert_before)))
                insert_before = PREV_INSN (insert_before);
 #endif
@@ -1154,7 +1142,8 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
   if (unroll_type == UNROLL_NAIVE && ! flag_unroll_all_loops)
     {
       if (loop_dump_stream)
-       fprintf (loop_dump_stream, "Unrolling failure: Naive unrolling not being done.\n");
+       fprintf (loop_dump_stream,
+                "Unrolling failure: Naive unrolling not being done.\n");
       goto egress;
     }
 
@@ -1195,7 +1184,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
   /* Search the list of bivs and givs to find ones which need to be remapped
      when split, and set their reg_map entry appropriately.  */
 
-  for (bl = ivs->loop_iv_list; bl; bl = bl->next)
+  for (bl = ivs->list; bl; bl = bl->next)
     {
       if (REGNO (bl->biv->src_reg) != bl->regno)
        map->reg_map[bl->regno] = bl->biv->src_reg;
@@ -1208,8 +1197,8 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
     }
 
   /* Use our current register alignment and pointer flags.  */
-  map->regno_pointer_flag = cfun->emit->regno_pointer_flag;
   map->regno_pointer_align = cfun->emit->regno_pointer_align;
+  map->x_regno_reg_rtx = cfun->emit->x_regno_reg_rtx;
 
   /* If the loop is being partially unrolled, and the iteration variables
      are being split, and are being renamed for the split, then must fix up
@@ -1230,9 +1219,9 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
 
   for (i = 0; i < unroll_number; i++)
     {
-      bzero ((char *) map->insn_map, max_insnno * sizeof (rtx));
-      bzero ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0),
-            VARRAY_SIZE (map->const_equiv_varray) * sizeof (struct const_equiv_data));
+      memset ((char *) map->insn_map, 0, max_insnno * sizeof (rtx));
+      memset ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0), 0,
+             VARRAY_SIZE (map->const_equiv_varray) * sizeof (struct const_equiv_data));
       map->const_age = 0;
 
       for (j = 0; j < max_labelno; j++)
@@ -1344,7 +1333,6 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
     }
   free (map->insn_map);
   free (splittable_regs);
-  free (derived_regs);
   free (splittable_regs_updates);
   free (addr_combined_regs);
   free (local_regno);
@@ -1419,7 +1407,7 @@ precondition_loop_p (loop, initial_value, final_value, increment, mode)
       return 0;
     }
   else if ((exact_log2 (INTVAL (loop_info->increment)) < 0)
-          && (exact_log2 (- INTVAL (loop_info->increment)) < 0))
+          && (exact_log2 (-INTVAL (loop_info->increment)) < 0))
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
@@ -1469,7 +1457,7 @@ precondition_loop_p (loop, initial_value, final_value, increment, mode)
   /* 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_info->iteration_var))]
+  if (REGNO_FIRST_LUID (REGNO (loop_info->iteration_var))
       > INSN_LUID (loop_start))
     {
       if (loop_dump_stream)
@@ -1510,7 +1498,6 @@ precondition_loop_p (loop, initial_value, final_value, increment, mode)
   return 1;
 }
 
-
 /* All pseudo-registers must be mapped to themselves.  Two hard registers
    must be mapped, VIRTUAL_STACK_VARS_REGNUM and VIRTUAL_INCOMING_ARGS_
    REGNUM, to avoid function-inlining specific conversions of these
@@ -1739,8 +1726,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
   if (! last_iteration)
     {
       final_label = gen_label_rtx ();
-      set_label_in_map (map, CODE_LABEL_NUMBER (start_label),
-                       final_label);
+      set_label_in_map (map, CODE_LABEL_NUMBER (start_label), final_label);
     }
   else
     set_label_in_map (map, CODE_LABEL_NUMBER (start_label), start_label);
@@ -1784,7 +1770,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
              unsigned int regno = REGNO (SET_DEST (set));
 
              v = addr_combined_regs[REGNO (SET_DEST (set))];
-             bl = ivs->reg_biv_class[REGNO (v->src_reg)];
+             bl = REG_IV_CLASS (ivs, REGNO (v->src_reg));
 
              /* Although the giv_inc amount is not needed here, we must call
                 calculate_giv_inc here since it might try to delete the
@@ -1792,8 +1778,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
                 we might accidentally delete insns generated immediately
                 below by emit_unrolled_add.  */
 
-             if (! derived_regs[regno])
-               giv_inc = calculate_giv_inc (set, insn, regno);
+             giv_inc = calculate_giv_inc (set, insn, regno);
 
              /* Now find all address giv's that were combined with this
                 giv 'v'.  */
@@ -1857,7 +1842,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
                           We must subtract the const_adjust factor added in
                           above.  */
                        tv->dest_reg = plus_constant (dest_reg,
-                                                     - tv->const_adjust);
+                                                     -tv->const_adjust);
                        *tv->location = tv->dest_reg;
                      }
                  }
@@ -1880,23 +1865,12 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
              dest_reg_was_split = 1;
 
              giv_dest_reg = SET_DEST (set);
-             if (derived_regs[regno])
-               {
-                 /* ??? This relies on SET_SRC (SET) to be of
-                    the form (plus (reg) (const_int)), and thus
-                    forces recombine_givs to restrict the kind
-                    of giv derivations it does before unrolling.  */
-                 giv_src_reg = XEXP (SET_SRC (set), 0);
-                 giv_inc = XEXP (SET_SRC (set), 1);
-               }
-             else
-               {
-                 giv_src_reg = giv_dest_reg;
-                 /* Compute the increment value for the giv, if it wasn't
-                    already computed above.  */
-                 if (giv_inc == 0)
-                   giv_inc = calculate_giv_inc (set, insn, regno);
-               }
+             giv_src_reg = giv_dest_reg;
+             /* Compute the increment value for the giv, if it wasn't
+                already computed above.  */
+             if (giv_inc == 0)
+               giv_inc = calculate_giv_inc (set, insn, regno);
+
              src_regno = REGNO (giv_src_reg);
 
              if (unroll_type == UNROLL_COMPLETELY)
@@ -1938,10 +1912,10 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
                     for the biv was stored in the biv's first struct
                     induction entry by find_splittable_regs.  */
 
-                 if (regno < max_reg_before_loop
+                 if (regno < ivs->n_regs
                      && REG_IV_TYPE (ivs, regno) == BASIC_INDUCT)
                    {
-                     giv_src_reg = ivs->reg_biv_class[regno]->biv->src_reg;
+                     giv_src_reg = REG_IV_CLASS (ivs, regno)->biv->src_reg;
                      giv_dest_reg = giv_src_reg;
                    }
 
@@ -2050,10 +2024,12 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
          if (JUMP_LABEL (insn) == start_label && insn == copy_end
              && ! last_iteration)
            {
-             /* Update JUMP_LABEL correctly to make invert_jump working.  */
+             /* Update JUMP_LABEL make invert_jump work correctly.  */
              JUMP_LABEL (copy) = get_label_from_map (map,
                                                      CODE_LABEL_NUMBER
                                                      (JUMP_LABEL (insn)));
+             LABEL_NUSES (JUMP_LABEL (copy))++;
+
              /* This is a branch to the beginning of the loop; this is the
                 last insn being copied; and this is not the last iteration.
                 In this case, we want to change the original fall through
@@ -2073,7 +2049,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
                  emit_label_after (lab, jmp);
                  LABEL_NUSES (lab) = 0;
                  if (!redirect_jump (copy, lab, 0))
-                   abort();
+                   abort ();
                }
            }
 
@@ -2209,7 +2185,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
          /* VTOP and CONT notes are valid only before the loop exit test.
             If placed anywhere else, loop may generate bad code.  */
          /* BASIC_BLOCK notes exist to stabilize basic block structures with
-            the associated rtl.  We do not want to share the structure in 
+            the associated rtl.  We do not want to share the structure in
             this new block.  */
 
          if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED
@@ -2430,7 +2406,6 @@ biv_total_increment (bl)
   return result;
 }
 
-
 /* For each biv and giv, determine whether it can be safely split into
    a different variable for each unrolled copy of the loop body.  If it
    is safe to split, then indicate that by saving some useful info
@@ -2472,7 +2447,7 @@ find_splittable_regs (loop, unroll_type, end_insert_before, unroll_number)
   rtx loop_start = loop->start;
   rtx loop_end = loop->end;
 
-  for (bl = ivs->loop_iv_list; bl; bl = bl->next)
+  for (bl = ivs->list; bl; bl = bl->next)
     {
       /* Biv_total_increment must return a constant value,
         otherwise we can not calculate the split values.  */
@@ -2494,10 +2469,10 @@ find_splittable_regs (loop, unroll_type, end_insert_before, unroll_number)
       biv_final_value = 0;
       if (unroll_type != UNROLL_COMPLETELY
          && (loop->exit_count || unroll_type == UNROLL_NAIVE)
-         && (uid_luid[REGNO_LAST_UID (bl->regno)] >= INSN_LUID (loop_end)
+         && (REGNO_LAST_LUID (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)]
+             || (REGNO_FIRST_LUID (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 (loop, bl)))
@@ -2541,7 +2516,8 @@ find_splittable_regs (loop, unroll_type, end_insert_before, unroll_number)
                                    loop_start);
 
                  if (loop_dump_stream)
-                   fprintf (loop_dump_stream, "Biv %d initial value remapped to %d.\n",
+                   fprintf (loop_dump_stream,
+                            "Biv %d initial value remapped to %d.\n",
                             bl->regno, REGNO (tem));
 
                  splittable_regs[bl->regno] = tem;
@@ -2568,7 +2544,7 @@ find_splittable_regs (loop, unroll_type, end_insert_before, unroll_number)
         depend on it may be splittable if the biv is live outside the
         loop, and the givs aren't.  */
 
-      result += find_splittable_givs (loop, bl, unroll_type, increment, 
+      result += find_splittable_givs (loop, bl, unroll_type, increment,
                                      unroll_number);
 
       /* If final value is non-zero, then must emit an instruction which sets
@@ -2722,12 +2698,8 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
                      || (REGNO_FIRST_UID (REGNO (v->dest_reg))
                          != 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))]
+             || (REGNO_LAST_LUID (REGNO (v->dest_reg))
                  >= INSN_LUID (loop->end)))
-         /* Givs made from biv increments are missed by the above test, so
-            test explicitly for them.  */
-         && (REGNO (v->dest_reg) < ivs->first_increment_giv
-             || REGNO (v->dest_reg) > ivs->last_increment_giv)
          && ! (final_value = v->final_value))
        continue;
 
@@ -2829,7 +2801,6 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
                }
 
              splittable_regs[REGNO (v->new_reg)] = value;
-             derived_regs[REGNO (v->new_reg)] = v->derived_from != 0;
            }
          else
            {
@@ -2889,25 +2860,6 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
                  rtx new_reg = v->new_reg;
                  record_base_value (REGNO (tem), v->add_val, 0);
 
-                 if (same && same->derived_from)
-                   {
-                     /* calculate_giv_inc doesn't work for derived givs.
-                        copy_loop_body works around the problem for the
-                        DEST_REG givs themselves, but it can't handle
-                        DEST_ADDR givs that have been combined with
-                        a derived DEST_REG giv.
-                        So Handle V as if the giv from which V->SAME has
-                        been derived has been combined with V.
-                        recombine_givs only derives givs from givs that
-                        are reduced the ordinary, so we need not worry
-                        about same->derived_from being in turn derived.  */
-
-                     same = same->derived_from;
-                     new_reg = express_from (same, v);
-                     new_reg = replace_rtx (new_reg, same->dest_reg,
-                                            same->new_reg);
-                   }
-
                  /* If the address giv has a constant in its new_reg value,
                     then this constant can be pulled out and put in value,
                     instead of being part of the initialization code.  */
@@ -2927,7 +2879,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
                          /* Save the negative of the eliminated const, so
                             that we can calculate the dest_reg's increment
                             value later.  */
-                         v->const_adjust = - INTVAL (XEXP (new_reg, 1));
+                         v->const_adjust = -INTVAL (XEXP (new_reg, 1));
 
                          new_reg = XEXP (new_reg, 0);
                          if (loop_dump_stream)
@@ -3015,17 +2967,6 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
                                 INSN_UID (v->insn));
                      continue;
                    }
-                 if (v->same && v->same->derived_from)
-                   {
-                     /* Handle V as if the giv from which V->SAME has
-                        been derived has been combined with V.  */
-
-                     v->same = v->same->derived_from;
-                     v->new_reg = express_from (v->same, v);
-                     v->new_reg = replace_rtx (v->new_reg, v->same->dest_reg,
-                                               v->same->new_reg);
-                   }
-
                }
 
              /* Store the value of dest_reg into the insn.  This sharing
@@ -3048,7 +2989,6 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
                     Make sure that it's giv is marked as splittable here.  */
 
                  splittable_regs[REGNO (v->new_reg)] = value;
-                 derived_regs[REGNO (v->new_reg)] = v->derived_from != 0;
 
                  /* Make it appear to depend upon itself, so that the
                     giv will be properly split in the main loop above.  */
@@ -3090,12 +3030,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
        {
          int count = 1;
          if (! v->ignore)
-           count = ivs->reg_biv_class[REGNO (v->src_reg)]->biv_count;
-
-         if (count > 1 && v->derived_from)
-            /* In this case, there is one set where the giv insn was and one
-               set each after each biv increment.  (Most are likely dead.)  */
-           count++;
+           count = REG_IV_CLASS (ivs, REGNO (v->src_reg))->biv_count;
 
          splittable_regs_updates[REGNO (v->new_reg)] = count;
        }
@@ -3155,7 +3090,7 @@ reg_dead_after_loop (loop, reg)
   label = gen_rtx_LABEL_REF (VOIDmode, loop->end);
   LABEL_NEXTREF (label) = loop->exit_labels;
 
-  for ( ; label; label = LABEL_NEXTREF (label))
+  for (; label; label = LABEL_NEXTREF (label))
     {
       /* Succeed if find an insn which sets the biv or if reach end of
         function.  Fail if find an insn that uses the biv, or if come to
@@ -3215,7 +3150,7 @@ final_biv_value (loop, bl)
     return 0;
 
   /* The final value for reversed bivs must be calculated differently than
-      for ordinary bivs.  In this case, there is already an insn after the
+     for ordinary bivs.  In this case, there is already an insn after the
      loop which sets this biv's final value (if necessary), and there are
      no other loop exits, so we can return any value.  */
   if (bl->reversed)
@@ -3291,7 +3226,7 @@ final_giv_value (loop, v)
   rtx loop_end = loop->end;
   unsigned HOST_WIDE_INT n_iterations = LOOP_INFO (loop)->n_iterations;
 
-  bl = ivs->reg_biv_class[REGNO (v->src_reg)];
+  bl = REG_IV_CLASS (ivs, REGNO (v->src_reg));
 
   /* The final value for givs which depend on reversed bivs must be calculated
      differently than for ordinary givs.  In this case, there is already an
@@ -3349,7 +3284,8 @@ final_giv_value (loop, v)
          /* Put the final biv value in tem.  */
          tem = gen_reg_rtx (v->mode);
          record_base_value (REGNO (tem), bl->biv->add_val, 0);
-         emit_iv_add_mult (increment, GEN_INT (n_iterations),
+         emit_iv_add_mult (extend_value_for_giv (v, increment),
+                           GEN_INT (n_iterations),
                            extend_value_for_giv (v, bl->initial_value),
                            tem, insert_before);
 
@@ -3373,8 +3309,7 @@ final_giv_value (loop, v)
            }
 
          /* Now calculate the giv's final value.  */
-         emit_iv_add_mult (tem, v->mult_val, v->add_val, tem,
-                           insert_before);
+         emit_iv_add_mult (tem, v->mult_val, v->add_val, tem, insert_before);
 
          if (loop_dump_stream)
            fprintf (loop_dump_stream,
@@ -3403,7 +3338,6 @@ final_giv_value (loop, v)
   return 0;
 }
 
-
 /* 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.  */
@@ -3418,7 +3352,7 @@ loop_find_equiv_value (loop, reg)
   rtx ret;
 
   ret = reg;
-  for (insn = PREV_INSN (loop_start); insn ; insn = PREV_INSN (insn))
+  for (insn = PREV_INSN (loop_start); insn; insn = PREV_INSN (insn))
     {
       if (GET_CODE (insn) == CODE_LABEL)
        break;
@@ -3429,7 +3363,7 @@ loop_find_equiv_value (loop, reg)
             If it sets the entire register, and has a REG_EQUAL note,
             then use the value of the REG_EQUAL note.  */
          if ((set = single_set (insn))
-                 && (SET_DEST (set) == reg))
+             && (SET_DEST (set) == reg))
            {
              rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
 
@@ -3480,7 +3414,6 @@ subtract_reg_term (op, reg)
   abort ();
 }
 
-
 /* Find and return register term common to both expressions OP0 and
    OP1 or NULL_RTX if no such term exists.  Each expression must be a
    REG or a PLUS of a REG.  */
@@ -3518,7 +3451,6 @@ find_common_reg_term (op0, op1)
   return NULL_RTX;
 }
 
-
 /* Determine the loop iterator and calculate the number of loop
    iterations.  Returns the exact number of loop iterations if it can
    be calculated, otherwise returns zero.  */
@@ -3613,7 +3545,7 @@ loop_iterations (loop)
      will propagate a new pseudo into the old iteration register but
      this will be marked by having the REG_USERVAR_P bit set.  */
 
-  if ((unsigned) REGNO (iteration_var) >= ivs->reg_iv_type->num_elements
+  if ((unsigned) REGNO (iteration_var) >= ivs->n_regs
       && ! REG_USERVAR_P (iteration_var))
     abort ();
 
@@ -3631,7 +3563,7 @@ loop_iterations (loop)
 
   /* If this is a new register, can't handle it since we don't have any
      reg_iv_type entry for it.  */
-  if ((unsigned) REGNO (iteration_var) >= ivs->reg_iv_type->num_elements)
+  if ((unsigned) REGNO (iteration_var) >= ivs->n_regs)
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
@@ -3659,14 +3591,11 @@ loop_iterations (loop)
     }
   else if (REG_IV_TYPE (ivs, REGNO (iteration_var)) == BASIC_INDUCT)
     {
-      /* When reg_iv_type / reg_iv_info is resized for biv increments
-        that are turned into givs, reg_biv_class is not resized.
-        So check here that we don't make an out-of-bounds access.  */
-      if (REGNO (iteration_var) >= max_reg_before_loop)
+      if (REGNO (iteration_var) >= ivs->n_regs)
        abort ();
 
       /* Grab initial value, only useful if it is a constant.  */
-      bl = ivs->reg_biv_class[REGNO (iteration_var)];
+      bl = REG_IV_CLASS (ivs, REGNO (iteration_var));
       initial_value = bl->initial_value;
 
       increment = biv_total_increment (bl);
@@ -3677,10 +3606,10 @@ loop_iterations (loop)
       struct induction *v = REG_IV_INFO (ivs, REGNO (iteration_var));
       rtx biv_initial_value;
 
-      if (REGNO (v->src_reg) >= max_reg_before_loop)
+      if (REGNO (v->src_reg) >= ivs->n_regs)
        abort ();
 
-      bl = ivs->reg_biv_class[REGNO (v->src_reg)];
+      bl = REG_IV_CLASS (ivs, REGNO (v->src_reg));
 
       /* Increment value is mult_val times the increment value of the biv.  */
 
@@ -3689,8 +3618,9 @@ loop_iterations (loop)
        {
          struct induction *biv_inc;
 
-         increment
-           = fold_rtx_mult_add (v->mult_val, increment, const0_rtx, v->mode);
+         increment = fold_rtx_mult_add (v->mult_val,
+                                        extend_value_for_giv (v, increment),
+                                        const0_rtx, v->mode);
          /* The caller assumes that one full increment has occured at the
             first loop test.  But that's not true when the biv is incremented
             after the giv is set (which is the usual case), e.g.:
@@ -3768,7 +3698,7 @@ loop_iterations (loop)
      its value from the insns before the start of the loop.  */
 
   final_value = comparison_value;
-  if (GET_CODE (comparison_value) == REG 
+  if (GET_CODE (comparison_value) == REG
       && loop_invariant_p (loop, comparison_value))
     {
       final_value = loop_find_equiv_value (loop, comparison_value);
@@ -3855,12 +3785,12 @@ loop_iterations (loop)
        {
          rtx temp;
 
-         /*  When running the loop optimizer twice, check_dbra_loop
-             further obfuscates reversible loops of the form:
-             for (i = init; i < init + const; i++).  We often end up with
-             final_value = 0, initial_value = temp, temp = temp2 - init,
-             where temp2 = init + const.  If the loop has a vtop we
-             can replace initial_value with const.  */
+         /* When running the loop optimizer twice, check_dbra_loop
+            further obfuscates reversible loops of the form:
+            for (i = init; i < init + const; i++).  We often end up with
+            final_value = 0, initial_value = temp, temp = temp2 - init,
+            where temp2 = init + const.  If the loop has a vtop we
+            can replace initial_value with const.  */
 
          temp = loop_find_equiv_value (loop, reg1);
 
@@ -3898,7 +3828,7 @@ loop_iterations (loop)
      Check this now so that we won't leave an invalid value if we
      return early for any other reason.  */
   if (comparison_code == EQ)
-      loop_info->final_equiv_value = loop_info->final_value = 0;
+    loop_info->final_equiv_value = loop_info->final_value = 0;
 
   if (increment == 0)
     {
@@ -3944,8 +3874,7 @@ loop_iterations (loop)
   else if (comparison_code == EQ)
     {
       if (loop_dump_stream)
-       fprintf (loop_dump_stream,
-                "Loop iterations: EQ comparison loop.\n");
+       fprintf (loop_dump_stream, "Loop iterations: EQ comparison loop.\n");
       return 0;
     }
   else if (GET_CODE (final_value) != CONST_INT)
@@ -4012,8 +3941,7 @@ loop_iterations (loop)
   else
     {
       if (loop_dump_stream)
-       fprintf (loop_dump_stream,
-                "Loop iterations: Not normal loop.\n");
+       fprintf (loop_dump_stream, "Loop iterations: Not normal loop.\n");
       return 0;
     }
 
@@ -4046,7 +3974,6 @@ loop_iterations (loop)
   return loop_info->n_iterations;
 }
 
-
 /* Replace uses of split bivs with their split pseudo register.  This is
    for original instructions which remain after loop unrolling without
    copying.  */
@@ -4082,9 +4009,9 @@ remap_split_bivs (loop, x)
       /* If non-reduced/final-value givs were split, then this would also
         have to remap those givs also.  */
 #endif
-      if (REGNO (x) < max_reg_before_loop
+      if (REGNO (x) < ivs->n_regs
          && REG_IV_TYPE (ivs, REGNO (x)) == BASIC_INDUCT)
-       return ivs->reg_biv_class[REGNO (x)]->biv->src_reg;
+       return REG_IV_CLASS (ivs, REGNO (x))->biv->src_reg;
       break;
 
     default:
@@ -4135,7 +4062,7 @@ set_dominates_use (regno, first_uid, last_uid, copy_start, copy_end)
   while (INSN_UID (p) != first_uid)
     {
       if (GET_CODE (p) == JUMP_INSN)
-       passed_jump= 1;
+       passed_jump = 1;
       /* Could not find FIRST_UID.  */
       if (p == copy_end)
        return 0;
@@ -4172,10 +4099,11 @@ set_dominates_use (regno, first_uid, last_uid, copy_start, copy_end)
    unconditional branch to the loop continuation note (or a label just after).
    In this case, the unconditional branch that starts the loop needs to be
    deleted so that we execute the single iteration.  */
+
 static rtx
 ujump_to_loop_cont (loop_start, loop_cont)
-      rtx loop_start;
-      rtx loop_cont;
+     rtx loop_start;
+     rtx loop_cont;
 {
   rtx x, label, label_ref;
 
@@ -4196,11 +4124,8 @@ ujump_to_loop_cont (loop_start, loop_cont)
     return NULL_RTX;
 
   /* Return the loop start if the branch label matches the code label.  */
-  if (CODE_LABEL_NUMBER (label) == CODE_LABEL_NUMBER (XEXP (label_ref,0)))
+  if (CODE_LABEL_NUMBER (label) == CODE_LABEL_NUMBER (XEXP (label_ref, 0)))
     return loop_start;
   else
     return NULL_RTX;
-
 }
-
-