OSDN Git Service

Word wrap comment
[pf3gnuchains/gcc-fork.git] / gcc / local-alloc.c
index ddcd475..e277f80 100644 (file)
@@ -1,5 +1,6 @@
 /* Allocate registers within a basic block, for GNU compiler.
-   Copyright (C) 1987, 88, 91, 93-97, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -62,9 +63,11 @@ Boston, MA 02111-1307, USA.  */
 #include "config.h"
 #include "system.h"
 #include "rtl.h"
+#include "tm_p.h"
 #include "flags.h"
 #include "basic-block.h"
 #include "regs.h"
+#include "function.h"
 #include "hard-reg-set.h"
 #include "insn-config.h"
 #include "insn-attr.h"
@@ -76,100 +79,108 @@ Boston, MA 02111-1307, USA.  */
 
 static int next_qty;
 
-/* In all the following vectors indexed by quantity number.  */
+/* Information we maitain about each quantity.  */
+struct qty
+{
+  /* The number of refs to quantity Q.  */
 
-/* Element Q is the hard reg number chosen for quantity Q,
-   or -1 if none was found.  */
+  int n_refs;
 
-static short *qty_phys_reg;
+  /* Insn number (counting from head of basic block)
+     where quantity Q was born.  -1 if birth has not been recorded.  */
 
-/* We maintain two hard register sets that indicate suggested hard registers
-   for each quantity.  The first, qty_phys_copy_sugg, contains hard registers
-   that are tied to the quantity by a simple copy.  The second contains all
-   hard registers that are tied to the quantity via an arithmetic operation.
+  int birth;
 
-   The former register set is given priority for allocation.  This tends to
-   eliminate copy insns.  */
+  /* Insn number (counting from head of basic block)
+     where given quantity died.  Due to the way tying is done,
+     and the fact that we consider in this pass only regs that die but once,
+     a quantity can die only once.  Each quantity's life span
+     is a set of consecutive insns.  -1 if death has not been recorded.  */
 
-/* Element Q is a set of hard registers that are suggested for quantity Q by
-   copy insns.  */
+  int death;
 
-static HARD_REG_SET *qty_phys_copy_sugg;
+  /* Number of words needed to hold the data in given quantity.
+     This depends on its machine mode.  It is used for these purposes:
+     1. It is used in computing the relative importances of qtys,
+       which determines the order in which we look for regs for them.
+     2. It is used in rules that prevent tying several registers of
+       different sizes in a way that is geometrically impossible
+       (see combine_regs).  */
 
-/* Element Q is a set of hard registers that are suggested for quantity Q by
-   arithmetic insns.  */
+  int size;
 
-static HARD_REG_SET *qty_phys_sugg;
+  /* Number of times a reg tied to given qty lives across a CALL_INSN.  */
 
-/* Element Q is the number of suggested registers in qty_phys_copy_sugg.  */
+  int n_calls_crossed;
 
-static short *qty_phys_num_copy_sugg;
+  /* The register number of one pseudo register whose reg_qty value is Q.
+     This register should be the head of the chain
+     maintained in reg_next_in_qty.  */
 
-/* Element Q is the number of suggested registers in qty_phys_sugg.  */
+  int first_reg;
 
-static short *qty_phys_num_sugg;
+  /* Reg class contained in (smaller than) the preferred classes of all
+     the pseudo regs that are tied in given quantity.
+     This is the preferred class for allocating that quantity.  */
 
-/* Element Q is the number of refs to quantity Q.  */
+  enum reg_class min_class;
 
-static int *qty_n_refs;
+  /* Register class within which we allocate given qty if we can't get
+     its preferred class.  */
 
-/* Element Q is a reg class contained in (smaller than) the
-   preferred classes of all the pseudo regs that are tied in quantity Q.
-   This is the preferred class for allocating that quantity.  */
+  enum reg_class alternate_class;
 
-static enum reg_class *qty_min_class;
+  /* This holds the mode of the registers that are tied to given qty,
+     or VOIDmode if registers with differing modes are tied together.  */
 
-/* Insn number (counting from head of basic block)
-   where quantity Q was born.  -1 if birth has not been recorded.  */
+  enum machine_mode mode;
 
-static int *qty_birth;
+  /* the hard reg number chosen for given quantity,
+     or -1 if none was found.  */
 
-/* Insn number (counting from head of basic block)
-   where quantity Q died.  Due to the way tying is done,
-   and the fact that we consider in this pass only regs that die but once,
-   a quantity can die only once.  Each quantity's life span
-   is a set of consecutive insns.  -1 if death has not been recorded.  */
+  short phys_reg;
 
-static int *qty_death;
+  /* Nonzero if this quantity has been used in a SUBREG that changes
+     its size.  */
 
-/* Number of words needed to hold the data in quantity Q.
-   This depends on its machine mode.  It is used for these purposes:
-   1. It is used in computing the relative importances of qtys,
-      which determines the order in which we look for regs for them.
-   2. It is used in rules that prevent tying several registers of
-      different sizes in a way that is geometrically impossible
-      (see combine_regs).  */
+  char changes_size;
 
-static int *qty_size;
+};
 
-/* This holds the mode of the registers that are tied to qty Q,
-   or VOIDmode if registers with differing modes are tied together.  */
+static struct qty *qty;
 
-static enum machine_mode *qty_mode;
+/* These fields are kept separately to speedup their clearing.  */
 
-/* Number of times a reg tied to qty Q lives across a CALL_INSN.  */
+/* We maintain two hard register sets that indicate suggested hard registers
+   for each quantity.  The first, phys_copy_sugg, contains hard registers
+   that are tied to the quantity by a simple copy.  The second contains all
+   hard registers that are tied to the quantity via an arithmetic operation.
+
+   The former register set is given priority for allocation.  This tends to
+   eliminate copy insns.  */
+
+/* Element Q is a set of hard registers that are suggested for quantity Q by
+   copy insns.  */
 
-static int *qty_n_calls_crossed;
+static HARD_REG_SET *qty_phys_copy_sugg;
 
-/* Register class within which we allocate qty Q if we can't get
-   its preferred class.  */
+/* Element Q is a set of hard registers that are suggested for quantity Q by
+   arithmetic insns.  */
 
-static enum reg_class *qty_alternate_class;
+static HARD_REG_SET *qty_phys_sugg;
 
-/* Element Q is nonzero if this quantity has been used in a SUBREG
-   that changes its size.  */
+/* Element Q is the number of suggested registers in qty_phys_copy_sugg.  */
 
-static char *qty_changes_size;
+static short *qty_phys_num_copy_sugg;
 
-/* Element Q is the register number of one pseudo register whose
-   reg_qty value is Q.  This register should be the head of the chain
-   maintained in reg_next_in_qty.  */
+/* Element Q is the number of suggested registers in qty_phys_sugg.  */
+
+static short *qty_phys_num_sugg;
 
