loop.c (n_times_set, [...]): Convert to varrays.
authorMark Mitchell <mark@markmitchell.com>
Tue, 25 Aug 1998 23:17:35 +0000 (23:17 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 25 Aug 1998 23:17:35 +0000 (23:17 +0000)
* loop.c (n_times_set, n_times_used, may_not_optimize,
reg_single_usage): Convert to varrays.  All uses changed.
(insert_loop_mem): Return a value.
(scan_loop): Tweak AVOID_CC_MODE_COPIES code.
(load_mems_and_recount_loop_regs_set): Likewise.  Grow the arrays, if
necessary.

From-SVN: r21986

gcc/ChangeLog
gcc/loop.c

index 4311658077a10621b6cc208ccf5d5d6e1bba2d81..681ab6173cd51e6b625dd9b117c67e4d68f512ae 100644 (file)
@@ -1,3 +1,12 @@
+Tue Aug 25 10:57:41 1998  Mark Mitchell  <mark@markmitchell.com>
+
+       * loop.c (n_times_set, n_times_used, may_not_optimize,
+       reg_single_usage): Convert to varrays.  All uses changed.
+       (insert_loop_mem): Return a value.
+       (scan_loop): Tweak AVOID_CC_MODE_COPIES code.
+       (load_mems_and_recount_loop_regs_set): Likewise.  Grow the arrays, if
+       necessary.
+
 Tue Aug 25 23:57:12 1998  Jeffrey A Law  (law@cygnus.com)
 
        * From Alexandre:
index 674b1ccd7d8e93c6d05a89e46f919536134d877c..33f3454ae5bccc286aa40fe1cbb19a32aa20d394 100644 (file)
@@ -168,18 +168,18 @@ static rtx loop_continue;
    Therefore, at all times, == 0 indicates an invariant register;
    < 0 a conditionally invariant one.  */
 
-static int *n_times_set;
+static varray_type n_times_set;
 
 /* Original value of n_times_set; same except that this value
    is not set negative for a reg whose sets have been made candidates
    and not set to 0 for a reg that is moved.  */
 
-static int *n_times_used;
+static varray_type n_times_used;
 
 /* Index by register number, 1 indicates that the register
    cannot be moved or strength reduced.  */
 
-static char *may_not_optimize;
+static varray_type may_not_optimize;
 
 /* Nonzero means reg N has already been moved out of one loop.
    This reduces the desire to move it out of another.  */
@@ -306,7 +306,8 @@ static int reg_in_basic_block_p PROTO((rtx, rtx));
 static int consec_sets_invariant_p PROTO((rtx, int, rtx));
 static rtx libcall_other_reg PROTO((rtx, rtx));
 static int labels_in_range_p PROTO((rtx, int));
-static void count_loop_regs_set PROTO((rtx, rtx, char *, rtx *, int *, int));
+static void count_loop_regs_set PROTO((rtx, rtx, varray_type, varray_type,
+                                      int *, int)); 
 static void note_addr_stored PROTO((rtx, rtx));
 static int loop_reg_used_before_p PROTO((rtx, rtx, rtx, rtx, rtx));
 static void scan_loop PROTO((rtx, rtx, int));
@@ -324,7 +325,7 @@ static void add_label_notes PROTO((rtx, rtx));
 static void move_movables PROTO((struct movable *, int, int, rtx, rtx, int));
 static int count_nonfixed_reads PROTO((rtx));
 static void strength_reduce PROTO((rtx, rtx, rtx, int, rtx, rtx, int));
-static void find_single_use_in_loop PROTO((rtx, rtx, rtx *));
+static void find_single_use_in_loop PROTO((rtx, rtx, varray_type));
 static int valid_initial_value_p PROTO((rtx, rtx, int, rtx));
 static void find_mem_givs PROTO((rtx, rtx, int, rtx, rtx));
 static void record_biv PROTO((struct induction *, rtx, rtx, rtx, rtx, int, int));
@@ -348,7 +349,8 @@ static void record_initial PROTO((rtx, rtx));
 static void update_reg_last_use PROTO((rtx, rtx));
 static rtx next_insn_in_loop PROTO((rtx, rtx, rtx, rtx));
 static void load_mems_and_recount_loop_regs_set PROTO((rtx, rtx, rtx,
-                                                      rtx, rtx *, int *));
+                                                      rtx, varray_type, 
+                                                      int *));
 static void load_mems PROTO((rtx, rtx, rtx, rtx));
 static int insert_loop_mem PROTO((rtx *, void *));
 static int replace_loop_mem PROTO((rtx *, void *));
