OSDN Git Service

2007-08-05 Andrew Pinski <andrew_pinski@playstation.sony.com>
[pf3gnuchains/gcc-fork.git] / gcc / combine.c
index 5cf65ba..3fe9a16 100644 (file)
@@ -7,7 +7,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -16,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 /* This module is essentially the "combiner" phase of the U. of Arizona
    Portable Optimizer, but redone to work on our list-structured
 
 /* This module is essentially the "combiner" phase of the U. of Arizona
    Portable Optimizer, but redone to work on our list-structured
@@ -143,11 +142,7 @@ static rtx i2mod_old_rhs;
 
 static rtx i2mod_new_rhs;
 \f
 
 static rtx i2mod_new_rhs;
 \f
-/* Maximum register number, which is the size of the tables below.  */
-
-static unsigned int combine_max_regno;
-
-struct reg_stat {
+typedef struct reg_stat_struct {
   /* Record last point of death of (hard or pseudo) register n.  */
   rtx                          last_death;
 
   /* Record last point of death of (hard or pseudo) register n.  */
   rtx                          last_death;
 
@@ -254,9 +249,12 @@ struct reg_stat {
      value.  */
 
   ENUM_BITFIELD(machine_mode)  truncated_to_mode : 8;
      value.  */
 
   ENUM_BITFIELD(machine_mode)  truncated_to_mode : 8;
-};
+} reg_stat_type;
 
 
-static struct reg_stat *reg_stat;
+DEF_VEC_O(reg_stat_type);
+DEF_VEC_ALLOC_O(reg_stat_type,heap);
+
+static VEC(reg_stat_type,heap) *reg_stat;
 
 /* Record the luid of the last insn that invalidated memory
    (anything that writes memory, and subroutine calls, but not pushes).  */
 
 /* Record the luid of the last insn that invalidated memory
    (anything that writes memory, and subroutine calls, but not pushes).  */
@@ -370,18 +368,18 @@ static struct undobuf undobuf;
 
 static int n_occurrences;
 
 
 static int n_occurrences;
 
-static rtx reg_nonzero_bits_for_combine (rtx, enum machine_mode, rtx,
+static rtx reg_nonzero_bits_for_combine (const_rtx, enum machine_mode, const_rtx,
                                         enum machine_mode,
                                         unsigned HOST_WIDE_INT,
                                         unsigned HOST_WIDE_INT *);
                                         enum machine_mode,
                                         unsigned HOST_WIDE_INT,
                                         unsigned HOST_WIDE_INT *);
-static rtx reg_num_sign_bit_copies_for_combine (rtx, enum machine_mode, rtx,
+static rtx reg_num_sign_bit_copies_for_combine (const_rtx, enum machine_mode, const_rtx,
                                                enum machine_mode,
                                                unsigned int, unsigned int *);
 static void do_SUBST (rtx *, rtx);
 static void do_SUBST_INT (int *, int);
 static void init_reg_last (void);
 static void setup_incoming_promotions (rtx);
                                                enum machine_mode,
                                                unsigned int, unsigned int *);
 static void do_SUBST (rtx *, rtx);
 static void do_SUBST_INT (int *, int);
 static void init_reg_last (void);
 static void setup_incoming_promotions (rtx);
-static void set_nonzero_bits_and_sign_copies (rtx, rtx, void *);
+static void set_nonzero_bits_and_sign_copies (rtx, const_rtx, void *);
 static int cant_combine_insn_p (rtx);
 static int can_combine_p (rtx, rtx, rtx, rtx, rtx *, rtx *);
 static int combinable_i3pat (rtx, rtx *, rtx, rtx, int, rtx *);
 static int cant_combine_insn_p (rtx);
 static int can_combine_p (rtx, rtx, rtx, rtx, rtx *, rtx *);
 static int combinable_i3pat (rtx, rtx *, rtx, rtx, int, rtx *);
@@ -396,7 +394,7 @@ static rtx simplify_if_then_else (rtx);
 static rtx simplify_set (rtx);
 static rtx simplify_logical (rtx);
 static rtx expand_compound_operation (rtx);
 static rtx simplify_set (rtx);
 static rtx simplify_logical (rtx);
 static rtx expand_compound_operation (rtx);
-static rtx expand_field_assignment (rtx);
+static const_rtx expand_field_assignment (const_rtx);
 static rtx make_extraction (enum machine_mode, rtx, HOST_WIDE_INT,
                            rtx, unsigned HOST_WIDE_INT, int, int, int);
 static rtx extract_left_shift (rtx, int);
 static rtx make_extraction (enum machine_mode, rtx, HOST_WIDE_INT,
                            rtx, unsigned HOST_WIDE_INT, int, int, int);
 static rtx extract_left_shift (rtx, int);
@@ -427,12 +425,12 @@ static enum rtx_code simplify_comparison (enum rtx_code, rtx *, rtx *);
 static void update_table_tick (rtx);
 static void record_value_for_reg (rtx, rtx, rtx);
 static void check_conversions (rtx, rtx);
 static void update_table_tick (rtx);
 static void record_value_for_reg (rtx, rtx, rtx);
 static void check_conversions (rtx, rtx);
-static void record_dead_and_set_regs_1 (rtx, rtx, void *);
+static void record_dead_and_set_regs_1 (rtx, const_rtx, void *);
 static void record_dead_and_set_regs (rtx);
 static int get_last_value_validate (rtx *, rtx, int, int);
 static void record_dead_and_set_regs (rtx);
 static int get_last_value_validate (rtx *, rtx, int, int);
-static rtx get_last_value (rtx);
-static int use_crosses_set_p (rtx, int);
-static void reg_dead_at_p_1 (rtx, rtx, void *);
+static rtx get_last_value (const_rtx);
+static int use_crosses_set_p (const_rtx, int);
+static void reg_dead_at_p_1 (rtx, const_rtx, void *);
 static int reg_dead_at_p (rtx, rtx);
 static void move_deaths (rtx, rtx, int, rtx, rtx *);
 static int reg_bitfield_target_p (rtx, rtx);
 static int reg_dead_at_p (rtx, rtx);
 static void move_deaths (rtx, rtx, int, rtx, rtx *);
 static int reg_bitfield_target_p (rtx, rtx);
@@ -443,7 +441,7 @@ static void record_promoted_value (rtx, rtx);
 static int unmentioned_reg_p_1 (rtx *, void *);
 static bool unmentioned_reg_p (rtx, rtx);
 static void record_truncated_value (rtx);
 static int unmentioned_reg_p_1 (rtx *, void *);
 static bool unmentioned_reg_p (rtx, rtx);
 static void record_truncated_value (rtx);
-static bool reg_truncated_to_mode (enum machine_mode, rtx);
+static bool reg_truncated_to_mode (enum machine_mode, const_rtx);
 static rtx gen_lowpart_or_truncate (enum machine_mode, rtx);
 \f
 
 static rtx gen_lowpart_or_truncate (enum machine_mode, rtx);
 \f
 
@@ -468,6 +466,25 @@ static rtx gen_lowpart_or_truncate (enum machine_mode, rtx);
 static const struct rtl_hooks combine_rtl_hooks = RTL_HOOKS_INITIALIZER;
 
 \f
 static const struct rtl_hooks combine_rtl_hooks = RTL_HOOKS_INITIALIZER;
 
 \f
+/* Try to split PATTERN found in INSN.  This returns NULL_RTX if
+   PATTERN can not be split.  Otherwise, it returns an insn sequence.
+   This is a wrapper around split_insns which ensures that the
+   reg_stat vector is made larger if the splitter creates a new
+   register.  */
+
+static rtx
+combine_split_insns (rtx pattern, rtx insn)
+{
+  rtx ret;
+  unsigned int nregs;
+
+  ret = split_insns (pattern, insn);
+  nregs = max_reg_num ();
+  if (nregs > VEC_length (reg_stat_type, reg_stat))
+    VEC_safe_grow_cleared (reg_stat_type, heap, reg_stat, nregs);
+  return ret;
+}
+
 /* This is used by find_single_use to locate an rtx in LOC that
    contains exactly one use of DEST, which is typically either a REG
    or CC0.  It returns a pointer to the innermost rtx expression
 /* This is used by find_single_use to locate an rtx in LOC that
    contains exactly one use of DEST, which is typically either a REG
    or CC0.  It returns a pointer to the innermost rtx expression
@@ -1024,11 +1041,9 @@ combine_instructions (rtx f, unsigned int nregs)
   combine_extras = 0;
   combine_successes = 0;
 
   combine_extras = 0;
   combine_successes = 0;
 
-  combine_max_regno = nregs;
-
   rtl_hooks = combine_rtl_hooks;
 
   rtl_hooks = combine_rtl_hooks;
 
-  reg_stat = XCNEWVEC (struct reg_stat, nregs);
+  VEC_safe_grow_cleared (reg_stat_type, heap, reg_stat, nregs);
 
   init_recog_no_volatile ();
 
 
   init_recog_no_volatile ();
 
@@ -1261,7 +1276,7 @@ combine_instructions (rtx f, unsigned int nregs)
   /* Clean up.  */
   free (uid_log_links);
   free (uid_insn_cost);
   /* Clean up.  */
   free (uid_log_links);
   free (uid_insn_cost);
-  free (reg_stat);
+  VEC_free (reg_stat_type, heap, reg_stat);
 
   {
     struct undo *undo, *next;
 
   {
     struct undo *undo, *next;
@@ -1293,8 +1308,10 @@ static void
 init_reg_last (void)
 {
   unsigned int i;
 init_reg_last (void)
 {
   unsigned int i;
-  for (i = 0; i < combine_max_regno; i++)
-    memset (reg_stat + i, 0, offsetof (struct reg_stat, sign_bit_copies));
+  reg_stat_type *p;
+
+  for (i = 0; VEC_iterate (reg_stat_type, reg_stat, i, p); ++i)
+    memset (p, 0, offsetof (reg_stat_type, sign_bit_copies));
 }
 \f
 /* Set up any promoted values for incoming argument registers.  */
 }
 \f
 /* Set up any promoted values for incoming argument registers.  */
@@ -1344,7 +1361,7 @@ setup_incoming_promotions (rtx first)
    by any set of X.  */
 
 static void
    by any set of X.  */
 
 static void
-set_nonzero_bits_and_sign_copies (rtx x, rtx set, void *data)
+set_nonzero_bits_and_sign_copies (rtx x, const_rtx set, void *data)
 {
   rtx insn = (rtx) data;
   unsigned int num;
 {
   rtx insn = (rtx) data;
   unsigned int num;
@@ -1357,10 +1374,12 @@ set_nonzero_bits_and_sign_copies (rtx x, rtx set, void *data)
            (DF_LR_IN (ENTRY_BLOCK_PTR->next_bb), REGNO (x))
       && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
     {
            (DF_LR_IN (ENTRY_BLOCK_PTR->next_bb), REGNO (x))
       && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
     {
+      reg_stat_type *rsp = VEC_index (reg_stat_type, reg_stat, REGNO (x));
+
       if (set == 0 || GET_CODE (set) == CLOBBER)
        {
       if (set == 0 || GET_CODE (set) == CLOBBER)
        {
-         reg_stat[REGNO (x)].nonzero_bits = GET_MODE_MASK (GET_MODE (x));
-         reg_stat[REGNO (x)].sign_bit_copies = 1;
+         rsp->nonzero_bits = GET_MODE_MASK (GET_MODE (x));
+         rsp->sign_bit_copies = 1;
          return;
        }
 
          return;
        }
 
@@ -1391,8 +1410,8 @@ set_nonzero_bits_and_sign_copies (rtx x, rtx set, void *data)
            }
          if (!link)
            {
            }
          if (!link)
            {
-             reg_stat[REGNO (x)].nonzero_bits = GET_MODE_MASK (GET_MODE (x));
-             reg_stat[REGNO (x)].sign_bit_copies = 1;
+             rsp->nonzero_bits = GET_MODE_MASK (GET_MODE (x));
+             rsp->sign_bit_copies = 1;
              return;
            }
        }
              return;
            }
        }
@@ -1434,18 +1453,17 @@ set_nonzero_bits_and_sign_copies (rtx x, rtx set, void *data)
 #endif
 
          /* Don't call nonzero_bits if it cannot change anything.  */
 #endif
 
          /* Don't call nonzero_bits if it cannot change anything.  */
-         if (reg_stat[REGNO (x)].nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
-           reg_stat[REGNO (x)].nonzero_bits
-             |= nonzero_bits (src, nonzero_bits_mode);
+         if (rsp->nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
+           rsp->nonzero_bits |= nonzero_bits (src, nonzero_bits_mode);
          num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
          num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
-         if (reg_stat[REGNO (x)].sign_bit_copies == 0
-             || reg_stat[REGNO (x)].sign_bit_copies > num)
-           reg_stat[REGNO (x)].sign_bit_copies = num;
+         if (rsp->sign_bit_copies == 0
+             || rsp->sign_bit_copies > num)
+           rsp->sign_bit_copies = num;
        }
       else
        {
        }
       else
        {
-         reg_stat[REGNO (x)].nonzero_bits = GET_MODE_MASK (GET_MODE (x));
-         reg_stat[REGNO (x)].sign_bit_copies = 1;
+         rsp->nonzero_bits = GET_MODE_MASK (GET_MODE (x));
+         rsp->sign_bit_copies = 1;
        }
     }
 }
        }
     }
 }