-static int *qty_first_reg;
 
 /* If (REG N) has been assigned a quantity number, is a register number
    of another register assigned the same quantity number, or -1 for the
-   end of the chain.  qty_first_reg point to the head of this chain.  */
+   end of the chain.  qty->first_reg point to the head of this chain.  */
 
 static int *reg_next_in_qty;
 
@@ -237,31 +248,34 @@ static rtx *reg_equiv_replacement;
 /* Used for communication between update_equiv_regs and no_equiv.  */
 static rtx *reg_equiv_init_insns;
 
-static void alloc_qty          PROTO((int, enum machine_mode, int, int));
-static void validate_equiv_mem_from_store PROTO((rtx, rtx));
-static int validate_equiv_mem  PROTO((rtx, rtx, rtx));
-static int contains_replace_regs PROTO((rtx, char *));
-static int memref_referenced_p PROTO((rtx, rtx));
-static int memref_used_between_p PROTO((rtx, rtx, rtx));
-static void update_equiv_regs  PROTO((void));
-static void no_equiv           PROTO((rtx, rtx));
-static void block_alloc                PROTO((int));
-static int qty_sugg_compare            PROTO((int, int));
-static int qty_sugg_compare_1  PROTO((const GENERIC_PTR, const GENERIC_PTR));
-static int qty_compare         PROTO((int, int));
-static int qty_compare_1       PROTO((const GENERIC_PTR, const GENERIC_PTR));
-static int combine_regs                PROTO((rtx, rtx, int, int, rtx, int));
-static int reg_meets_class_p   PROTO((int, enum reg_class));
-static void update_qty_class   PROTO((int, int));
-static void reg_is_set         PROTO((rtx, rtx));
-static void reg_is_born                PROTO((rtx, int));
-static void wipe_dead_reg      PROTO((rtx, int));
-static int find_free_reg       PROTO((enum reg_class, enum machine_mode,
+/* Nonzero if we recorded an equivalence for a LABEL_REF.  */
+static int recorded_label_ref;
+
+static void alloc_qty          PARAMS ((int, enum machine_mode, int, int));
+static void validate_equiv_mem_from_store PARAMS ((rtx, rtx, void *));
+static int validate_equiv_mem  PARAMS ((rtx, rtx, rtx));
+static int contains_replace_regs PARAMS ((rtx, char *));
+static int memref_referenced_p PARAMS ((rtx, rtx));
+static int memref_used_between_p PARAMS ((rtx, rtx, rtx));
+static void update_equiv_regs  PARAMS ((void));
+static void no_equiv           PARAMS ((rtx, rtx, void *));
+static void block_alloc                PARAMS ((int));
+static int qty_sugg_compare            PARAMS ((int, int));
+static int qty_sugg_compare_1  PARAMS ((const PTR, const PTR));
+static int qty_compare         PARAMS ((int, int));
+static int qty_compare_1       PARAMS ((const PTR, const PTR));
+static int combine_regs                PARAMS ((rtx, rtx, int, int, rtx, int));
+static int reg_meets_class_p   PARAMS ((int, enum reg_class));
+static void update_qty_class   PARAMS ((int, int));
+static void reg_is_set         PARAMS ((rtx, rtx, void *));
+static void reg_is_born                PARAMS ((rtx, int));
+static void wipe_dead_reg      PARAMS ((rtx, int));
+static int find_free_reg       PARAMS ((enum reg_class, enum machine_mode,
                                       int, int, int, int, int));
-static void mark_life          PROTO((int, enum machine_mode, int));
-static void post_mark_life     PROTO((int, enum machine_mode, int, int, int));
-static int no_conflict_p       PROTO((rtx, rtx, rtx));
-static int requires_inout      PROTO((char *));
+static void mark_life          PARAMS ((int, enum machine_mode, int));
+static void post_mark_life     PARAMS ((int, enum machine_mode, int, int, int));
+static int no_conflict_p       PARAMS ((rtx, rtx, rtx));
+static int requires_inout      PARAMS ((const char *));
 \f
 /* Allocate a new quantity (new within current basic block)
    for register number REGNO which is born at index BIRTH
@@ -273,31 +287,35 @@ alloc_qty (regno, mode, size, birth)
      enum machine_mode mode;
      int size, birth;
 {
-  register int qty = next_qty++;
+  register int qtyno = next_qty++;
 
-  reg_qty[regno] = qty;
+  reg_qty[regno] = qtyno;
   reg_offset[regno] = 0;
   reg_next_in_qty[regno] = -1;
 
-  qty_first_reg[qty] = regno;
-  qty_size[qty] = size;
-  qty_mode[qty] = mode;
-  qty_birth[qty] = birth;
-  qty_n_calls_crossed[qty] = REG_N_CALLS_CROSSED (regno);
-  qty_min_class[qty] = reg_preferred_class (regno);
-  qty_alternate_class[qty] = reg_alternate_class (regno);
-  qty_n_refs[qty] = REG_N_REFS (regno);
-  qty_changes_size[qty] = REG_CHANGES_SIZE (regno);
+  qty[qtyno].first_reg = regno;
+  qty[qtyno].size = size;
+  qty[qtyno].mode = mode;
+  qty[qtyno].birth = birth;
+  qty[qtyno].n_calls_crossed = REG_N_CALLS_CROSSED (regno);
+  qty[qtyno].min_class = reg_preferred_class (regno);
+  qty[qtyno].alternate_class = reg_alternate_class (regno);
+  qty[qtyno].n_refs = REG_N_REFS (regno);
+  qty[qtyno].changes_size = REG_CHANGES_SIZE (regno);
 }
 \f
 /* Main entry point of this file.  */
 
-void
+int
 local_alloc ()
 {
   register int b, i;
   int max_qty;
 
+  /* We need to keep track of whether or not we recorded a LABEL_REF so
+     that we know if the jump optimizer needs to be rerun.  */
+  recorded_label_ref = 0;
+
   /* Leaf functions and non-leaf functions have different needs.
      If defined, let the machine say what kind of ordering we
      should use.  */
@@ -317,29 +335,16 @@ local_alloc ()
      See the declarations of these variables, above,
      for what they mean.  */
 
-  qty_phys_reg = (short *) alloca (max_qty * sizeof (short));
+  qty = (struct qty *) xmalloc (max_qty * sizeof (struct qty));
   qty_phys_copy_sugg
-    = (HARD_REG_SET *) alloca (max_qty * sizeof (HARD_REG_SET));
-  qty_phys_num_copy_sugg = (short *) alloca (max_qty * sizeof (short));
-  qty_phys_sugg = (HARD_REG_SET *) alloca (max_qty * sizeof (HARD_REG_SET));
-  qty_phys_num_sugg = (short *) alloca (max_qty * sizeof (short));
-  qty_birth = (int *) alloca (max_qty * sizeof (int));
-  qty_death = (int *) alloca (max_qty * sizeof (int));
-  qty_first_reg = (int *) alloca (max_qty * sizeof (int));
-  qty_size = (int *) alloca (max_qty * sizeof (int));
-  qty_mode
-    = (enum machine_mode *) alloca (max_qty * sizeof (enum machine_mode));
-  qty_n_calls_crossed = (int *) alloca (max_qty * sizeof (int));
-  qty_min_class
-    = (enum reg_class *) alloca (max_qty * sizeof (enum reg_class));
-  qty_alternate_class
-    = (enum reg_class *) alloca (max_qty * sizeof (enum reg_class));
-  qty_n_refs = (int *) alloca (max_qty * sizeof (int));
-  qty_changes_size = (char *) alloca (max_qty * sizeof (char));
-
-  reg_qty = (int *) alloca (max_regno * sizeof (int));
-  reg_offset = (char *) alloca (max_regno * sizeof (char));
-  reg_next_in_qty = (int *) alloca (max_regno * sizeof (int));
+    = (HARD_REG_SET *) xmalloc (max_qty * sizeof (HARD_REG_SET));
+  qty_phys_num_copy_sugg = (short *) xmalloc (max_qty * sizeof (short));
+  qty_phys_sugg = (HARD_REG_SET *) xmalloc (max_qty * sizeof (HARD_REG_SET));
+  qty_phys_num_sugg = (short *) xmalloc (max_qty * sizeof (short));
+
+  reg_qty = (int *) xmalloc (max_regno * sizeof (int));
+  reg_offset = (char *) xmalloc (max_regno * sizeof (char));
+  reg_next_in_qty = (int *) xmalloc(max_regno * sizeof (int));
 
   /* Allocate the reg_renumber array */
   allocate_reg_info (max_regno, FALSE, TRUE);
@@ -402,10 +407,19 @@ local_alloc ()
       next_qty = 0;
 
       block_alloc (b);
-#ifdef USE_C_ALLOCA
-      alloca (0);
-#endif
     }
+
+  free (qty);
+  free (qty_phys_copy_sugg);
+  free (qty_phys_num_copy_sugg);
+  free (qty_phys_sugg);
+  free (qty_phys_num_sugg);
+
+  free (reg_qty);
+  free (reg_offset);
+  free (reg_next_in_qty);
+
+  return recorded_label_ref;
 }
 \f
 /* Depth of loops we are in while in update_equiv_regs.  */
@@ -422,9 +436,10 @@ static int equiv_mem_modified;
    Called via note_stores.  */
 
 static void
-validate_equiv_mem_from_store (dest, set)
+validate_equiv_mem_from_store (dest, set, data)
      rtx dest;
      rtx set ATTRIBUTE_UNUSED;
+     void *data ATTRIBUTE_UNUSED;
 {
   if ((GET_CODE (dest) == REG
        && reg_overlap_mentioned_p (dest, equiv_mem))
@@ -469,7 +484,7 @@ validate_equiv_mem (start, reg, memref)
          && ! CONST_CALL_P (insn))
        return 0;
 
-      note_stores (PATTERN (insn), validate_equiv_mem_from_store);
+      note_stores (PATTERN (insn), validate_equiv_mem_from_store, NULL);
 
       /* If a register mentioned in MEMREF is modified via an
         auto-increment, we lose the equivalence.  Do the same if one
@@ -495,7 +510,7 @@ contains_replace_regs (x, reg_equiv_replace)
      char *reg_equiv_replace;
 {
   int i, j;
-  char *fmt;
+  const char *fmt;
   enum rtx_code code = GET_CODE (x);
 
   switch (code)
@@ -545,7 +560,7 @@ memref_referenced_p (memref, x)
      rtx memref;
 {
   int i, j;
-  char *fmt;
+  const char *fmt;
   enum rtx_code code = GET_CODE (x);
 
   switch (code)
@@ -626,6 +641,22 @@ memref_used_between_p (memref, start, end)
   return 0;
 }
 \f
+/* Return nonzero if the rtx X is invariant over the current function.  */
+int
+function_invariant_p (x)
+     rtx x;
+{
+  if (CONSTANT_P (x))
+    return 1;
+  if (x == frame_pointer_rtx || x == arg_pointer_rtx)
+    return 1;
+  if (GET_CODE (x) == PLUS
+      && (XEXP (x, 0) == frame_pointer_rtx || XEXP (x, 0) == arg_pointer_rtx)
+      && CONSTANT_P (XEXP (x, 1)))
+    return 1;
+  return 0;
+}
+
 /* Find registers that are equivalent to a single value throughout the
    compilation (either because they can be referenced in memory or are set once
    from a single constant).  Lower their priority for a register.
@@ -639,21 +670,17 @@ update_equiv_regs ()
 {
   /* Set when an attempt should be made to replace a register with the
      associated reg_equiv_replacement entry at the end of this function.  */
-  char *reg_equiv_replace
-    = (char *) alloca (max_regno * sizeof *reg_equiv_replace);
+  char *reg_equiv_replace;
   rtx insn;
   int block, depth;
 
-  reg_equiv_init_insns = (rtx *) alloca (max_regno * sizeof (rtx));
-  reg_equiv_replacement = (rtx *) alloca (max_regno * sizeof (rtx));
-
-  bzero ((char *) reg_equiv_init_insns, max_regno * sizeof (rtx));
-  bzero ((char *) reg_equiv_replacement, max_regno * sizeof (rtx));
-  bzero ((char *) reg_equiv_replace, max_regno * sizeof *reg_equiv_replace);
+  reg_equiv_replace = (char *) xcalloc (max_regno, sizeof *reg_equiv_replace);
+  reg_equiv_init_insns = (rtx *) xcalloc (max_regno, sizeof (rtx));
+  reg_equiv_replacement = (rtx *) xcalloc (max_regno, sizeof (rtx));
 
   init_alias_analysis ();
 
-  loop_depth = 1;
+  loop_depth = 0;
 
   /* Scan the insns and find which registers have equivalences.  Do this
      in a separate scan of the insns because (due to -fcse-follow-jumps)
@@ -678,7 +705,7 @@ update_equiv_regs ()
 
       for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
        if (REG_NOTE_KIND (note) == REG_INC)
-         no_equiv (XEXP (note, 0), note);
+         no_equiv (XEXP (note, 0), note, NULL);
 
       set = single_set (insn);
 
@@ -686,7 +713,7 @@ update_equiv_regs ()
         only mark all destinations as having no known equivalence.  */
       if (set == 0)
        {
-         note_stores (PATTERN (insn), no_equiv);
+         note_stores (PATTERN (insn), no_equiv, NULL);
          continue;
        }
       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
@@ -697,7 +724,7 @@ update_equiv_regs ()
            {
              rtx part = XVECEXP (PATTERN (insn), 0, i);
              if (part != set)
-               note_stores (part, no_equiv);
+               note_stores (part, no_equiv, NULL);
            }
        }
 
@@ -731,7 +758,8 @@ update_equiv_regs ()
          && REG_N_SETS (regno) == 1
          && reg_equiv_init_insns[regno] != 0
          && reg_equiv_init_insns[regno] != const0_rtx
-         && ! find_reg_note (insn, REG_EQUIV, NULL_RTX)
+         && ! find_reg_note (XEXP (reg_equiv_init_insns[regno], 0),
+                             REG_EQUIV, NULL_RTX)
          && ! contains_replace_regs (XEXP (dest, 0), reg_equiv_replace))
        {
          rtx init_insn = XEXP (reg_equiv_init_insns[regno], 0);
@@ -750,7 +778,7 @@ update_equiv_regs ()
         calculate_needs, but we traditionally work around this problem
         here by rejecting equivalences when the destination is in a register
         that's likely spilled.  This is fragile, of course, since the
-        preferred class of a pseudo depends on all intructions that set
+        preferred class of a pseudo depends on all instructions that set
         or use it.  */
 
       if (GET_CODE (dest) != REG
@@ -761,7 +789,7 @@ update_equiv_regs ()
        {
          /* This might be seting a SUBREG of a pseudo, a pseudo that is
             also set somewhere else to a constant.  */
-         note_stores (set, no_equiv);
+         note_stores (set, no_equiv, NULL);
          continue;
        }
       /* Don't handle the equivalence if the source is in a register
@@ -770,36 +798,20 @@ update_equiv_regs ()
          && REGNO (src) >= FIRST_PSEUDO_REGISTER
          && CLASS_LIKELY_SPILLED_P (reg_preferred_class (REGNO (src))))
        {
-         no_equiv (dest, set);
+         no_equiv (dest, set, NULL);
          continue;
        }
 
       note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
 
-#ifdef DONT_RECORD_EQUIVALENCE
-      /* Allow the target to reject promotions of some REG_EQUAL notes to
-        REG_EQUIV notes.
-
-        In some cases this can improve register allocation if the existence
-        of the REG_EQUIV note is likely to increase the lifetime of a register
-        that is likely to be spilled.
-
-        It may also be necessary if the target can't handle certain constant
-        expressions appearing randomly in insns, but for whatever reason
-        those expressions must be considered legitimate constant expressions
-        to prevent them from being forced into memory.  */
-      if (note && DONT_RECORD_EQUIVALENCE (note))
-        note = NULL;
-#endif
-
       if (REG_N_SETS (regno) != 1
          && (! note
-             || ! CONSTANT_P (XEXP (note, 0))
+             || ! function_invariant_p (XEXP (note, 0))
              || (reg_equiv_replacement[regno]
                  && ! rtx_equal_p (XEXP (note, 0),
                                    reg_equiv_replacement[regno]))))
        {
-         no_equiv (dest, set);
+         no_equiv (dest, set, NULL);
          continue;
        }
       /* Record this insn as initializing this register.  */
@@ -808,7 +820,7 @@ update_equiv_regs ()
 
       /* If this register is known to be equal to a constant, record that
         it is always equivalent to the constant.  */
-      if (note && CONSTANT_P (XEXP (note, 0)))
+      if (note && function_invariant_p (XEXP (note, 0)))
        PUT_MODE (note, (enum machine_mode) REG_EQUIV);
 
       /* If this insn introduces a "constant" register, decrease the priority
@@ -838,6 +850,19 @@ update_equiv_regs ()
        {
          int regno = REGNO (dest);
 
+         /* Record whether or not we created a REG_EQUIV note for a LABEL_REF.
+            We might end up substituting the LABEL_REF for uses of the
+            pseudo here or later.  That kind of transformation may turn an
+            indirect jump into a direct jump, in which case we must rerun the
+            jump optimizer to ensure that the JUMP_LABEL fields are valid.  */
+         if (GET_CODE (XEXP (note, 0)) == LABEL_REF
+             || (GET_CODE (XEXP (note, 0)) == CONST
+                 && GET_CODE (XEXP (XEXP (note, 0), 0)) == PLUS
+                 && (GET_CODE (XEXP (XEXP (XEXP (note, 0), 0), 0))
+                     == LABEL_REF)))
+           recorded_label_ref = 1;
+         
+        
          reg_equiv_replacement[regno] = XEXP (note, 0);
 
          /* Don't mess with things live during setjmp.  */
@@ -884,7 +909,7 @@ update_equiv_regs ()
 
       /* Keep track of which basic block we are in.  */
       if (block + 1 < n_basic_blocks
-         && basic_block_head[block + 1] == insn)
+         && BLOCK_HEAD (block + 1) == insn)
        ++block;
 
       if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
@@ -945,11 +970,11 @@ update_equiv_regs ()
 
                  emit_insn_before (copy_rtx (PATTERN (equiv_insn)), insn);
                  REG_NOTES (PREV_INSN (insn)) = REG_NOTES (equiv_insn);
+                 REG_NOTES (equiv_insn) = 0;
 
                  PUT_CODE (equiv_insn, NOTE);
                  NOTE_LINE_NUMBER (equiv_insn) = NOTE_INSN_DELETED;
                  NOTE_SOURCE_FILE (equiv_insn) = 0;
-                 REG_NOTES (equiv_insn) = 0;
 
                  if (block < 0)
                    REG_BASIC_BLOCK (regno) = 0;
@@ -958,15 +983,22 @@ update_equiv_regs ()
                  REG_N_CALLS_CROSSED (regno) = 0;
                  REG_LIVE_LENGTH (regno) = 2;
 
-                 if (block >= 0 && insn == basic_block_head[block])
-                   basic_block_head[block] = PREV_INSN (insn);
+                 if (block >= 0 && insn == BLOCK_HEAD (block))
+                   BLOCK_HEAD (block) = PREV_INSN (insn);
 
                  for (l = 0; l < n_basic_blocks; l++)
-                   CLEAR_REGNO_REG_SET (basic_block_live_at_start[l], regno);
+                   CLEAR_REGNO_REG_SET (BASIC_BLOCK (l)->global_live_at_start,
+                                        regno);
                }
            }
        }
     }