@@ -678,7 +680,7 @@ scan_loop (loop_start, end, unroll_p)
   /* If we have calls, contains the insn in which a register was used
      if it was used exactly once; contains const0_rtx if it was used more
      than once.  */
-  rtx *reg_single_usage = 0;
+  varray_type reg_single_usage = 0;
   /* Nonzero if we are scanning instructions in a sub-loop.  */
   int loop_depth = 0;
   int nregs;
@@ -757,40 +759,42 @@ scan_loop (loop_start, end, unroll_p)
     }
 
   /* Count number of times each reg is set during this loop.
-     Set may_not_optimize[I] if it is not safe to move out
+     Set VARRAY_CHAR (may_not_optimize, I) if it is not safe to move out
      the setting of register I.  If this loop has calls, set
-     reg_single_usage[I].  */
+     VARRAY_RTX (reg_single_usage, I).  */
   
   /* Allocate extra space for REGS that might be created by
-     load_mems and move_movables.  */
-  nregs = max_reg_num () + loop_mems_idx + 100;
-  n_times_set = (int *) alloca (nregs * sizeof (int));
-  n_times_used = (int *) alloca (nregs * sizeof (int));
-  may_not_optimize = (char *) alloca (nregs);
-  bzero ((char *) n_times_set, nregs * sizeof (int));
-  bzero (may_not_optimize, nregs);
+     load_mems.  We allocate a little extra slop as well, in the hopes
+     that even after the moving of movables creates some new registers
+     we won't have to reallocate these arrays.  However, we do grow
+     the arrays, if necessary, in load_mems_recount_loop_regs_set.  */
+  nregs = max_reg_num () + loop_mems_idx + 16;
+  VARRAY_INT_INIT (n_times_set, nregs, "n_times_set");
+  VARRAY_INT_INIT (n_times_used, nregs, "n_times_used");
+  VARRAY_CHAR_INIT (may_not_optimize, nregs, "may_not_optimize");
 
   if (loop_has_call)
-    {
-      reg_single_usage = (rtx *) alloca (nregs * sizeof (rtx));
-      bzero ((char *) reg_single_usage, nregs * sizeof (rtx));
-    }
+    VARRAY_RTX_INIT (reg_single_usage, nregs, "reg_single_usage");
 
   count_loop_regs_set (loop_top ? loop_top : loop_start, end,
                       may_not_optimize, reg_single_usage, &insn_count, nregs);
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    may_not_optimize[i] = 1, n_times_set[i] = 1;
+    {
+      VARRAY_CHAR (may_not_optimize, i) = 1;
+      VARRAY_INT (n_times_set, i) = 1;
+    }
 
 #ifdef AVOID_CCMODE_COPIES
   /* Don't try to move insns which set CC registers if we should not
      create CCmode register copies.  */