@@ -1465,7 +1483,8 @@ can_combine_p (rtx insn, rtx i3, rtx pred ATTRIBUTE_UNUSED, rtx succ,
               rtx *pdest, rtx *psrc)
 {
   int i;
               rtx *pdest, rtx *psrc)
 {
   int i;
-  rtx set = 0, src, dest;
+  const_rtx set = 0;
+  rtx src, dest;
   rtx p;
 #ifdef AUTO_INC_DEC
   rtx link;
   rtx p;
 #ifdef AUTO_INC_DEC
   rtx link;
@@ -1974,7 +1993,7 @@ struct likely_spilled_retval_info
 /* Called via note_stores by likely_spilled_retval_p.  Remove from info->mask
    hard registers that are known to be written to / clobbered in full.  */
 static void
 /* Called via note_stores by likely_spilled_retval_p.  Remove from info->mask
    hard registers that are known to be written to / clobbered in full.  */
 static void
-likely_spilled_retval_1 (rtx x, rtx set, void *data)
+likely_spilled_retval_1 (rtx x, const_rtx set, void *data)
 {
   struct likely_spilled_retval_info *info = data;
   unsigned regno, nregs;
 {
   struct likely_spilled_retval_info *info = data;
   unsigned regno, nregs;
@@ -2869,13 +2888,13 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
   if (i1 && insn_code_number < 0 && GET_CODE (newpat) == SET
       && asm_noperands (newpat) < 0)
     {
   if (i1 && insn_code_number < 0 && GET_CODE (newpat) == SET
       && asm_noperands (newpat) < 0)
     {
-      rtx m_split, *split;
+      rtx parallel, m_split, *split;
 
       /* See if the MD file can split NEWPAT.  If it can't, see if letting it
         use I2DEST as a scratch register will help.  In the latter case,
         convert I2DEST to the mode of the source of NEWPAT if we can.  */
 
 
       /* See if the MD file can split NEWPAT.  If it can't, see if letting it
         use I2DEST as a scratch register will help.  In the latter case,
         convert I2DEST to the mode of the source of NEWPAT if we can.  */
 
-      m_split = split_insns (newpat, i3);
+      m_split = combine_split_insns (newpat, i3);
 
       /* We can only use I2DEST as a scratch reg if it doesn't overlap any
         inputs of NEWPAT.  */
 
       /* We can only use I2DEST as a scratch reg if it doesn't overlap any
         inputs of NEWPAT.  */
@@ -2890,12 +2909,11 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
 
          /* First try to split using the original register as a
             scratch register.  */
 
          /* First try to split using the original register as a
             scratch register.  */
-         m_split = split_insns (gen_rtx_PARALLEL
-                                (VOIDmode,
-                                 gen_rtvec (2, newpat,
-                                            gen_rtx_CLOBBER (VOIDmode,
-                                                             i2dest))),
-                                i3);
+         parallel = gen_rtx_PARALLEL (VOIDmode,
+                                      gen_rtvec (2, newpat,
+                                                 gen_rtx_CLOBBER (VOIDmode,
+                                                                  i2dest)));
+         m_split = combine_split_insns (parallel, i3);
 
          /* If that didn't work, try changing the mode of I2DEST if
             we can.  */
 
          /* If that didn't work, try changing the mode of I2DEST if
             we can.  */
@@ -2915,12 +2933,12 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
                  ni2dest = regno_reg_rtx[REGNO (i2dest)];
                }
 
                  ni2dest = regno_reg_rtx[REGNO (i2dest)];
                }
 
-             m_split = split_insns (gen_rtx_PARALLEL
-                                    (VOIDmode,
-                                     gen_rtvec (2, newpat,
-                                                gen_rtx_CLOBBER (VOIDmode,
-                                                                 ni2dest))),
-                                    i3);
+             parallel = (gen_rtx_PARALLEL
+                         (VOIDmode,
+                          gen_rtvec (2, newpat,
+                                     gen_rtx_CLOBBER (VOIDmode,
+                                                      ni2dest))));
+             m_split = combine_split_insns (parallel, i3);
 
              if (m_split == 0
                  && REGNO (i2dest) >= FIRST_PSEUDO_REGISTER)
 
              if (m_split == 0
                  && REGNO (i2dest) >= FIRST_PSEUDO_REGISTER)
@@ -2939,9 +2957,10 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
       /* If recog_for_combine has discarded clobbers, try to use them
         again for the split.  */
       if (m_split == 0 && newpat_vec_with_clobbers)
       /* If recog_for_combine has discarded clobbers, try to use them
         again for the split.  */
       if (m_split == 0 && newpat_vec_with_clobbers)
-       m_split
-         = split_insns (gen_rtx_PARALLEL (VOIDmode,
-                                          newpat_vec_with_clobbers), i3);
+       {
+         parallel = gen_rtx_PARALLEL (VOIDmode, newpat_vec_with_clobbers);
+         m_split = combine_split_insns (parallel, i3);
+       }
 
       if (m_split && NEXT_INSN (m_split) == NULL_RTX)
        {
 
       if (m_split && NEXT_INSN (m_split) == NULL_RTX)
        {
@@ -3191,18 +3210,22 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
           && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
           && ! (temp = SET_DEST (XVECEXP (newpat, 0, 1)),
                 (REG_P (temp)
           && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
           && ! (temp = SET_DEST (XVECEXP (newpat, 0, 1)),
                 (REG_P (temp)
-                 && reg_stat[REGNO (temp)].nonzero_bits != 0
+                 && VEC_index (reg_stat_type, reg_stat,
+                               REGNO (temp))->nonzero_bits != 0
                  && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
                  && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
                  && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
                  && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
-                 && (reg_stat[REGNO (temp)].nonzero_bits
+                 && (VEC_index (reg_stat_type, reg_stat,
+                                REGNO (temp))->nonzero_bits
                      != GET_MODE_MASK (word_mode))))
           && ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG
                 && (temp = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))),
                     (REG_P (temp)
                      != GET_MODE_MASK (word_mode))))
           && ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG
                 && (temp = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))),
                     (REG_P (temp)
-                     && reg_stat[REGNO (temp)].nonzero_bits != 0
+                     && VEC_index (reg_stat_type, reg_stat,
+                                   REGNO (temp))->nonzero_bits != 0
                      && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
                      && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
                      && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
                      && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
-                     && (reg_stat[REGNO (temp)].nonzero_bits
+                     && (VEC_index (reg_stat_type, reg_stat,
+                                    REGNO (temp))->nonzero_bits
                          != GET_MODE_MASK (word_mode)))))
           && ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)),
                                         SET_SRC (XVECEXP (newpat, 0, 1)))
                          != GET_MODE_MASK (word_mode)))))
           && ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)),
                                         SET_SRC (XVECEXP (newpat, 0, 1)))