+
+  /* Clean up.  */
+  end_alias_analysis ();
+  free (reg_equiv_replace);
+  free (reg_equiv_init_insns);
+  free (reg_equiv_replacement);
 }
 
 /* Mark REG as having no known equivalence.
@@ -977,8 +1009,9 @@ update_equiv_regs ()
    assignment - a SET, CLOBBER or REG_INC note.  It is currently not used,
    but needs to be there because this function is called from note_stores.  */
 static void
-no_equiv (reg, store)
-     rtx reg, store;
+no_equiv (reg, store, data)
+     rtx reg, store ATTRIBUTE_UNUSED;
+     void *data ATTRIBUTE_UNUSED;
 {
   int regno;
   rtx list;
@@ -1016,36 +1049,33 @@ block_alloc (b)
 
   /* Count the instructions in the basic block.  */
 
-  insn = basic_block_end[b];
+  insn = BLOCK_END (b);
   while (1)
     {
       if (GET_CODE (insn) != NOTE)
        if (++insn_count > max_uid)
          abort ();
-      if (insn == basic_block_head[b])
+      if (insn == BLOCK_HEAD (b))
        break;
       insn = PREV_INSN (insn);
     }
 
   /* +2 to leave room for a post_mark_life at the last insn and for
      the birth of a CLOBBER in the first insn.  */
-  regs_live_at = (HARD_REG_SET *) alloca ((2 * insn_count + 2)
-                                         * sizeof (HARD_REG_SET));
-  bzero ((char *) regs_live_at, (2 * insn_count + 2) * sizeof (HARD_REG_SET));
+  regs_live_at = (HARD_REG_SET *) xcalloc ((2 * insn_count + 2),
+                                          sizeof (HARD_REG_SET));
 
   /* Initialize table of hardware registers currently live.  */
 
-  REG_SET_TO_HARD_REG_SET (regs_live, basic_block_live_at_start[b]);
+  REG_SET_TO_HARD_REG_SET (regs_live, BASIC_BLOCK (b)->global_live_at_start);
 
   /* This loop scans the instructions of the basic block
      and assigns quantities to registers.
      It computes which registers to tie.  */
 
-  insn = basic_block_head[b];
+  insn = BLOCK_HEAD (b);
   while (1)
     {
-      register rtx body = PATTERN (insn);
-
       if (GET_CODE (insn) != NOTE)
        insn_number++;
 
@@ -1053,7 +1083,7 @@ block_alloc (b)
        {
          register rtx link, set;
          register int win = 0;
-         register rtx r0, r1;
+         register rtx r0, r1 = NULL_RTX;
          int combined_regno = -1;
          int i;
 
@@ -1081,48 +1111,39 @@ block_alloc (b)
 
             If tying is done, WIN is set nonzero.  */
 
-         if (1
-#ifdef REGISTER_CONSTRAINTS
-             && recog_n_operands > 1
-             && recog_constraints[0][0] == '='
-             && recog_constraints[0][1] != '&'
-#else
-             && GET_CODE (PATTERN (insn)) == SET
-             && rtx_equal_p (SET_DEST (PATTERN (insn)), recog_operand[0])
-#endif
-             )
+         if (optimize
+             && recog_data.n_operands > 1
+             && recog_data.constraints[0][0] == '='
+             && recog_data.constraints[0][1] != '&')
            {
-#ifdef REGISTER_CONSTRAINTS
              /* If non-negative, is an operand that must match operand 0.  */
              int must_match_0 = -1;
              /* Counts number of alternatives that require a match with
                 operand 0.  */
              int n_matching_alts = 0;
 
-             for (i = 1; i < recog_n_operands; i++)
+             for (i = 1; i < recog_data.n_operands; i++)
                {
-                 char *p = recog_constraints[i];
+                 const char *p = recog_data.constraints[i];
                  int this_match = (requires_inout (p));
 
                  n_matching_alts += this_match;
-                 if (this_match == recog_n_alternatives)
+                 if (this_match == recog_data.n_alternatives)
                    must_match_0 = i;
                }
-#endif
 
-             r0 = recog_operand[0];
-             for (i = 1; i < recog_n_operands; i++)
+             r0 = recog_data.operand[0];
+             for (i = 1; i < recog_data.n_operands; i++)
                {
-#ifdef REGISTER_CONSTRAINTS
                  /* Skip this operand if we found an operand that
                     must match operand 0 and this operand isn't it
                     and can't be made to be it by commutativity.  */
 
                  if (must_match_0 >= 0 && i != must_match_0
                      && ! (i == must_match_0 + 1
-                           && recog_constraints[i-1][0] == '%')
+                           && recog_data.constraints[i-1][0] == '%')
                      && ! (i == must_match_0 - 1
-                           && recog_constraints[i][0] == '%'))
+                           && recog_data.constraints[i][0] == '%'))
                    continue;
 
                  /* Likewise if each alternative has some operand that
@@ -1130,23 +1151,16 @@ block_alloc (b)
                     operand that doesn't list operand 0 since we know that
                     the operand always conflicts with operand 0.  We
                     ignore commutatity in this case to keep things simple.  */
-                 if (n_matching_alts == recog_n_alternatives
-                     && 0 == requires_inout (recog_constraints[i]))
+                 if (n_matching_alts == recog_data.n_alternatives
+                     && 0 == requires_inout (recog_data.constraints[i]))
                    continue;
-#endif
 
-                 r1 = recog_operand[i];
+                 r1 = recog_data.operand[i];
 
                  /* If the operand is an address, find a register in it.
                     There may be more than one register, but we only try one
                     of them.  */
-                 if (
-#ifdef REGISTER_CONSTRAINTS
-                     recog_constraints[i][0] == 'p'
-#else
-                     recog_operand_address_p[i]
-#endif
-                     )
+                 if (recog_data.constraints[i][0] == 'p')
                    while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT)
                      r1 = XEXP (r1, 0);
 
@@ -1157,11 +1171,7 @@ block_alloc (b)
                         can only be in the same register as the output, give
                         priority to an equivalence found from that insn.  */
                      int may_save_copy
-                       = ((SET_DEST (body) == r0 && SET_SRC (body) == r1)
-#ifdef REGISTER_CONSTRAINTS
-                          || (r1 == recog_operand[i] && must_match_0 >= 0)
-#endif
-                          );
+                       = (r1 == recog_data.operand[i] && must_match_0 >= 0);
                      
                      if (GET_CODE (r1) == REG || GET_CODE (r1) == SUBREG)
                        win = combine_regs (r1, r0, may_save_copy,
@@ -1186,7 +1196,8 @@ block_alloc (b)
             destination register won't have had a quantity number
             assigned, since that would prevent combining.  */
 
-         if (GET_CODE (PATTERN (insn)) == CLOBBER
+         if (optimize
+             && GET_CODE (PATTERN (insn)) == CLOBBER
              && (r0 = XEXP (PATTERN (insn), 0),
                  GET_CODE (r0) == REG)
              && (link = find_reg_note (insn, REG_LIBCALL, NULL_RTX)) != 0
@@ -1241,16 +1252,17 @@ block_alloc (b)
          for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
            if (REG_NOTE_KIND (link) == REG_DEAD
                && GET_CODE (XEXP (link, 0)) == REG
-               && combined_regno != REGNO (XEXP (link, 0))
-               && (no_conflict_combined_regno != REGNO (XEXP (link, 0))
-                   || ! find_reg_note (insn, REG_NO_CONFLICT, XEXP (link, 0))))
+               && combined_regno != (int) REGNO (XEXP (link, 0))
+               && (no_conflict_combined_regno != (int) REGNO (XEXP (link, 0))
+                   || ! find_reg_note (insn, REG_NO_CONFLICT,
+                                       XEXP (link, 0))))
              wipe_dead_reg (XEXP (link, 0), 0);
 
          /* Allocate qty numbers for all registers local to this block
             that are born (set) in this instruction.
             A pseudo that already has a qty is not changed.  */
 
-         note_stores (PATTERN (insn), reg_is_set);
+         note_stores (PATTERN (insn), reg_is_set, NULL);
 
          /* If anything is set in this insn and then unused, mark it as dying
             after this insn, so it will conflict with our outputs.  This
@@ -1279,7 +1291,7 @@ block_alloc (b)
       IOR_HARD_REG_SET (regs_live_at[2 * insn_number], regs_live);
       IOR_HARD_REG_SET (regs_live_at[2 * insn_number + 1], regs_live);
 
-      if (insn == basic_block_end[b])
+      if (insn == BLOCK_END (b))
        break;
 
       insn = NEXT_INSN (insn);
@@ -1293,7 +1305,7 @@ block_alloc (b)
      number of suggested registers they need so we allocate those with
      the most restrictive needs first.  */
 
-  qty_order = (int *) alloca (next_qty * sizeof (int));
+  qty_order = (int *) xmalloc (next_qty * sizeof (int));
   for (i = 0; i < next_qty; i++)
     qty_order[i] = i;
 
@@ -1333,10 +1345,10 @@ block_alloc (b)
     {
       q = qty_order[i];
       if (qty_phys_num_sugg[q] != 0 || qty_phys_num_copy_sugg[q] != 0)
-       qty_phys_reg[q] = find_free_reg (qty_min_class[q], qty_mode[q], q,
-                                        0, 1, qty_birth[q], qty_death[q]);
+       qty[q].phys_reg = find_free_reg (qty[q].min_class, qty[q].mode, q,
+                                        0, 1, qty[q].birth, qty[q].death);
       else
-       qty_phys_reg[q] = -1;
+       qty[q].phys_reg = -1;
     }
 
   /* Order the qtys so we assign them registers in order of 
@@ -1383,7 +1395,7 @@ block_alloc (b)
   for (i = 0; i < next_qty; i++)
     {
       q = qty_order[i];
-      if (qty_phys_reg[q] < 0)
+      if (qty[q].phys_reg < 0)
        {
 #ifdef INSN_SCHEDULING
          /* These values represent the adjusted lifetime of a qty so
@@ -1394,8 +1406,8 @@ block_alloc (b)
             discourage the register allocator from creating false
             dependencies.
  
-            The adjustment by the value +-3 indicates precisely that
-            this qty conflicts with qtys in the instructions immediately
+            The adjustment value is choosen to indicate that this qty
+            conflicts with all the qtys in the instructions immediately
             before and after the lifetime of this qty.
 
             Experiments have shown that higher values tend to hurt
@@ -1403,8 +1415,9 @@ block_alloc (b)
 
             If allocation using the extended lifetime fails we will try
             again with the qty's unadjusted lifetime.  */
-         int fake_birth = MAX (0, qty_birth[q] - 3);
-         int fake_death = MIN (insn_number * 2 + 1, qty_death[q] + 3);
+         int fake_birth = MAX (0, qty[q].birth - 2 + qty[q].birth % 2);
+         int fake_death = MIN (insn_number * 2 + 1,
+                               qty[q].death + 2 - qty[q].death % 2);
 #endif
 
          if (N_REG_CLASSES > 1)
@@ -1422,17 +1435,17 @@ block_alloc (b)
                  && !SMALL_REGISTER_CLASSES)
                {
                
-                 qty_phys_reg[q] = find_free_reg (qty_min_class[q]
-                                                  qty_mode[q], q, 0, 0,
+                 qty[q].phys_reg = find_free_reg (qty[q].min_class
+                                                  qty[q].mode, q, 0, 0,
                                                   fake_birth, fake_death);
-                 if (qty_phys_reg[q] >= 0)
+                 if (qty[q].phys_reg >= 0)
                    continue;
                }
 #endif
-             qty_phys_reg[q] = find_free_reg (qty_min_class[q]
-                                              qty_mode[q], q, 0, 0,
-                                              qty_birth[q], qty_death[q]);
-             if (qty_phys_reg[q] >= 0)
+             qty[q].phys_reg = find_free_reg (qty[q].min_class
+                                              qty[q].mode, q, 0, 0,
+                                              qty[q].birth, qty[q].death);
+             if (qty[q].phys_reg >= 0)
                continue;
            }
 
@@ -1441,15 +1454,15 @@ block_alloc (b)
          if (flag_schedule_insns_after_reload
              && !optimize_size
              && !SMALL_REGISTER_CLASSES
-             && qty_alternate_class[q] != NO_REGS)
-           qty_phys_reg[q] = find_free_reg (qty_alternate_class[q],
-                                            qty_mode[q], q, 0, 0,
+             && qty[q].alternate_class != NO_REGS)
+           qty[q].phys_reg = find_free_reg (qty[q].alternate_class,
+                                            qty[q].mode, q, 0, 0,
                                             fake_birth, fake_death);
 #endif
-         if (qty_alternate_class[q] != NO_REGS)
-           qty_phys_reg[q] = find_free_reg (qty_alternate_class[q],
-                                            qty_mode[q], q, 0, 0,
-                                            qty_birth[q], qty_death[q]);
+         if (qty[q].alternate_class != NO_REGS)
+           qty[q].phys_reg = find_free_reg (qty[q].alternate_class,
+                                            qty[q].mode, q, 0, 0,
+                                            qty[q].birth, qty[q].death);
        }
     }
 