-  for (i = FIRST_PSEUDO_REGISTER; i < nregs - loop_mems_idx; i++)
+  for (i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
     if (GET_MODE_CLASS (GET_MODE (regno_reg_rtx[i])) == MODE_CC)
-      may_not_optimize[i] = 1;
+      VARRAY_CHAR (may_not_optimize, i) = 1;
 #endif
 
-  bcopy ((char *) n_times_set, (char *) n_times_used, nregs * sizeof (int));
+  bcopy ((char *) &n_times_set->data, 
+        (char *) &n_times_used->data, nregs * sizeof (int));
 
   if (loop_dump_stream)
     {
@@ -828,7 +832,7 @@ scan_loop (loop_start, end, unroll_p)
       if (GET_CODE (p) == INSN
          && (set = single_set (p))
          && GET_CODE (SET_DEST (set)) == REG
-         && ! may_not_optimize[REGNO (SET_DEST (set))])
+         && ! VARRAY_CHAR (may_not_optimize, REGNO (SET_DEST (set))))
        {
          int tem1 = 0;
          int tem2 = 0;
@@ -884,11 +888,13 @@ scan_loop (loop_start, end, unroll_p)
          else if ((tem = invariant_p (src))
                   && (dependencies == 0
                       || (tem2 = invariant_p (dependencies)) != 0)
-                  && (n_times_set[REGNO (SET_DEST (set))] == 1
+                  && (VARRAY_INT (n_times_set, 
+                                  REGNO (SET_DEST (set))) == 1
                       || (tem1
-                          = consec_sets_invariant_p (SET_DEST (set),
-                                                     n_times_set[REGNO (SET_DEST (set))],
-                                                     p)))
+                          = consec_sets_invariant_p 
+                          (SET_DEST (set),
+                           VARRAY_INT (n_times_set, REGNO (SET_DEST (set))),
+                           p)))
                   /* If the insn can cause a trap (such as divide by zero),
                      can't move it unless it's guaranteed to be executed
                      once loop is entered.  Even a function call might
@@ -914,12 +920,12 @@ scan_loop (loop_start, end, unroll_p)
                 Don't do this if P has a REG_RETVAL note or if we have
                 SMALL_REGISTER_CLASSES and SET_SRC is a hard register.  */
 
-             if (reg_single_usage && reg_single_usage[regno] != 0
-                 && reg_single_usage[regno] != const0_rtx
+             if (reg_single_usage && VARRAY_RTX (reg_single_usage, regno) != 0
+                 && VARRAY_RTX (reg_single_usage, regno) != const0_rtx
                  && REGNO_FIRST_UID (regno) == INSN_UID (p)
                  && (REGNO_LAST_UID (regno)
-                     == INSN_UID (reg_single_usage[regno]))
-                 && n_times_set[REGNO (SET_DEST (set))] == 1
+                     == INSN_UID (VARRAY_RTX (reg_single_usage, regno)))
+                 && VARRAY_INT (n_times_set, regno) == 1
                  && ! side_effects_p (SET_SRC (set))
                  && ! find_reg_note (p, REG_RETVAL, NULL_RTX)
                  && (! SMALL_REGISTER_CLASSES
@@ -929,22 +935,25 @@ scan_loop (loop_start, end, unroll_p)
                     a call-clobbered register and the life of REGNO
                     might span a call.  */
                  && ! modified_between_p (SET_SRC (set), p,
-                                          reg_single_usage[regno])
-                 && no_labels_between_p (p, reg_single_usage[regno])
+                                          VARRAY_RTX
+                                          (reg_single_usage, regno)) 
+                 && no_labels_between_p (p, VARRAY_RTX (reg_single_usage, regno))
                  && validate_replace_rtx (SET_DEST (set), SET_SRC (set),
-                                          reg_single_usage[regno]))
+                                          VARRAY_RTX
+                                          (reg_single_usage, regno))) 
                {
                  /* Replace any usage in a REG_EQUAL note.  Must copy the
                     new source, so that we don't get rtx sharing between the
                     SET_SOURCE and REG_NOTES of insn p.  */
-                 REG_NOTES (reg_single_usage[regno])
-                   = replace_rtx (REG_NOTES (reg_single_usage[regno]),
+                 REG_NOTES (VARRAY_RTX (reg_single_usage, regno))
+                   = replace_rtx (REG_NOTES (VARRAY_RTX
+                                             (reg_single_usage, regno)), 
                                   SET_DEST (set), copy_rtx (SET_SRC (set)));
                                   
                  PUT_CODE (p, NOTE);
                  NOTE_LINE_NUMBER (p) = NOTE_INSN_DELETED;
                  NOTE_SOURCE_FILE (p) = 0;
-                 n_times_set[regno] = 0;
+                 VARRAY_INT (n_times_set, regno) = 0;
                  continue;
                }
 
@@ -955,7 +964,8 @@ scan_loop (loop_start, end, unroll_p)
              m->dependencies = dependencies;
              m->set_dest = SET_DEST (set);
              m->force = 0;
-             m->consec = n_times_set[REGNO (SET_DEST (set))] - 1;
+             m->consec = VARRAY_INT (n_times_set, 
+                                     REGNO (SET_DEST (set))) - 1;
              m->done = 0;
              m->forces = 0;
              m->partial = 0;
@@ -972,10 +982,10 @@ scan_loop (loop_start, end, unroll_p)
              m->match = 0;
              m->lifetime = (uid_luid[REGNO_LAST_UID (regno)]
                             - uid_luid[REGNO_FIRST_UID (regno)]);
-             m->savings = n_times_used[regno];
+             m->savings = VARRAY_INT (n_times_used, regno);
              if (find_reg_note (p, REG_RETVAL, NULL_RTX))
                m->savings += libcall_benefit (p);
-             n_times_set[regno] = move_insn ? -2 : -1;
+             VARRAY_INT (n_times_set, regno) = move_insn ? -2 : -1;
              /* Add M to the end of the chain MOVABLES.  */
              if (movables == 0)
                movables = m;
@@ -1034,7 +1044,7 @@ scan_loop (loop_start, end, unroll_p)
                   && !reg_mentioned_p (SET_DEST (set), SET_SRC (set1)))
            {
              register int regno = REGNO (SET_DEST (set));
-             if (n_times_set[regno] == 2)
+             if (VARRAY_INT (n_times_set, regno) == 2)
                {
                  register struct movable *m;
                  m = (struct movable *) alloca (sizeof (struct movable));
@@ -1084,7 +1094,7 @@ scan_loop (loop_start, end, unroll_p)
                  m->lifetime = (uid_luid[REGNO_LAST_UID (regno)]
                                 - uid_luid[REGNO_FIRST_UID (regno)]);
                  m->savings = 1;
-                 n_times_set[regno] = -1;
+                 VARRAY_INT (n_times_set, regno) = -1;
                  /* Add M to the end of the chain MOVABLES.  */
                  if (movables == 0)
                    movables = m;
@@ -1161,8 +1171,8 @@ scan_loop (loop_start, end, unroll_p)
   /* Now candidates that still are negative are those not moved.
      Change n_times_set to indicate that those are not actually invariant.  */
   for (i = 0; i < nregs; i++)
-    if (n_times_set[i] < 0)
-      n_times_set[i] = n_times_used[i];
+    if (VARRAY_INT (n_times_set, i) < 0)
+      VARRAY_INT (n_times_set, i) = VARRAY_INT (n_times_used, i);
 
   /* Now that we've moved some things out of the loop, we able to
      hoist even more memory references.  There's no need to pass
@@ -1177,6 +1187,11 @@ scan_loop (loop_start, end, unroll_p)
       strength_reduce (scan_start, end, loop_top,
                       insn_count, loop_start, end, unroll_p);
     }
+
+  VARRAY_FREE (n_times_set);
+  VARRAY_FREE (n_times_used);
+  VARRAY_FREE (may_not_optimize);
+  VARRAY_FREE (reg_single_usage);
 }
 \f
 /* Add elements to *OUTPUT to record all the pseudo-regs
@@ -1450,7 +1465,7 @@ combine_movables (movables, nregs)
   /* Perhaps testing m->consec_sets would be more appropriate here?  */
 
   for (m = movables; m; m = m->next)
-    if (m->match == 0 && n_times_used[m->regno] == 1 && !m->partial)
+    if (m->match == 0 && VARRAY_INT (n_times_used, m->regno) == 1 && !m->partial)
       {
        register struct movable *m1;
        int regno = m->regno;
@@ -1461,7 +1476,7 @@ combine_movables (movables, nregs)
        /* We want later insns to match the first one.  Don't make the first
           one match any later ones.  So start this loop at m->next.  */
        for (m1 = m->next; m1; m1 = m1->next)
-         if (m != m1 && m1->match == 0 && n_times_used[m1->regno] == 1
+         if (m != m1 && m1->match == 0 && VARRAY_INT (n_times_used, m1->regno) == 1
              /* A reg used outside the loop mustn't be eliminated.  */
              && !m1->global
              /* A reg used for zero-extending mustn't be eliminated.  */
@@ -1598,7 +1613,7 @@ rtx_equal_for_loop_p (x, y, movables)
 
   /* If we have a register and a constant, they may sometimes be
      equal.  */
-  if (GET_CODE (x) == REG && n_times_set[REGNO (x)] == -2
+  if (GET_CODE (x) == REG && VARRAY_INT (n_times_set, REGNO (x)) == -2
       && CONSTANT_P (y))
     {
       for (m = movables; m; m = m->next)
@@ -1606,7 +1621,7 @@ rtx_equal_for_loop_p (x, y, movables)
            && rtx_equal_p (m->set_src, y))
          return 1;
     }
-  else if (GET_CODE (y) == REG && n_times_set[REGNO (y)] == -2
+  else if (GET_CODE (y) == REG && VARRAY_INT (n_times_set, REGNO (y)) == -2
           && CONSTANT_P (x))
     {
       for (m = movables; m; m = m->next)
@@ -1837,7 +1852,7 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
              || flag_move_all_movables
              || (threshold * savings * m->lifetime) >= insn_count
              || (m->forces && m->forces->done
-                 && n_times_used[m->forces->regno] == 1))
+                 && VARRAY_INT (n_times_used, m->forces->regno) == 1))
            {
              int count;
              register struct movable *m1;
@@ -2128,7 +2143,7 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
 
              /* The reg set here is now invariant.  */
              if (! m->partial)
-               n_times_set[regno] = 0;
+               VARRAY_INT (n_times_set, regno) = 0;
 
              m->done = 1;
 
@@ -2185,7 +2200,7 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
                      /* The reg merged here is now invariant,
                         if the reg it matches is invariant.  */
                      if (! m->partial)
-                       n_times_set[m1->regno] = 0;
+                       VARRAY_INT (n_times_set, m1->regno) = 0;
                    }
            }
          else if (loop_dump_stream)
@@ -3087,10 +3102,10 @@ invariant_p (x)
          && REGNO (x) < FIRST_PSEUDO_REGISTER && call_used_regs[REGNO (x)])
        return 0;
 
-      if (n_times_set[REGNO (x)] < 0)
+      if (VARRAY_INT (n_times_set, REGNO (x)) < 0)
        return 2;
 
-      return n_times_set[REGNO (x)] == 0;
+      return VARRAY_INT (n_times_set, REGNO (x)) == 0;
 
     case MEM:
       /* Volatile memory references must be rejected.  Do this before
@@ -3178,7 +3193,7 @@ consec_sets_invariant_p (reg, n_sets, insn)
   rtx temp;
   /* Number of sets we have to insist on finding after INSN.  */
   int count = n_sets - 1;
-  int old = n_times_set[regno];
+  int old = VARRAY_INT (n_times_set, regno);
   int value = 0;
   int this;
 
@@ -3186,7 +3201,7 @@ consec_sets_invariant_p (reg, n_sets, insn)
   if (n_sets == 127)
     return 0;
 
-  n_times_set[regno] = 0;
+  VARRAY_INT (n_times_set, regno) = 0;
 
   while (count > 0)
     {
@@ -3225,12 +3240,12 @@ consec_sets_invariant_p (reg, n_sets, insn)
        count--;
       else if (code != NOTE)
        {
-         n_times_set[regno] = old;
+         VARRAY_INT (n_times_set, regno) = old;
          return 0;
        }
     }
 
-  n_times_set[regno] = old;
+  VARRAY_INT (n_times_set, regno) = old;
   /* If invariant_p ever returned 2, we return 2.  */
   return 1 + (value & 2);
 }
@@ -3276,15 +3291,16 @@ static void
 find_single_use_in_loop (insn, x, usage)
      rtx insn;
      rtx x;
-     rtx *usage;
+     varray_type usage;
 {
   enum rtx_code code = GET_CODE (x);
   char *fmt = GET_RTX_FORMAT (code);
   int i, j;
 
   if (code == REG)
-    usage[REGNO (x)]
-      = (usage[REGNO (x)] != 0 && usage[REGNO (x)] != insn)
+    VARRAY_RTX (usage, REGNO (x))
+      = (VARRAY_RTX (usage, REGNO (x)) != 0 
+        && VARRAY_RTX (usage, REGNO (x)) != insn)
        ? const0_rtx : insn;
 
   else if (code == SET)
@@ -3327,8 +3343,8 @@ find_single_use_in_loop (insn, x, usage)
 static void
 count_loop_regs_set (from, to, may_not_move, single_usage, count_ptr, nregs)
      register rtx from, to;
-     char *may_not_move;
-     rtx *single_usage;
+     varray_type may_not_move;
+     varray_type single_usage;
      int *count_ptr;
      int nregs;
 {
@@ -3358,7 +3374,7 @@ count_loop_regs_set (from, to, may_not_move, single_usage, count_ptr, nregs)
              && GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
            /* Don't move a reg that has an explicit clobber.
               We might do so sometimes, but it's not worth the pain.  */
-           may_not_move[REGNO (XEXP (PATTERN (insn), 0))] = 1;
+           VARRAY_CHAR (may_not_move, REGNO (XEXP (PATTERN (insn), 0))) = 1;
 
          if (GET_CODE (PATTERN (insn)) == SET
              || GET_CODE (PATTERN (insn)) == CLOBBER)
@@ -3376,16 +3392,17 @@ count_loop_regs_set (from, to, may_not_move, single_usage, count_ptr, nregs)
                     in current basic block, and it was set before,
                     it must be set in two basic blocks, so it cannot
                     be moved out of the loop.  */
-                 if (n_times_set[regno] > 0 && last_set[regno] == 0)
-                   may_not_move[regno] = 1;
+                 if (VARRAY_INT (n_times_set, regno) > 0
+                     && last_set[regno] == 0)
+                   VARRAY_CHAR (may_not_move, regno) = 1;
                  /* If this is not first setting in current basic block,
                     see if reg was used in between previous one and this.
                     If so, neither one can be moved.  */
                  if (last_set[regno] != 0
                      && reg_used_between_p (dest, last_set[regno], insn))
-                   may_not_move[regno] = 1;
-                 if (n_times_set[regno] < 127)
-                   ++n_times_set[regno];
+                   VARRAY_CHAR (may_not_move, regno) = 1;
+                 if (VARRAY_INT (n_times_set, regno) < 127)
+                   ++VARRAY_INT (n_times_set, regno);
                  last_set[regno] = insn;
                }
            }
@@ -3398,7 +3415,7 @@ count_loop_regs_set (from, to, may_not_move, single_usage, count_ptr, nregs)
                  if (GET_CODE (x) == CLOBBER && GET_CODE (XEXP (x, 0)) == REG)
                    /* Don't move a reg that has an explicit clobber.
                       It's not worth the pain to try to do it correctly.  */
-                   may_not_move[REGNO (XEXP (x, 0))] = 1;
+                   VARRAY_CHAR (may_not_move, REGNO (XEXP (x, 0))) = 1;
 
                  if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
                    {
@@ -3411,13 +3428,14 @@ count_loop_regs_set (from, to, may_not_move, single_usage, count_ptr, nregs)
                      if (GET_CODE (dest) == REG)
                        {
                          register int regno = REGNO (dest);
-                         if (n_times_set[regno] > 0 && last_set[regno] == 0)
-                           may_not_move[regno] = 1;
+                         if (VARRAY_INT (n_times_set, regno) > 0 
+                             && last_set[regno] == 0)
+                           VARRAY_CHAR (may_not_move, regno) = 1;
                          if (last_set[regno] != 0
                              && reg_used_between_p (dest, last_set[regno], insn))
-                           may_not_move[regno] = 1;
-                         if (n_times_set[regno] < 127)
-                           ++n_times_set[regno];
+                           VARRAY_CHAR (may_not_move, regno) = 1;
+                         if (VARRAY_INT (n_times_set, regno) < 127)
+                           ++VARRAY_INT (n_times_set, regno);
                          last_set[regno] = insn;
                        }
                    }
@@ -3745,7 +3763,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
       if (reg_iv_type[bl->regno] != BASIC_INDUCT
          /* Above happens if register modified by subreg, etc.  */
          /* Make sure it is not recognized as a basic induction var: */
-         || n_times_set[bl->regno] != bl->biv_count
+         || VARRAY_INT (n_times_set, bl->regno) != bl->biv_count
          /* If never incremented, it is invariant that we decided not to
             move.  So leave it alone.  */
          || ! bl->incremented)
@@ -3906,7 +3924,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
       if (GET_CODE (p) == INSN
          && (set = single_set (p))
          && GET_CODE (SET_DEST (set)) == REG
-         && ! may_not_optimize[REGNO (SET_DEST (set))])
+         && ! VARRAY_CHAR (may_not_optimize, REGNO (SET_DEST (set))))
        {
          rtx src_reg;
          rtx add_val;
@@ -3932,7 +3950,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
              /* Don't recognize a BASIC_INDUCT_VAR here.  */
              && dest_reg != src_reg
              /* This must be the only place where the register is set.  */
-             && (n_times_set[REGNO (dest_reg)] == 1
+             && (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,
                                                 src_reg, dest_reg,
@@ -3948,7 +3966,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
                benefit += libcall_benefit (p);
 
              /* Skip the consecutive insns, if there are any.  */
-             for (count = n_times_set[REGNO (dest_reg)] - 1;
+             for (count = VARRAY_INT (n_times_set, REGNO (dest_reg)) - 1;
                   count > 0; count--)
                {
                  /* If first insn of libcall sequence, skip to end.
@@ -4890,7 +4908,7 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
       v->lifetime = (uid_luid[REGNO_LAST_UID (REGNO (dest_reg))]
                     - uid_luid[REGNO_FIRST_UID (REGNO (dest_reg))]);
 
-      v->times_used = n_times_used[REGNO (dest_reg)];
+      v->times_used = VARRAY_INT (n_times_used, REGNO (dest_reg));
 
       /* If the lifetime is zero, it means that this register is
         really a dead store.  So mark this as a giv that can be
@@ -6050,7 +6068,7 @@ consec_sets_giv (first_benefit, p, src_reg, dest_reg,
   reg_iv_type[REGNO (dest_reg)] = GENERAL_INDUCT;
   reg_iv_info[REGNO (dest_reg)] = v;
 
-  count = n_times_set[REGNO (dest_reg)] - 1;
+  count = VARRAY_INT (n_times_set, REGNO (dest_reg)) - 1;
 
   while (count > 0)
     {
@@ -6322,12 +6340,12 @@ combine_givs_used_once (g1, g2)
      struct induction *g1, *g2;
 {
   if (g1->giv_type == DEST_REG
-      && n_times_used[REGNO (g1->dest_reg)] == 1
+      && VARRAY_INT (n_times_used, REGNO (g1->dest_reg)) == 1
       && reg_mentioned_p (g1->dest_reg, PATTERN (g2->insn)))
     return -1;
 
   if (g2->giv_type == DEST_REG
-      && n_times_used[REGNO (g2->dest_reg)] == 1
+      && VARRAY_INT (n_times_used, REGNO (g2->dest_reg)) == 1
       && reg_mentioned_p (g2->dest_reg, PATTERN (g1->insn)))
     return 1;
 
@@ -8398,6 +8416,8 @@ insert_loop_mem (mem, data)
   loop_mems[loop_mems_idx].optimize = (GET_MODE (m) != BLKmode);
   loop_mems[loop_mems_idx].reg = NULL_RTX;
   ++loop_mems_idx;
+
+  return 0;
 }
 
 /* Like load_mems, but also ensures that N_TIMES_SET,
@@ -8411,7 +8431,7 @@ load_mems_and_recount_loop_regs_set (scan_start, end, loop_top, start,
      rtx end;
      rtx loop_top;
      rtx start;
-     rtx *reg_single_usage;
+     varray_type reg_single_usage;
      int *insn_count;
 {
   int nregs = max_reg_num ();
@@ -8428,32 +8448,42 @@ load_mems_and_recount_loop_regs_set (scan_start, end, loop_top, start,
       old_nregs = nregs;
       nregs = max_reg_num ();
 
-      /* Note that we assume here that enough room was allocated in
-        the various arrays to accomodate the extra registers created
-        by load_mems.  */
-      bzero ((char *) n_times_set, nregs * sizeof (int));
-      bzero (may_not_optimize, nregs);
-      if (loop_has_call && reg_single_usage)
-       bzero ((char *) reg_single_usage, nregs * sizeof (rtx));
+      if (nregs > n_times_set->num_elements)
+       {
+         /* Grow all the arrays.  */
+         VARRAY_GROW (n_times_set, nregs);
+         VARRAY_GROW (n_times_used, nregs);
+         VARRAY_GROW (may_not_optimize, nregs);
+         if (reg_single_usage)
+           VARRAY_GROW (reg_single_usage, nregs);
+       }
+      /* Clear the arrays */
+      bzero ((char *) &n_times_set->data, nregs * sizeof (int));
+      bzero ((char *) &may_not_optimize->data, nregs * sizeof (char));
+      if (reg_single_usage)
+       bzero ((char *) &reg_single_usage->data, nregs * sizeof (rtx));
 
       count_loop_regs_set (loop_top ? loop_top : start, end,
                           may_not_optimize, reg_single_usage,
                           insn_count, nregs); 
 
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-       may_not_optimize[i] = 1, n_times_set[i] = 1;
+       {
+         VARRAY_CHAR (may_not_optimize, i) = 1;
+         VARRAY_INT (n_times_set, i) = 1;
+       }
       
 #ifdef AVOID_CCMODE_COPIES
       /* Don't try to move insns which set CC registers if we should not
         create CCmode register copies.  */
-      for (i = FIRST_PSEUDO_REGISTER; i < nregs - loop_mems_idx; i++)
+      for (i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
        if (GET_MODE_CLASS (GET_MODE (regno_reg_rtx[i])) == MODE_CC)
-         may_not_optimize[i] = 1;
+         VARRAY_CHAR (may_not_optimize, i) = 1;
 #endif
 
       /* Set n_times_used for the new registers.  */
-      bcopy ((char *) (n_times_set + old_nregs),
-            (char *) (n_times_used + old_nregs),
+      bcopy ((char *) (&n_times_set->data.i[0] + old_nregs),
+            (char *) (&n_times_used->data.i[0] + old_nregs),
             (nregs - old_nregs) * sizeof (int));
     }
 }