@@ -3849,8 +3872,9 @@ find_split_point (rtx *loc, rtx insn)
          && ! memory_address_p (GET_MODE (x), XEXP (x, 0)))
        {
          rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER];
          && ! memory_address_p (GET_MODE (x), XEXP (x, 0)))
        {
          rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER];
-         rtx seq = split_insns (gen_rtx_SET (VOIDmode, reg, XEXP (x, 0)),
-                                subst_insn);
+         rtx seq = combine_split_insns (gen_rtx_SET (VOIDmode, reg,
+                                                     XEXP (x, 0)),
+                                        subst_insn);
 
          /* This should have produced two insns, each of which sets our
             placeholder.  If the source of the second is a valid address,
 
          /* This should have produced two insns, each of which sets our
             placeholder.  If the source of the second is a valid address,
@@ -6146,8 +6170,8 @@ expand_compound_operation (rtx x)
    We half-heartedly support variable positions, but do not at all
    support variable lengths.  */
 
    We half-heartedly support variable positions, but do not at all
    support variable lengths.  */
 
-static rtx
-expand_field_assignment (rtx x)
+static const_rtx
+expand_field_assignment (const_rtx x)
 {
   rtx inner;
   rtx pos;                     /* Always counts from low bit.  */
 {
   rtx inner;
   rtx pos;                     /* Always counts from low bit.  */
@@ -8599,33 +8623,35 @@ simplify_and_const_int (rtx x, enum machine_mode mode, rtx varop,
    a shift, AND, or zero_extract, we can do better.  */
 
 static rtx
    a shift, AND, or zero_extract, we can do better.  */
 
 static rtx
-reg_nonzero_bits_for_combine (rtx x, enum machine_mode mode,
-                             rtx known_x ATTRIBUTE_UNUSED,
+reg_nonzero_bits_for_combine (const_rtx x, enum machine_mode mode,
+                             const_rtx known_x ATTRIBUTE_UNUSED,
                              enum machine_mode known_mode ATTRIBUTE_UNUSED,
                              unsigned HOST_WIDE_INT known_ret ATTRIBUTE_UNUSED,
                              unsigned HOST_WIDE_INT *nonzero)
 {
   rtx tem;
                              enum machine_mode known_mode ATTRIBUTE_UNUSED,
                              unsigned HOST_WIDE_INT known_ret ATTRIBUTE_UNUSED,
                              unsigned HOST_WIDE_INT *nonzero)
 {
   rtx tem;
+  reg_stat_type *rsp;
 
   /* If X is a register whose nonzero bits value is current, use it.
      Otherwise, if X is a register whose value we can find, use that
      value.  Otherwise, use the previously-computed global nonzero bits
      for this register.  */
 
 
   /* If X is a register whose nonzero bits value is current, use it.
      Otherwise, if X is a register whose value we can find, use that
      value.  Otherwise, use the previously-computed global nonzero bits
      for this register.  */
 
-  if (reg_stat[REGNO (x)].last_set_value != 0
-      && (reg_stat[REGNO (x)].last_set_mode == mode
-         || (GET_MODE_CLASS (reg_stat[REGNO (x)].last_set_mode) == MODE_INT
+  rsp = VEC_index (reg_stat_type, reg_stat, REGNO (x));
+  if (rsp->last_set_value != 0
+      && (rsp->last_set_mode == mode
+         || (GET_MODE_CLASS (rsp->last_set_mode) == MODE_INT
              && GET_MODE_CLASS (mode) == MODE_INT))
              && GET_MODE_CLASS (mode) == MODE_INT))
-      && ((reg_stat[REGNO (x)].last_set_label >= label_tick_ebb_start
-          && reg_stat[REGNO (x)].last_set_label < label_tick)
-         || (reg_stat[REGNO (x)].last_set_label == label_tick
-              && DF_INSN_LUID (reg_stat[REGNO (x)].last_set) < subst_low_luid)
+      && ((rsp->last_set_label >= label_tick_ebb_start
+          && rsp->last_set_label < label_tick)
+         || (rsp->last_set_label == label_tick
+              && DF_INSN_LUID (rsp->last_set) < subst_low_luid)
          || (REGNO (x) >= FIRST_PSEUDO_REGISTER
              && REG_N_SETS (REGNO (x)) == 1
              && !REGNO_REG_SET_P
                  (DF_LR_IN (ENTRY_BLOCK_PTR->next_bb), REGNO (x)))))
     {
          || (REGNO (x) >= FIRST_PSEUDO_REGISTER
              && REG_N_SETS (REGNO (x)) == 1
              && !REGNO_REG_SET_P
                  (DF_LR_IN (ENTRY_BLOCK_PTR->next_bb), REGNO (x)))))
     {
-      *nonzero &= reg_stat[REGNO (x)].last_set_nonzero_bits;
+      *nonzero &= rsp->last_set_nonzero_bits;
       return NULL;
     }
 
       return NULL;
     }
 
@@ -8655,9 +8681,9 @@ reg_nonzero_bits_for_combine (rtx x, enum machine_mode mode,
 #endif
       return tem;
     }
 #endif
       return tem;
     }
-  else if (nonzero_sign_valid && reg_stat[REGNO (x)].nonzero_bits)
+  else if (nonzero_sign_valid && rsp->nonzero_bits)
     {
     {
-      unsigned HOST_WIDE_INT mask = reg_stat[REGNO (x)].nonzero_bits;
+      unsigned HOST_WIDE_INT mask = rsp->nonzero_bits;
 
       if (GET_MODE_BITSIZE (GET_MODE (x)) < GET_MODE_BITSIZE (mode))
        /* We don't know anything about the upper bits.  */
 
       if (GET_MODE_BITSIZE (GET_MODE (x)) < GET_MODE_BITSIZE (mode))
        /* We don't know anything about the upper bits.  */
@@ -8674,27 +8700,29 @@ reg_nonzero_bits_for_combine (rtx x, enum machine_mode mode,
    be between 1 and the number of bits in MODE.  */
 
 static rtx
    be between 1 and the number of bits in MODE.  */
 
 static rtx
-reg_num_sign_bit_copies_for_combine (rtx x, enum machine_mode mode,
-                                    rtx known_x ATTRIBUTE_UNUSED,
+reg_num_sign_bit_copies_for_combine (const_rtx x, enum machine_mode mode,
+                                    const_rtx known_x ATTRIBUTE_UNUSED,
                                     enum machine_mode known_mode
                                     ATTRIBUTE_UNUSED,
                                     unsigned int known_ret ATTRIBUTE_UNUSED,
                                     unsigned int *result)
 {
   rtx tem;
                                     enum machine_mode known_mode
                                     ATTRIBUTE_UNUSED,
                                     unsigned int known_ret ATTRIBUTE_UNUSED,
                                     unsigned int *result)
 {
   rtx tem;
-
-  if (reg_stat[REGNO (x)].last_set_value != 0
-      && reg_stat[REGNO (x)].last_set_mode == mode
-      && ((reg_stat[REGNO (x)].last_set_label >= label_tick_ebb_start
-          && reg_stat[REGNO (x)].last_set_label < label_tick)
-         || (reg_stat[REGNO (x)].last_set_label == label_tick
-              && DF_INSN_LUID (reg_stat[REGNO (x)].last_set) < subst_low_luid)
+  reg_stat_type *rsp;
+
+  rsp = VEC_index (reg_stat_type, reg_stat, REGNO (x));
+  if (rsp->last_set_value != 0
+      && rsp->last_set_mode == mode
+      && ((rsp->last_set_label >= label_tick_ebb_start
+          && rsp->last_set_label < label_tick)
+         || (rsp->last_set_label == label_tick
+              && DF_INSN_LUID (rsp->last_set) < subst_low_luid)
          || (REGNO (x) >= FIRST_PSEUDO_REGISTER
              && REG_N_SETS (REGNO (x)) == 1
              && !REGNO_REG_SET_P
                  (DF_LR_IN (ENTRY_BLOCK_PTR->next_bb), REGNO (x)))))
     {
          || (REGNO (x) >= FIRST_PSEUDO_REGISTER
              && REG_N_SETS (REGNO (x)) == 1
              && !REGNO_REG_SET_P
                  (DF_LR_IN (ENTRY_BLOCK_PTR->next_bb), REGNO (x)))))
     {
-      *result = reg_stat[REGNO (x)].last_set_sign_bit_copies;
+      *result = rsp->last_set_sign_bit_copies;
       return NULL;
     }
 
       return NULL;
     }
 
@@ -8702,9 +8730,9 @@ reg_num_sign_bit_copies_for_combine (rtx x, enum machine_mode mode,
   if (tem != 0)
     return tem;
 
   if (tem != 0)
     return tem;
 
-  if (nonzero_sign_valid && reg_stat[REGNO (x)].sign_bit_copies != 0
+  if (nonzero_sign_valid && rsp->sign_bit_copies != 0
       && GET_MODE_BITSIZE (GET_MODE (x)) == GET_MODE_BITSIZE (mode))
       && GET_MODE_BITSIZE (GET_MODE (x)) == GET_MODE_BITSIZE (mode))
-    *result = reg_stat[REGNO (x)].sign_bit_copies;
+    *result = rsp->sign_bit_copies;
 
   return NULL;
 }
 
   return NULL;
 }
@@ -8721,7 +8749,7 @@ reg_num_sign_bit_copies_for_combine (rtx x, enum machine_mode mode,
    implies that it must be called from a define_split.  */
 
 unsigned int
    implies that it must be called from a define_split.  */
 
 unsigned int
-extended_count (rtx x, enum machine_mode mode, int unsignedp)
+extended_count (const_rtx x, enum machine_mode mode, int unsignedp)
 {
   if (nonzero_sign_valid == 0)
     return 0;
 {
   if (nonzero_sign_valid == 0)
     return 0;
@@ -9665,6 +9693,14 @@ recog_for_combine (rtx *pnewpat, rtx insn, rtx *pnotes)
   REG_NOTES (insn) = 0;
 
   insn_code_number = recog (pat, insn, &num_clobbers_to_add);
   REG_NOTES (insn) = 0;
 
   insn_code_number = recog (pat, insn, &num_clobbers_to_add);
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      if (insn_code_number < 0)
+       fputs ("Failed to match this instruction:\n", dump_file);
+      else
+       fputs ("Successfully matched this instruction:\n", dump_file);
+      print_rtl_single (dump_file, pat);
+    }
 
   /* If it isn't, there is the possibility that we previously had an insn
      that clobbered some register as a side effect, but the combined
 
   /* If it isn't, there is the possibility that we previously had an insn
      that clobbered some register as a side effect, but the combined
@@ -9691,6 +9727,14 @@ recog_for_combine (rtx *pnewpat, rtx insn, rtx *pnotes)
 
       PATTERN (insn) = pat;
       insn_code_number = recog (pat, insn, &num_clobbers_to_add);
 
       PATTERN (insn) = pat;
       insn_code_number = recog (pat, insn, &num_clobbers_to_add);
+      if (dump_file && (dump_flags & TDF_DETAILS))
+       {
+         if (insn_code_number < 0)
+           fputs ("Failed to match this instruction:\n", dump_file);
+         else
+           fputs ("Successfully matched this instruction:\n", dump_file);
+         print_rtl_single (dump_file, pat);
+       }
     }
   PATTERN (insn) = old_pat;
   REG_NOTES (insn) = old_notes;
     }
   PATTERN (insn) = old_pat;
   REG_NOTES (insn) = old_notes;
@@ -11140,7 +11184,10 @@ update_table_tick (rtx x)
       unsigned int r;
 
       for (r = regno; r < endregno; r++)
       unsigned int r;
 
       for (r = regno; r < endregno; r++)
-       reg_stat[r].last_set_table_tick = label_tick;
+       {
+         reg_stat_type *rsp = VEC_index (reg_stat_type, reg_stat, r);
+         rsp->last_set_table_tick = label_tick;
+       }
 
       return;
     }
 
       return;
     }
@@ -11198,6 +11245,7 @@ record_value_for_reg (rtx reg, rtx insn, rtx value)
   unsigned int regno = REGNO (reg);
   unsigned int endregno = END_REGNO (reg);
   unsigned int i;
   unsigned int regno = REGNO (reg);
   unsigned int endregno = END_REGNO (reg);
   unsigned int i;
+  reg_stat_type *rsp;
 
   /* If VALUE contains REG and we have a previous value for REG, substitute
      the previous value.  */
 
   /* If VALUE contains REG and we have a previous value for REG, substitute
      the previous value.  */
@@ -11238,15 +11286,17 @@ record_value_for_reg (rtx reg, rtx insn, rtx value)
      register.  */
   for (i = regno; i < endregno; i++)
     {
      register.  */
   for (i = regno; i < endregno; i++)
     {
+      rsp = VEC_index (reg_stat_type, reg_stat, i);
+
       if (insn)
       if (insn)
-       reg_stat[i].last_set = insn;
+       rsp->last_set = insn;
 
 
-      reg_stat[i].last_set_value = 0;
-      reg_stat[i].last_set_mode = 0;
-      reg_stat[i].last_set_nonzero_bits = 0;
-      reg_stat[i].last_set_sign_bit_copies = 0;
-      reg_stat[i].last_death = 0;
-      reg_stat[i].truncated_to_mode = 0;
+      rsp->last_set_value = 0;
+      rsp->last_set_mode = 0;
+      rsp->last_set_nonzero_bits = 0;
+      rsp->last_set_sign_bit_copies = 0;
+      rsp->last_death = 0;
+      rsp->truncated_to_mode = 0;
     }
 
   /* Mark registers that are being referenced in this value.  */
     }
 
   /* Mark registers that are being referenced in this value.  */
@@ -11262,41 +11312,43 @@ record_value_for_reg (rtx reg, rtx insn, rtx value)
 
   for (i = regno; i < endregno; i++)
     {
 
   for (i = regno; i < endregno; i++)
     {
-      reg_stat[i].last_set_label = label_tick;
+      rsp = VEC_index (reg_stat_type, reg_stat, i);
+      rsp->last_set_label = label_tick;
       if (!insn
       if (!insn
-         || (value && reg_stat[i].last_set_table_tick >= label_tick_ebb_start))
-       reg_stat[i].last_set_invalid = 1;
+         || (value && rsp->last_set_table_tick >= label_tick_ebb_start))
+       rsp->last_set_invalid = 1;
       else
       else
-       reg_stat[i].last_set_invalid = 0;
+       rsp->last_set_invalid = 0;
     }
 
   /* The value being assigned might refer to X (like in "x++;").  In that
      case, we must replace it with (clobber (const_int 0)) to prevent
      infinite loops.  */
     }
 
   /* The value being assigned might refer to X (like in "x++;").  In that
      case, we must replace it with (clobber (const_int 0)) to prevent
      infinite loops.  */
+  rsp = VEC_index (reg_stat_type, reg_stat, regno);
   if (value && ! get_last_value_validate (&value, insn,
   if (value && ! get_last_value_validate (&value, insn,
-                                         reg_stat[regno].last_set_label, 0))
+                                         rsp->last_set_label, 0))
     {
       value = copy_rtx (value);
       if (! get_last_value_validate (&value, insn,
     {
       value = copy_rtx (value);
       if (! get_last_value_validate (&value, insn,
-                                    reg_stat[regno].last_set_label, 1))
+                                    rsp->last_set_label, 1))
        value = 0;
     }
 
   /* For the main register being modified, update the value, the mode, the
      nonzero bits, and the number of sign bit copies.  */
 
        value = 0;
     }
 
   /* For the main register being modified, update the value, the mode, the
      nonzero bits, and the number of sign bit copies.  */
 
-  reg_stat[regno].last_set_value = value;
+  rsp->last_set_value = value;
 
   if (value)
     {
       enum machine_mode mode = GET_MODE (reg);
       subst_low_luid = DF_INSN_LUID (insn);
 
   if (value)
     {
       enum machine_mode mode = GET_MODE (reg);
       subst_low_luid = DF_INSN_LUID (insn);
-      reg_stat[regno].last_set_mode = mode;
+      rsp->last_set_mode = mode;
       if (GET_MODE_CLASS (mode) == MODE_INT
          && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
        mode = nonzero_bits_mode;
       if (GET_MODE_CLASS (mode) == MODE_INT
          && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
        mode = nonzero_bits_mode;
-      reg_stat[regno].last_set_nonzero_bits = nonzero_bits (value, mode);
-      reg_stat[regno].last_set_sign_bit_copies
+      rsp->last_set_nonzero_bits = nonzero_bits (value, mode);
+      rsp->last_set_sign_bit_copies
        = num_sign_bit_copies (value, GET_MODE (reg));
     }
 }
        = num_sign_bit_copies (value, GET_MODE (reg));
     }
 }
@@ -11306,7 +11358,7 @@ record_value_for_reg (rtx reg, rtx insn, rtx value)
    set is occurring.  */
 
 static void
    set is occurring.  */
 
 static void
-record_dead_and_set_regs_1 (rtx dest, rtx setter, void *data)
+record_dead_and_set_regs_1 (rtx dest, const_rtx setter, void *data)
 {
   rtx record_dead_insn = (rtx) data;
 
 {
   rtx record_dead_insn = (rtx) data;
 
@@ -11369,7 +11421,12 @@ record_dead_and_set_regs (rtx insn)
          unsigned int endregno = END_REGNO (XEXP (link, 0));
 
          for (i = regno; i < endregno; i++)
          unsigned int endregno = END_REGNO (XEXP (link, 0));
 
          for (i = regno; i < endregno; i++)
-           reg_stat[i].last_death = insn;
+           {
+             reg_stat_type *rsp;
+
+             rsp = VEC_index (reg_stat_type, reg_stat, i);
+             rsp->last_death = insn;
+           }
        }
       else if (REG_NOTE_KIND (link) == REG_INC)
        record_value_for_reg (XEXP (link, 0), insn, NULL_RTX);
        }
       else if (REG_NOTE_KIND (link) == REG_INC)
        record_value_for_reg (XEXP (link, 0), insn, NULL_RTX);
@@ -11380,14 +11437,17 @@ record_dead_and_set_regs (rtx insn)
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
          {
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
          {
-           reg_stat[i].last_set_invalid = 1;
-           reg_stat[i].last_set = insn;
-           reg_stat[i].last_set_value = 0;
-           reg_stat[i].last_set_mode = 0;
-           reg_stat[i].last_set_nonzero_bits = 0;
-           reg_stat[i].last_set_sign_bit_copies = 0;
-           reg_stat[i].last_death = 0;
-           reg_stat[i].truncated_to_mode = 0;
+           reg_stat_type *rsp;
+
+           rsp = VEC_index (reg_stat_type, reg_stat, i);
+           rsp->last_set_invalid = 1;
+           rsp->last_set = insn;
+           rsp->last_set_value = 0;
+           rsp->last_set_mode = 0;
+           rsp->last_set_nonzero_bits = 0;
+           rsp->last_set_sign_bit_copies = 0;
+           rsp->last_death = 0;
+           rsp->truncated_to_mode = 0;
          }
 
       last_call_luid = mem_last_set = DF_INSN_LUID (insn);
          }
 
       last_call_luid = mem_last_set = DF_INSN_LUID (insn);
@@ -11423,6 +11483,8 @@ record_promoted_value (rtx insn, rtx subreg)
 
   for (links = LOG_LINKS (insn); links;)
     {
 
   for (links = LOG_LINKS (insn); links;)
     {
+      reg_stat_type *rsp;
+
       insn = XEXP (links, 0);
       set = single_set (insn);
 
       insn = XEXP (links, 0);
       set = single_set (insn);
 
@@ -11434,10 +11496,11 @@ record_promoted_value (rtx insn, rtx subreg)
          continue;
        }
 
          continue;
        }
 
-      if (reg_stat[regno].last_set == insn)
+      rsp = VEC_index (reg_stat_type, reg_stat, regno);
+      if (rsp->last_set == insn)
        {
          if (SUBREG_PROMOTED_UNSIGNED_P (subreg) > 0)
        {
          if (SUBREG_PROMOTED_UNSIGNED_P (subreg) > 0)
-           reg_stat[regno].last_set_nonzero_bits &= GET_MODE_MASK (mode);
+           rsp->last_set_nonzero_bits &= GET_MODE_MASK (mode);
        }
 
       if (REG_P (SET_SRC (set)))
        }
 
       if (REG_P (SET_SRC (set)))
@@ -11456,12 +11519,13 @@ record_promoted_value (rtx insn, rtx subreg)
    an explicit truncation.  */
 
 static bool
    an explicit truncation.  */
 
 static bool
-reg_truncated_to_mode (enum machine_mode mode, rtx x)
+reg_truncated_to_mode (enum machine_mode mode, const_rtx x)
 {
 {
-  enum machine_mode truncated = reg_stat[REGNO (x)].truncated_to_mode;
+  reg_stat_type *rsp = VEC_index (reg_stat_type, reg_stat, REGNO (x));
+  enum machine_mode truncated = rsp->truncated_to_mode;
 
   if (truncated == 0
 
   if (truncated == 0
-      || reg_stat[REGNO (x)].truncation_label < label_tick_ebb_start)
+      || rsp->truncation_label < label_tick_ebb_start)
     return false;
   if (GET_MODE_SIZE (truncated) <= GET_MODE_SIZE (mode))
     return true;
     return false;
   if (GET_MODE_SIZE (truncated) <= GET_MODE_SIZE (mode))
     return true;
@@ -11479,6 +11543,7 @@ static void
 record_truncated_value (rtx x)
 {
   enum machine_mode truncated_mode;
 record_truncated_value (rtx x)
 {
   enum machine_mode truncated_mode;
+  reg_stat_type *rsp;
 
   if (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x)))
     {
 
   if (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x)))
     {
@@ -11501,13 +11566,14 @@ record_truncated_value (rtx x)
   else
     return;
 
   else
     return;
 
-  if (reg_stat[REGNO (x)].truncated_to_mode == 0
-      || reg_stat[REGNO (x)].truncation_label < label_tick_ebb_start
+  rsp = VEC_index (reg_stat_type, reg_stat, REGNO (x));
+  if (rsp->truncated_to_mode == 0
+      || rsp->truncation_label < label_tick_ebb_start
       || (GET_MODE_SIZE (truncated_mode)
       || (GET_MODE_SIZE (truncated_mode)
-         < GET_MODE_SIZE (reg_stat[REGNO (x)].truncated_to_mode)))
+         < GET_MODE_SIZE (rsp->truncated_to_mode)))
     {
     {
-      reg_stat[REGNO (x)].truncated_to_mode = truncated_mode;
-      reg_stat[REGNO (x)].truncation_label = label_tick;
+      rsp->truncated_to_mode = truncated_mode;
+      rsp->truncation_label = label_tick;
     }
 }
 
     }
 }
 
@@ -11572,19 +11638,22 @@ get_last_value_validate (rtx *loc, rtx insn, int tick, int replace)
       unsigned int j;
 
       for (j = regno; j < endregno; j++)
       unsigned int j;
 
       for (j = regno; j < endregno; j++)
-       if (reg_stat[j].last_set_invalid
-           /* If this is a pseudo-register that was only set once and not
-              live at the beginning of the function, it is always valid.  */
-           || (! (regno >= FIRST_PSEUDO_REGISTER
-                  && REG_N_SETS (regno) == 1
-                  && !REGNO_REG_SET_P
-                      (DF_LR_IN (ENTRY_BLOCK_PTR->next_bb), regno))
-               && reg_stat[j].last_set_label > tick))
+       {
+         reg_stat_type *rsp = VEC_index (reg_stat_type, reg_stat, j);
+         if (rsp->last_set_invalid
+             /* If this is a pseudo-register that was only set once and not
+                live at the beginning of the function, it is always valid.  */
+             || (! (regno >= FIRST_PSEUDO_REGISTER
+                    && REG_N_SETS (regno) == 1
+                    && (!REGNO_REG_SET_P
+                        (DF_LR_IN (ENTRY_BLOCK_PTR->next_bb), regno)))
+                 && rsp->last_set_label > tick))
          {
            if (replace)
              *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
            return replace;
          }
          {
            if (replace)
              *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
            return replace;
          }
+       }
 
       return 1;
     }
 
       return 1;
     }
@@ -11652,10 +11721,11 @@ get_last_value_validate (rtx *loc, rtx insn, int tick, int replace)
    is known longer known reliably.  */
 
 static rtx
    is known longer known reliably.  */
 
 static rtx
-get_last_value (rtx x)
+get_last_value (const_rtx x)
 {
   unsigned int regno;
   rtx value;
 {
   unsigned int regno;
   rtx value;
+  reg_stat_type *rsp;
 
   /* If this is a non-paradoxical SUBREG, get the value of its operand and
      then convert it to the desired mode.  If this is a paradoxical SUBREG,
 
   /* If this is a non-paradoxical SUBREG, get the value of its operand and
      then convert it to the desired mode.  If this is a paradoxical SUBREG,
@@ -11671,7 +11741,8 @@ get_last_value (rtx x)
     return 0;
 
   regno = REGNO (x);
     return 0;
 
   regno = REGNO (x);
-  value = reg_stat[regno].last_set_value;
+  rsp = VEC_index (reg_stat_type, reg_stat, regno);
+  value = rsp->last_set_value;
 
   /* If we don't have a value, or if it isn't for this basic block and
      it's either a hard register, set more than once, or it's a live
 
   /* If we don't have a value, or if it isn't for this basic block and
      it's either a hard register, set more than once, or it's a live
@@ -11684,7 +11755,7 @@ get_last_value (rtx x)
      block.  */
 
   if (value == 0
      block.  */
 
   if (value == 0
-      || (reg_stat[regno].last_set_label < label_tick_ebb_start
+      || (rsp->last_set_label < label_tick_ebb_start
          && (regno < FIRST_PSEUDO_REGISTER
              || REG_N_SETS (regno) != 1
              || REGNO_REG_SET_P
          && (regno < FIRST_PSEUDO_REGISTER
              || REG_N_SETS (regno) != 1
              || REGNO_REG_SET_P
@@ -11693,21 +11764,21 @@ get_last_value (rtx x)
 
   /* If the value was set in a later insn than the ones we are processing,
      we can't use it even if the register was only set once.  */
 
   /* If the value was set in a later insn than the ones we are processing,
      we can't use it even if the register was only set once.  */
-  if (reg_stat[regno].last_set_label == label_tick
-      && DF_INSN_LUID (reg_stat[regno].last_set) >= subst_low_luid)
+  if (rsp->last_set_label == label_tick
+      && DF_INSN_LUID (rsp->last_set) >= subst_low_luid)
     return 0;
 
   /* If the value has all its registers valid, return it.  */
     return 0;
 
   /* If the value has all its registers valid, return it.  */
-  if (get_last_value_validate (&value, reg_stat[regno].last_set,
-                              reg_stat[regno].last_set_label, 0))
+  if (get_last_value_validate (&value, rsp->last_set,
+                              rsp->last_set_label, 0))
     return value;
 
   /* Otherwise, make a copy and replace any invalid register with
      (clobber (const_int 0)).  If that fails for some reason, return 0.  */
 
   value = copy_rtx (value);
     return value;
 
   /* Otherwise, make a copy and replace any invalid register with
      (clobber (const_int 0)).  If that fails for some reason, return 0.  */
 
   value = copy_rtx (value);
-  if (get_last_value_validate (&value, reg_stat[regno].last_set,
-                              reg_stat[regno].last_set_label, 1))
+  if (get_last_value_validate (&value, rsp->last_set,
+                              rsp->last_set_label, 1))
     return value;
 
   return 0;
     return value;
 
   return 0;
@@ -11717,7 +11788,7 @@ get_last_value (rtx x)
    that is set in an instruction more recent than FROM_LUID.  */
 
 static int
    that is set in an instruction more recent than FROM_LUID.  */
 
 static int
-use_crosses_set_p (rtx x, int from_luid)
+use_crosses_set_p (const_rtx x, int from_luid)
 {
   const char *fmt;
   int i;
 {
   const char *fmt;
   int i;
@@ -11735,10 +11806,13 @@ use_crosses_set_p (rtx x, int from_luid)
        return 1;
 #endif
       for (; regno < endreg; regno++)
        return 1;
 #endif
       for (; regno < endreg; regno++)
-       if (reg_stat[regno].last_set
-           && reg_stat[regno].last_set_label == label_tick
-           && DF_INSN_LUID (reg_stat[regno].last_set) > from_luid)
-         return 1;
+       {
+         reg_stat_type *rsp = VEC_index (reg_stat_type, reg_stat, regno);
+         if (rsp->last_set
+             && rsp->last_set_label == label_tick
+             && DF_INSN_LUID (rsp->last_set) > from_luid)
+           return 1;
+       }
       return 0;
     }
 
       return 0;
     }
 
@@ -11775,7 +11849,7 @@ static int reg_dead_flag;
    reg_dead_flag to 1 if X is a CLOBBER and to -1 it is a SET.  */
 
 static void
    reg_dead_flag to 1 if X is a CLOBBER and to -1 it is a SET.  */
 
 static void
-reg_dead_at_p_1 (rtx dest, rtx x, void *data ATTRIBUTE_UNUSED)
+reg_dead_at_p_1 (rtx dest, const_rtx x, void *data ATTRIBUTE_UNUSED)
 {
   unsigned int regno, endregno;
 
 {
   unsigned int regno, endregno;
 
@@ -11985,7 +12059,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx to_insn,
   if (code == REG)
     {
       unsigned int regno = REGNO (x);
   if (code == REG)
     {
       unsigned int regno = REGNO (x);
-      rtx where_dead = reg_stat[regno].last_death;
+      rtx where_dead = VEC_index (reg_stat_type, reg_stat, regno)->last_death;
 
       /* Don't move the register if it gets killed in between from and to.  */
       if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn)
 
       /* Don't move the register if it gets killed in between from and to.  */
       if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn)
@@ -12621,7 +12695,7 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
          if (place && REG_NOTE_KIND (note) == REG_DEAD)
            {
              unsigned int regno = REGNO (XEXP (note, 0));
          if (place && REG_NOTE_KIND (note) == REG_DEAD)
            {
              unsigned int regno = REGNO (XEXP (note, 0));
-
+             reg_stat_type *rsp = VEC_index (reg_stat_type, reg_stat, regno);
 
              if (dead_or_set_p (place, XEXP (note, 0))
                  || reg_bitfield_target_p (XEXP (note, 0), PATTERN (place)))
 
              if (dead_or_set_p (place, XEXP (note, 0))
                  || reg_bitfield_target_p (XEXP (note, 0), PATTERN (place)))
@@ -12629,12 +12703,12 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
                  /* Unless the register previously died in PLACE, clear
                     last_death.  [I no longer understand why this is
                     being done.] */
                  /* Unless the register previously died in PLACE, clear
                     last_death.  [I no longer understand why this is
                     being done.] */
-                 if (reg_stat[regno].last_death != place)
-                   reg_stat[regno].last_death = 0;
+                 if (rsp->last_death != place)
+                   rsp->last_death = 0;
                  place = 0;
                }
              else
                  place = 0;
                }
              else
-               reg_stat[regno].last_death = place;
+               rsp->last_death = place;
 
              /* If this is a death note for a hard reg that is occupying
                 multiple registers, ensure that we are still using all
 
              /* If this is a death note for a hard reg that is occupying
                 multiple registers, ensure that we are still using all