@@ -1457,11 +1470,15 @@ block_alloc (b)
      to the pseudo regs belonging to the qtys.  */
 
   for (q = 0; q < next_qty; q++)
-    if (qty_phys_reg[q] >= 0)
+    if (qty[q].phys_reg >= 0)
       {
-       for (i = qty_first_reg[q]; i >= 0; i = reg_next_in_qty[i])
-         reg_renumber[i] = qty_phys_reg[q] + reg_offset[i];
+       for (i = qty[q].first_reg; i >= 0; i = reg_next_in_qty[i])
+         reg_renumber[i] = qty[q].phys_reg + reg_offset[i];
       }
+
+  /* Clean up.  */
+  free (regs_live_at);
+  free (qty_order);
 }
 \f
 /* Compare two quantities' priority for getting real registers.
@@ -1481,8 +1498,8 @@ block_alloc (b)
    QTY_CMP_PRI is also used by qty_sugg_compare.  */
 
 #define QTY_CMP_PRI(q)         \
-  ((int) (((double) (floor_log2 (qty_n_refs[q]) * qty_n_refs[q] * qty_size[q]) \
-         / (qty_death[q] - qty_birth[q])) * 10000))
+  ((int) (((double) (floor_log2 (qty[q].n_refs) * qty[q].n_refs * qty[q].size) \
+         / (qty[q].death - qty[q].birth)) * 10000))
 
 static int
 qty_compare (q1, q2)
@@ -1493,10 +1510,10 @@ qty_compare (q1, q2)
 
 static int
 qty_compare_1 (q1p, q2p)
-     const GENERIC_PTR q1p;
-     const GENERIC_PTR q2p;
+     const PTR q1p;
+     const PTR q2p;
 {
-  register int q1 = *(int *)q1p, q2 = *(int *)q2p;
+  register int q1 = *(const int *)q1p, q2 = *(const int *)q2p;
   register int tem = QTY_CMP_PRI (q2) - QTY_CMP_PRI (q1);
 
   if (tem != 0)
@@ -1533,10 +1550,10 @@ qty_sugg_compare (q1, q2)
 
 static int
 qty_sugg_compare_1 (q1p, q2p)
-     const GENERIC_PTR q1p;
-     const GENERIC_PTR q2p;
+     const PTR q1p;
+     const PTR q2p;
 {
-  register int q1 = *(int *)q1p, q2 = *(int *)q2p;
+  register int q1 = *(const int *)q1p, q2 = *(const int *)q2p;
   register int tem = QTY_CMP_SUGG (q1) - QTY_CMP_SUGG (q2);
 
   if (tem != 0)
@@ -1628,7 +1645,7 @@ combine_regs (usedreg, setreg, may_save_copy, insn_number, insn, already_dead)
       /* Do not combine with a smaller already-assigned object
         if that smaller object is already combined with something bigger.  */
       || (ssize > usize && ureg >= FIRST_PSEUDO_REGISTER
-         && usize < qty_size[reg_qty[ureg]])
+         && usize < qty[reg_qty[ureg]].size)
       /* Can't combine if SREG is not a register we can allocate.  */
       || (sreg >= FIRST_PSEUDO_REGISTER && reg_qty[sreg] == -1)
       /* Don't combine with a pseudo mentioned in a REG_NO_CONFLICT note.
@@ -1642,6 +1659,11 @@ combine_regs (usedreg, setreg, may_save_copy, insn_number, insn, already_dead)
       || ureg == sreg
       /* Don't try to connect two different hardware registers.  */
       || (ureg < FIRST_PSEUDO_REGISTER && sreg < FIRST_PSEUDO_REGISTER)
+      /* Don't use a hard reg that might be spilled.  */
+      || (ureg < FIRST_PSEUDO_REGISTER
+         && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (ureg)))
+      || (sreg < FIRST_PSEUDO_REGISTER
+         && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (sreg)))
       /* Don't connect two different machine modes if they have different
         implications as to which registers may be used.  */
       || !MODES_TIEABLE_P (GET_MODE (usedreg), GET_MODE (setreg)))
@@ -1712,30 +1734,30 @@ combine_regs (usedreg, setreg, may_save_copy, insn_number, insn, already_dead)
      are compatible.  */
 
   if ((already_dead || find_regno_note (insn, REG_DEAD, ureg))
-      && reg_meets_class_p (sreg, qty_min_class[reg_qty[ureg]]))
+      && reg_meets_class_p (sreg, qty[reg_qty[ureg]].min_class))
     {
       /* Add SREG to UREG's quantity.  */
       sqty = reg_qty[ureg];
       reg_qty[sreg] = sqty;
       reg_offset[sreg] = reg_offset[ureg] + offset;
-      reg_next_in_qty[sreg] = qty_first_reg[sqty];
-      qty_first_reg[sqty] = sreg;
+      reg_next_in_qty[sreg] = qty[sqty].first_reg;
+      qty[sqty].first_reg = sreg;
 
-      /* If SREG's reg class is smaller, set qty_min_class[SQTY].  */
+      /* If SREG's reg class is smaller, set qty[SQTY].min_class.  */
       update_qty_class (sqty, sreg);
 
       /* Update info about quantity SQTY.  */
-      qty_n_calls_crossed[sqty] += REG_N_CALLS_CROSSED (sreg);
-      qty_n_refs[sqty] += REG_N_REFS (sreg);
+      qty[sqty].n_calls_crossed += REG_N_CALLS_CROSSED (sreg);
+      qty[sqty].n_refs += REG_N_REFS (sreg);
       if (usize < ssize)
        {
          register int i;
 
-         for (i = qty_first_reg[sqty]; i >= 0; i = reg_next_in_qty[i])
+         for (i = qty[sqty].first_reg; i >= 0; i = reg_next_in_qty[i])
            reg_offset[i] -= offset;
 
-         qty_size[sqty] = ssize;
-         qty_mode[sqty] = GET_MODE (setreg);
+         qty[sqty].size = ssize;
+         qty[sqty].mode = GET_MODE (setreg);
        }
     }
   else
@@ -1758,23 +1780,23 @@ reg_meets_class_p (reg, class)
          || reg_class_subset_p (class, rclass));
 }
 
-/* Update the class of QTY assuming that REG is being tied to it.  */
+/* Update the class of QTYNO assuming that REG is being tied to it.  */
 
 static void
-update_qty_class (qty, reg)
-     int qty;
+update_qty_class (qtyno, reg)
+     int qtyno;
      int reg;
 {
   enum reg_class rclass = reg_preferred_class (reg);
-  if (reg_class_subset_p (rclass, qty_min_class[qty]))
-    qty_min_class[qty] = rclass;
+  if (reg_class_subset_p (rclass, qty[qtyno].min_class))
+    qty[qtyno].min_class = rclass;
 
   rclass = reg_alternate_class (reg);
-  if (reg_class_subset_p (rclass, qty_alternate_class[qty]))
-    qty_alternate_class[qty] = rclass;
+  if (reg_class_subset_p (rclass, qty[qtyno].alternate_class))
+    qty[qtyno].alternate_class = rclass;
 
   if (REG_CHANGES_SIZE (reg))
-    qty_changes_size[qty] = 1;
+    qty[qtyno].changes_size = 1;
 }
 \f
 /* Handle something which alters the value of an rtx REG.
@@ -1787,9 +1809,10 @@ update_qty_class (qty, reg)
    carry info from `block_alloc'.  */
 
 static void
-reg_is_set (reg, setter)
+reg_is_set (reg, setter, data)
      rtx reg;
      rtx setter;
+     void *data ATTRIBUTE_UNUSED;
 {
   /* Note that note_stores will only pass us a SUBREG if it is a SUBREG of
      a hard register.  These may actually not exist any more.  */
@@ -1836,7 +1859,7 @@ reg_is_born (reg, birth)
 
       /* If this register has a quantity number, show that it isn't dead.  */
       if (reg_qty[regno] >= 0)
-       qty_death[reg_qty[regno]] = -1;
+       qty[reg_qty[regno]].death = -1;
     }
 }
 
@@ -1855,9 +1878,16 @@ wipe_dead_reg (reg, output_p)
   /* If this insn has multiple results,
      and the dead reg is used in one of the results,
      extend its life to after this insn,
-     so it won't get allocated together with any other result of this insn.  */
+     so it won't get allocated together with any other result of this insn. 
+
+     It is unsafe to use !single_set here since it will ignore an unused
+     output.  Just because an output is unused does not mean the compiler
+     can assume the side effect will not occur.   Consider if REG appears
+     in the address of an output and we reload the output.  If we allocate
+     REG to the same hard register as an unused output we could set the hard
+     register before the output reload insn.  */
   if (GET_CODE (PATTERN (this_insn)) == PARALLEL
-      && !single_set (this_insn))
+      && multiple_sets (this_insn))
     {
       int i;
       for (i = XVECLEN (PATTERN (this_insn), 0) - 1; i >= 0; i--)
@@ -1890,7 +1920,7 @@ wipe_dead_reg (reg, output_p)
     }
 
   else if (reg_qty[regno] >= 0)
-    qty_death[reg_qty[regno]] = 2 * this_insn_number + output_p;
+    qty[reg_qty[regno]].death = 2 * this_insn_number + output_p;
 }
 \f
 /* Find a block of SIZE words of hard regs in reg_class CLASS
@@ -1899,18 +1929,18 @@ wipe_dead_reg (reg, output_p)
    and still free between insn BORN_INDEX and insn DEAD_INDEX,
    and return the number of the first of them.
    Return -1 if such a block cannot be found. 
-   If QTY crosses calls, insist on a register preserved by calls,
+   If QTYNO crosses calls, insist on a register preserved by calls,
    unless ACCEPT_CALL_CLOBBERED is nonzero.
 
    If JUST_TRY_SUGGESTED is non-zero, only try to see if the suggested
    register is available.  If not, return -1.  */
 
 static int
-find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
+find_free_reg (class, mode, qtyno, accept_call_clobbered, just_try_suggested,
               born_index, dead_index)
      enum reg_class class;
      enum machine_mode mode;
-     int qty;
+     int qtyno;
      int accept_call_clobbered;
      int just_try_suggested;
      int born_index, dead_index;
@@ -1931,12 +1961,12 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
   /* Don't let a pseudo live in a reg across a function call
      if we might get a nonlocal goto.  */
   if (current_function_has_nonlocal_label
-      && qty_n_calls_crossed[qty] > 0)
+      && qty[qtyno].n_calls_crossed > 0)
     return -1;
 
   if (accept_call_clobbered)
     COPY_HARD_REG_SET (used, call_fixed_reg_set);
-  else if (qty_n_calls_crossed[qty] == 0)
+  else if (qty[qtyno].n_calls_crossed == 0)
     COPY_HARD_REG_SET (used, fixed_reg_set);
   else
     COPY_HARD_REG_SET (used, call_used_reg_set);
@@ -1968,7 +1998,7 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
 #endif
 
 #ifdef CLASS_CANNOT_CHANGE_SIZE
-  if (qty_changes_size[qty])
+  if (qty[qtyno].changes_size)
     IOR_HARD_REG_SET (used,
                      reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE]);
 #endif
@@ -1983,10 +2013,10 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
 
   if (just_try_suggested)
     {
-      if (qty_phys_num_copy_sugg[qty] != 0)
-       IOR_COMPL_HARD_REG_SET (first_used, qty_phys_copy_sugg[qty]);
+      if (qty_phys_num_copy_sugg[qtyno] != 0)
+       IOR_COMPL_HARD_REG_SET (first_used, qty_phys_copy_sugg[qtyno]);
       else
-       IOR_COMPL_HARD_REG_SET (first_used, qty_phys_sugg[qty]);
+       IOR_COMPL_HARD_REG_SET (first_used, qty_phys_sugg[qtyno]);
     }
 
   /* If all registers are excluded, we can't do anything.  */
@@ -2003,7 +2033,7 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
 #endif
       if (! TEST_HARD_REG_BIT (first_used, regno)
          && HARD_REGNO_MODE_OK (regno, mode)
-         && (qty_n_calls_crossed[qty] == 0
+         && (qty[qtyno].n_calls_crossed == 0
              || accept_call_clobbered
              || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
        {
@@ -2031,12 +2061,12 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
   
   /* If it would be profitable to allocate a call-clobbered register
      and save and restore it around calls, do that.  */
-  if (just_try_suggested && qty_phys_num_copy_sugg[qty] != 0
-      && qty_phys_num_sugg[qty] != 0)
+  if (just_try_suggested && qty_phys_num_copy_sugg[qtyno] != 0
+      && qty_phys_num_sugg[qtyno] != 0)
     {
       /* Don't try the copy-suggested regs again.  */
-      qty_phys_num_copy_sugg[qty] = 0;
-      return find_free_reg (class, mode, qty, accept_call_clobbered, 1,
+      qty_phys_num_copy_sugg[qtyno] = 0;
+      return find_free_reg (class, mode, qtyno, accept_call_clobbered, 1,
                            born_index, dead_index);
     }
 
@@ -2047,10 +2077,10 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
   if (! accept_call_clobbered
       && flag_caller_saves
       && ! just_try_suggested
-      && qty_n_calls_crossed[qty] != 0
-      && CALLER_SAVE_PROFITABLE (qty_n_refs[qty], qty_n_calls_crossed[qty]))
+      && qty[qtyno].n_calls_crossed != 0
+      && CALLER_SAVE_PROFITABLE (qty[qtyno].n_refs, qty[qtyno].n_calls_crossed))
     {
-      i = find_free_reg (class, mode, qty, 1, 0, born_index, dead_index);
+      i = find_free_reg (class, mode, qtyno, 1, 0, born_index, dead_index);
       if (i >= 0)
        caller_save_needed = 1;
       return i;
@@ -2122,7 +2152,7 @@ post_mark_life (regno, mode, life, birth, death)
 
 static int
 no_conflict_p (insn, r0, r1)
-     rtx insn, r0, r1;
+     rtx insn, r0 ATTRIBUTE_UNUSED, r1;
 {
   int ok = 0;
   rtx note = find_reg_note (insn, REG_LIBCALL, NULL_RTX);
@@ -2157,15 +2187,13 @@ no_conflict_p (insn, r0, r1)
   return ok;
 }
 \f
-#ifdef REGISTER_CONSTRAINTS
-
 /* Return the number of alternatives for which the constraint string P
    indicates that the operand must be equal to operand 0 and that no register
    is acceptable.  */
 
 static int
 requires_inout (p)
-     char *p;
+  const char *p;
 {
   char c;
   int found_zero = 0;
@@ -2178,7 +2206,8 @@ requires_inout (p)
       case '=':  case '+':  case '?':
       case '#':  case '&':  case '!':
       case '*':  case '%':
-      case '1':  case '2':  case '3':  case '4':
+      case '1':  case '2':  case '3':  case '4': case '5':
+      case '6':  case '7':  case '8':  case '9':
       case 'm':  case '<':  case '>':  case 'V':  case 'o':
       case 'E':  case 'F':  case 'G':  case 'H':
       case 's':  case 'i':  case 'n':
@@ -2214,7 +2243,6 @@ requires_inout (p)
 
   return num_matching_alts;
 }
-#endif /* REGISTER_CONSTRAINTS */
 \f
 void
 dump_local_alloc (file)