]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/reload1.c
Better spill failure messages.
[gcc.git] / gcc / reload1.c
index 05850def4bcb8fa3a5810a73c48f831773846ca1..2a6f9cc6ae999b912d2e6d8df3c00245a428f7ca 100644 (file)
@@ -25,6 +25,7 @@ Boston, MA 02111-1307, USA.  */
 #include "machmode.h"
 #include "hard-reg-set.h"
 #include "rtl.h"
+#include "tm_p.h"
 #include "obstack.h"
 #include "insn-config.h"
 #include "insn-flags.h"
@@ -214,13 +215,6 @@ static HARD_REG_SET used_spill_regs;
    a round-robin fashion.  */
 static int last_spill_reg;
 
-/* Describes order of preference for putting regs into spill_regs.
-   Contains the numbers of all the hard regs, in order most preferred first.
-   This order is different for each function.
-   It is set up by order_regs_for_reload.
-   Empty elements at the end contain -1.  */
-static short potential_reload_regs[FIRST_PSEUDO_REGISTER];
-
 /* Nonzero if indirect addressing is supported on the machine; this means
    that spilling (REG n) does not require reloading it into a register in
    order to do (MEM (REG n)) or (MEM (PLUS (REG n) (CONST_INT c))).  The
@@ -244,7 +238,11 @@ static rtx spill_stack_slot[FIRST_PSEUDO_REGISTER];
 static int spill_stack_slot_width[FIRST_PSEUDO_REGISTER];
 
 /* Record which pseudos needed to be spilled.  */
-static regset spilled_pseudos;
+static regset_head spilled_pseudos;
+
+/* Used for communication between order_regs_for_reload and count_pseudo.
+   Used to avoid counting one pseudo twice.  */
+static regset_head pseudos_counted;
 
 /* First uid used by insns created by reload in this function.
    Used in find_equiv_reg.  */
@@ -274,9 +272,13 @@ struct obstack reload_obstack;
 char *reload_startobj;
 
 /* The point after all insn_chain structures.  Used to quickly deallocate
-   memory used while processing one insn.  */
+   memory allocated in copy_reloads during calculate_needs_all_insns.  */
 char *reload_firstobj;
 
+/* This points before all local rtl generated by register elimination.
+   Used to quickly free all memory after processing one insn.  */
+static char *reload_insn_firstobj;
+
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
@@ -363,39 +365,26 @@ static int (*offsets_at)[NUM_ELIMINABLE_REGS];
 /* Number of labels in the current function.  */
 
 static int num_labels;
-
-struct hard_reg_n_uses
-{
-  int regno;
-  unsigned int uses;
-};
 \f
 static void maybe_fix_stack_asms       PROTO((void));
+static void copy_reloads               PROTO((struct insn_chain *));
 static void calculate_needs_all_insns  PROTO((int));
-static void calculate_needs            PROTO((struct insn_chain *));
-static void find_reload_regs           PROTO((struct insn_chain *chain,
-                                              FILE *));
-static void find_tworeg_group          PROTO((struct insn_chain *, int,
+static int find_reg                    PROTO((struct insn_chain *, int,
                                               FILE *));
-static void find_group                 PROTO((struct insn_chain *, int,
-                                              FILE *));
-static int possible_group_p            PROTO((struct insn_chain *, int));
-static void count_possible_groups      PROTO((struct insn_chain *, int));
-static int modes_equiv_for_class_p     PROTO((enum machine_mode,
-                                              enum machine_mode,
-                                              enum reg_class));
+static void find_reload_regs           PROTO((struct insn_chain *, FILE *));
+static void select_reload_regs         PROTO((FILE *));
 static void delete_caller_save_insns   PROTO((void));
 
-static void spill_failure              PROTO((rtx));
-static void new_spill_reg              PROTO((struct insn_chain *, int, int,
-                                              int, FILE *));
-static void maybe_mark_pseudo_spilled  PROTO((int));
+static void spill_failure              PROTO((rtx, enum reg_class));
+static void count_spilled_pseudo       PROTO((int, int, int));
 static void delete_dead_insn           PROTO((rtx));
 static void alter_reg                          PROTO((int, int));
 static void set_label_offsets          PROTO((rtx, rtx, int));
+static void check_eliminable_occurrences       PROTO((rtx));
+static void elimination_effects                PROTO((rtx, enum machine_mode));
 static int eliminate_regs_in_insn      PROTO((rtx, int));
 static void update_eliminable_offsets  PROTO((void));
-static void mark_not_eliminable                PROTO((rtx, rtx));
+static void mark_not_eliminable                PROTO((rtx, rtx, void *));
 static void set_initial_elim_offsets   PROTO((void));
 static void verify_initial_elim_offsets        PROTO((void));
 static void set_initial_label_offsets  PROTO((void));
@@ -406,21 +395,23 @@ static void spill_hard_reg                PROTO((int, FILE *, int));
 static int finish_spills               PROTO((int, FILE *));
 static void ior_hard_reg_set           PROTO((HARD_REG_SET *, HARD_REG_SET *));
 static void scan_paradoxical_subregs   PROTO((rtx));
-static int hard_reg_use_compare                PROTO((const PTR, const PTR));
-static void count_pseudo               PROTO((struct hard_reg_n_uses *, int));
+static void count_pseudo               PROTO((int));
 static void order_regs_for_reload      PROTO((struct insn_chain *));
 static void reload_as_needed           PROTO((int));
-static void forget_old_reloads_1       PROTO((rtx, rtx));
+static void forget_old_reloads_1       PROTO((rtx, rtx, void *));
 static int reload_reg_class_lower      PROTO((const PTR, const PTR));
 static void mark_reload_reg_in_use     PROTO((int, int, enum reload_type,
                                               enum machine_mode));
 static void clear_reload_reg_in_use    PROTO((int, int, enum reload_type,
                                               enum machine_mode));
 static int reload_reg_free_p           PROTO((int, int, enum reload_type));
-static int reload_reg_free_for_value_p PROTO((int, int, enum reload_type, rtx, rtx, int, int));
+static int reload_reg_free_for_value_p PROTO((int, int, enum reload_type,
+                                              rtx, rtx, int, int));
 static int reload_reg_reaches_end_p    PROTO((int, int, enum reload_type));
-static int allocate_reload_reg         PROTO((struct insn_chain *, int, int,
-                                              int));
+static int allocate_reload_reg         PROTO((struct insn_chain *, int, int));
+static void failed_reload              PROTO((rtx, int));
+static int set_reload_reg              PROTO((int, int));
+static void choose_reload_regs_init    PROTO((struct insn_chain *, rtx *));
 static void choose_reload_regs         PROTO((struct insn_chain *));
 static void merge_assigned_reloads     PROTO((rtx));
 static void emit_reload_insns          PROTO((struct insn_chain *));
@@ -433,21 +424,26 @@ static void reload_cse_regs_1             PROTO((rtx));
 static void reload_cse_invalidate_regno        PROTO((int, enum machine_mode, int));
 static int reload_cse_mem_conflict_p   PROTO((rtx, rtx));
 static void reload_cse_invalidate_mem  PROTO((rtx));
-static void reload_cse_invalidate_rtx  PROTO((rtx, rtx));
+static void reload_cse_invalidate_rtx  PROTO((rtx, rtx, void *));
 static int reload_cse_regno_equal_p    PROTO((int, rtx, enum machine_mode));
 static int reload_cse_noop_set_p       PROTO((rtx, rtx));
 static int reload_cse_simplify_set     PROTO((rtx, rtx));
 static int reload_cse_simplify_operands        PROTO((rtx));
-static void reload_cse_check_clobber   PROTO((rtx, rtx));
+static void reload_cse_check_clobber   PROTO((rtx, rtx, void *));
 static void reload_cse_record_set      PROTO((rtx, rtx));
 static void reload_combine PROTO((void));
 static void reload_combine_note_use PROTO((rtx *, rtx));
-static void reload_combine_note_store PROTO((rtx, rtx));
+static void reload_combine_note_store PROTO((rtx, rtx, void *));
 static void reload_cse_move2add PROTO((rtx));
-static void move2add_note_store PROTO((rtx, rtx));
+static void move2add_note_store PROTO((rtx, rtx, void *));
 #ifdef AUTO_INC_DEC
 static void add_auto_inc_notes PROTO((rtx, rtx));
 #endif
+static rtx gen_mode_int                        PROTO((enum machine_mode,
+                                              HOST_WIDE_INT));
+static void failed_reload              PROTO((rtx, int));
+static int set_reload_reg              PROTO((int, int));
+extern void dump_needs                 PROTO((struct insn_chain *, FILE *));
 \f
 /* Initialize the reload pass once per compilation.  */
 
@@ -500,6 +496,9 @@ init_reload ()
   /* Initialize obstack for our rtl allocation.  */
   gcc_obstack_init (&reload_obstack);
   reload_startobj = (char *) obstack_alloc (&reload_obstack, 0);
+
+  INIT_REG_SET (&spilled_pseudos);
+  INIT_REG_SET (&pseudos_counted);
 }
 
 /* List of insn chains that are currently unused.  */
@@ -515,8 +514,8 @@ new_insn_chain ()
     {
       c = (struct insn_chain *)
        obstack_alloc (&reload_obstack, sizeof (struct insn_chain));
-      c->live_before = OBSTACK_ALLOC_REG_SET (&reload_obstack);
-      c->live_after = OBSTACK_ALLOC_REG_SET (&reload_obstack);
+      c->live_throughout = OBSTACK_ALLOC_REG_SET (&reload_obstack);
+      c->dead_or_set = OBSTACK_ALLOC_REG_SET (&reload_obstack);
     }
   else
     {
@@ -798,35 +797,7 @@ reload (first, global, dumpfile)
   for (insn = first; insn && num_eliminable; insn = NEXT_INSN (insn))
     if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
        || GET_CODE (insn) == CALL_INSN)
-      note_stores (PATTERN (insn), mark_not_eliminable);
-
-#ifndef REGISTER_CONSTRAINTS
-  /* If all the pseudo regs have hard regs,
-     except for those that are never referenced,
-     we know that no reloads are needed.  */
-  /* But that is not true if there are register constraints, since
-     in that case some pseudos might be in the wrong kind of hard reg.  */
-
-  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
-    if (reg_renumber[i] == -1 && REG_N_REFS (i) != 0)
-      break;
-
-  if (i == max_regno && num_eliminable == 0 && ! caller_save_needed)
-    {
-      free (real_known_ptr);
-      free (real_at_ptr);
-      free (reg_equiv_constant);
-      free (reg_equiv_memory_loc);
-      free (reg_equiv_mem);
-      free (reg_equiv_init);
-      free (reg_equiv_address);
-      free (reg_max_ref_width);
-      free (reg_old_renumber);
-      free (pseudo_previous_regs);
-      free (pseudo_forbidden_regs);
-      return 0;
-    }
-#endif
+      note_stores (PATTERN (insn), mark_not_eliminable, NULL);
 
   maybe_fix_stack_asms ();
 
@@ -836,8 +807,6 @@ reload (first, global, dumpfile)
   /* Initialize to -1, which means take the first spill register.  */
   last_spill_reg = -1;
 
-  spilled_pseudos = ALLOCA_REG_SET ();
-
   /* Spill any hard regs that we know we can't eliminate.  */
   CLEAR_HARD_REG_SET (used_spill_regs);
   for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
@@ -861,7 +830,6 @@ reload (first, global, dumpfile)
     {
       int something_changed;
       int did_spill;
-      struct insn_chain *chain;
 
       HOST_WIDE_INT starting_frame_size;
 
@@ -947,7 +915,7 @@ reload (first, global, dumpfile)
 
       calculate_needs_all_insns (global);
 
-      CLEAR_REG_SET (spilled_pseudos);
+      CLEAR_REG_SET (&spilled_pseudos);
       did_spill = 0;
 
       something_changed = 0;
@@ -980,12 +948,7 @@ reload (first, global, dumpfile)
            }
       }
 
-      CLEAR_HARD_REG_SET (used_spill_regs);
-      /* Try to satisfy the needs for each insn.  */
-      for (chain = insns_need_reload; chain != 0;
-          chain = chain->next_need_reload)
-       find_reload_regs (chain, dumpfile);
-
+      select_reload_regs (dumpfile);
       if (failure)
        goto failed;
 
@@ -997,6 +960,8 @@ reload (first, global, dumpfile)
 
       if (caller_save_needed)
        delete_caller_save_insns ();
+
+      obstack_free (&reload_obstack, reload_firstobj);
     }
 
   /* If global-alloc was run, notify it of any register eliminations we have
@@ -1068,6 +1033,7 @@ reload (first, global, dumpfile)
      and we decide not to abort about it.  */
  failed:
 
+  CLEAR_REG_SET (&spilled_pseudos);
   reload_in_progress = 0;
 
   /* Now eliminate all pseudo regs by modifying them into
@@ -1125,13 +1091,12 @@ reload (first, global, dumpfile)
      which are only valid during and after reload.  */
   reload_completed = 1;
 
-  /* Make a pass over all the insns and delete all USEs which we
-     inserted only to tag a REG_EQUAL note on them.  Remove all
-     REG_DEAD and REG_UNUSED notes.  Delete all CLOBBER insns and
-     simplify (subreg (reg)) operands.  Also remove all REG_RETVAL and
-     REG_LIBCALL notes since they are no longer useful or accurate.
-     Strip and regenerate REG_INC notes that may have been moved
-     around.  */
+  /* Make a pass over all the insns and delete all USEs which we inserted
+     only to tag a REG_EQUAL note on them.  Remove all REG_DEAD and REG_UNUSED
+     notes.  Delete all CLOBBER insns that don't refer to the return value
+     and simplify (subreg (reg)) operands.  Also remove all REG_RETVAL and
+     REG_LIBCALL notes since they are no longer useful or accurate.  Strip
+     and regenerate REG_INC notes that may have been moved around.  */
 
   for (insn = first; insn; insn = NEXT_INSN (insn))
     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
@@ -1140,7 +1105,9 @@ reload (first, global, dumpfile)
 
        if ((GET_CODE (PATTERN (insn)) == USE
             && find_reg_note (insn, REG_EQUAL, NULL_RTX))
-           || GET_CODE (PATTERN (insn)) == CLOBBER)
+           || (GET_CODE (PATTERN (insn)) == CLOBBER
+               && (GET_CODE (XEXP (PATTERN (insn), 0)) != REG
+                   || ! REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))))
          {
            PUT_CODE (insn, NOTE);
            NOTE_SOURCE_FILE (insn) = 0;
@@ -1212,8 +1179,6 @@ reload (first, global, dumpfile)
   free (pseudo_previous_regs);
   free (pseudo_forbidden_regs);
 
-  FREE_REG_SET (spilled_pseudos);
-
   CLEAR_HARD_REG_SET (used_spill_regs);
   for (i = 0; i < n_spills; i++)
     SET_HARD_REG_BIT (used_spill_regs, spill_regs[i]);
@@ -1264,7 +1229,7 @@ maybe_fix_stack_asms ()
        }
 
       /* Get the operand values and constraints out of the insn.  */
-      decode_asm_operands (pat, recog_operand, recog_operand_loc,
+      decode_asm_operands (pat, recog_data.operand, recog_data.operand_loc,
                           constraints, operand_mode);
 
       /* For every operand, see what registers are allowed.  */
@@ -1330,15 +1295,28 @@ maybe_fix_stack_asms ()
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        if (TEST_HARD_REG_BIT (allowed, i))
          {
-           CLEAR_REGNO_REG_SET (chain->live_before, i);
-           CLEAR_REGNO_REG_SET (chain->live_after, i);
+           CLEAR_REGNO_REG_SET (chain->live_throughout, i);
+           CLEAR_REGNO_REG_SET (chain->dead_or_set, i);
          }
     }
 
 #endif
 }
-
 \f
+/* Copy the global variables n_reloads and rld into the corresponding elts
+   of CHAIN.  */
+static void
+copy_reloads (chain)
+     struct insn_chain *chain;
+{
+  chain->n_reloads = n_reloads;
+  chain->rld
+    = (struct reload *) obstack_alloc (&reload_obstack,
+                                      n_reloads * sizeof (struct reload));
+  memcpy (chain->rld, rld, n_reloads * sizeof (struct reload));
+  reload_insn_firstobj = (char *) obstack_alloc (&reload_obstack, 0);
+}
+
 /* Walk the chain of insns, and determine for each whether it needs reloads
    and/or eliminations.  Build the corresponding insns_need_reload list, and
    set something_needs_elimination as appropriate.  */
@@ -1347,17 +1325,20 @@ calculate_needs_all_insns (global)
      int global;
 {
   struct insn_chain **pprev_reload = &insns_need_reload;
-  struct insn_chain **pchain;
+  struct insn_chain *chain;
 
   something_needs_elimination = 0;
 
-  for (pchain = &reload_insn_chain; *pchain != 0; pchain = &(*pchain)->next)
+  reload_insn_firstobj = (char *) obstack_alloc (&reload_obstack, 0);
+  for (chain = reload_insn_chain; chain != 0; chain = chain->next)
     {
-      rtx insn;
-      struct insn_chain *chain;
+      rtx insn = chain->insn;
 
-      chain = *pchain;
-      insn = chain->insn;
+      /* Clear out the shortcuts.  */
+      chain->n_reloads = 0;
+      chain->need_elim = 0;
+      chain->need_reload = 0;
+      chain->need_operand_change = 0;
 
       /* If this is a label, a JUMP_INSN, or has REG_NOTES (which might
         include REG_LABEL), we need to see what effects this has on the
@@ -1381,14 +1362,7 @@ calculate_needs_all_insns (global)
          if (set && GET_CODE (SET_DEST (set)) == REG
              && reg_renumber[REGNO (SET_DEST (set))] < 0
              && reg_equiv_constant[REGNO (SET_DEST (set))])
-           {
-             /* Must clear out the shortcuts, in case they were set last
-                time through.  */
-             chain->need_elim = 0;
-             chain->need_reload = 0;
-             chain->need_operand_change = 0;
-             continue;
-           }
+           continue;
 
          /* If needed, eliminate any eliminable registers.  */
          if (num_eliminable || num_eliminable_invariants)
@@ -1431,7 +1405,7 @@ calculate_needs_all_insns (global)
          /* Discard any register replacements done.  */
          if (did_elimination)
            {
-             obstack_free (&reload_obstack, reload_firstobj);
+             obstack_free (&reload_obstack, reload_insn_firstobj);
              PATTERN (insn) = old_body;
              INSN_CODE (insn) = old_code;
              REG_NOTES (insn) = old_notes;
@@ -1442,613 +1416,332 @@ calculate_needs_all_insns (global)
 
          if (n_reloads != 0)
            {
+             copy_reloads (chain);
              *pprev_reload = chain;
              pprev_reload = &chain->next_need_reload;
-
-             calculate_needs (chain);
            }
        }
     }
   *pprev_reload = 0;
 }
+\f
+/* Comparison function for qsort to decide which of two reloads
+   should be handled first.  *P1 and *P2 are the reload numbers.  */
 
-/* Compute the most additional registers needed by one instruction,
-   given by CHAIN.  Collect information separately for each class of regs.
-
-   To compute the number of reload registers of each class needed for an
-   insn, we must simulate what choose_reload_regs can do.  We do this by
-   splitting an insn into an "input" and an "output" part.  RELOAD_OTHER
-   reloads are used in both.  The input part uses those reloads,
-   RELOAD_FOR_INPUT reloads, which must be live over the entire input section
-   of reloads, and the maximum of all the RELOAD_FOR_INPUT_ADDRESS and
-   RELOAD_FOR_OPERAND_ADDRESS reloads, which conflict with the inputs.
-
-   The registers needed for output are RELOAD_OTHER and RELOAD_FOR_OUTPUT,
-   which are live for the entire output portion, and the maximum of all the
-   RELOAD_FOR_OUTPUT_ADDRESS reloads for each operand.
-
-   The total number of registers needed is the maximum of the
-   inputs and outputs.  */
-
-static void
-calculate_needs (chain)
-     struct insn_chain *chain;
+static int
+reload_reg_class_lower (r1p, r2p)
+     const PTR r1p;
+     const PTR r2p;
 {
-  int i;
-
-  /* Each `struct needs' corresponds to one RELOAD_... type.  */
-  struct {
-    struct needs other;
-    struct needs input;
-    struct needs output;
-    struct needs insn;
-    struct needs other_addr;
-    struct needs op_addr;
-    struct needs op_addr_reload;
-    struct needs in_addr[MAX_RECOG_OPERANDS];
-    struct needs in_addr_addr[MAX_RECOG_OPERANDS];
-    struct needs out_addr[MAX_RECOG_OPERANDS];
-    struct needs out_addr_addr[MAX_RECOG_OPERANDS];
-  } insn_needs;
-
-  bzero ((char *) chain->group_size, sizeof chain->group_size);
-  for (i = 0; i < N_REG_CLASSES; i++)
-    chain->group_mode[i] = VOIDmode;
-  bzero ((char *) &insn_needs, sizeof insn_needs);
-
-  /* Count each reload once in every class
-     containing the reload's own class.  */
-
-  for (i = 0; i < n_reloads; i++)
-    {
-      register enum reg_class *p;
-      enum reg_class class = reload_reg_class[i];
-      int size;
-      enum machine_mode mode;
-      struct needs *this_needs;
-
-      /* Don't count the dummy reloads, for which one of the
-        regs mentioned in the insn can be used for reloading.
-        Don't count optional reloads.
-        Don't count reloads that got combined with others.  */
-      if (reload_reg_rtx[i] != 0
-         || reload_optional[i] != 0
-         || (reload_out[i] == 0 && reload_in[i] == 0
-             && ! reload_secondary_p[i]))
-       continue;
-
-      mode = reload_inmode[i];
-      if (GET_MODE_SIZE (reload_outmode[i]) > GET_MODE_SIZE (mode))
-       mode = reload_outmode[i];
-      size = CLASS_MAX_NREGS (class, mode);
+  register int r1 = *(short *)r1p, r2 = *(short *)r2p;
+  register int t;
 
-      /* Decide which time-of-use to count this reload for.  */
-      switch (reload_when_needed[i])
-       {
-       case RELOAD_OTHER:
-         this_needs = &insn_needs.other;
-         break;
-       case RELOAD_FOR_INPUT:
-         this_needs = &insn_needs.input;
-         break;
-       case RELOAD_FOR_OUTPUT:
-         this_needs = &insn_needs.output;
-         break;
-       case RELOAD_FOR_INSN:
-         this_needs = &insn_needs.insn;
-         break;
-       case RELOAD_FOR_OTHER_ADDRESS:
-         this_needs = &insn_needs.other_addr;
-         break;
-       case RELOAD_FOR_INPUT_ADDRESS:
-         this_needs = &insn_needs.in_addr[reload_opnum[i]];
-         break;
-       case RELOAD_FOR_INPADDR_ADDRESS:
-         this_needs = &insn_needs.in_addr_addr[reload_opnum[i]];
-         break;
-       case RELOAD_FOR_OUTPUT_ADDRESS:
-         this_needs = &insn_needs.out_addr[reload_opnum[i]];
-         break;
-       case RELOAD_FOR_OUTADDR_ADDRESS:
-         this_needs = &insn_needs.out_addr_addr[reload_opnum[i]];
-         break;
-       case RELOAD_FOR_OPERAND_ADDRESS:
-         this_needs = &insn_needs.op_addr;
-         break;
-       case RELOAD_FOR_OPADDR_ADDR:
-         this_needs = &insn_needs.op_addr_reload;
-         break;
-       default:
-         abort();
-       }
+  /* Consider required reloads before optional ones.  */
+  t = rld[r1].optional - rld[r2].optional;
+  if (t != 0)
+    return t;
 
-      if (size > 1)
-       {
-         enum machine_mode other_mode, allocate_mode;
-
-         /* Count number of groups needed separately from
-            number of individual regs needed.  */
-         this_needs->groups[(int) class]++;
-         p = reg_class_superclasses[(int) class];
-         while (*p != LIM_REG_CLASSES)
-           this_needs->groups[(int) *p++]++;
-
-         /* Record size and mode of a group of this class.  */
-         /* If more than one size group is needed,
-            make all groups the largest needed size.  */
-         if (chain->group_size[(int) class] < size)
-           {
-             other_mode = chain->group_mode[(int) class];
-             allocate_mode = mode;
+  /* Count all solitary classes before non-solitary ones.  */
+  t = ((reg_class_size[(int) rld[r2].class] == 1)
+       - (reg_class_size[(int) rld[r1].class] == 1));
+  if (t != 0)
+    return t;
 
-             chain->group_size[(int) class] = size;
-             chain->group_mode[(int) class] = mode;
-           }
-         else
-           {
-             other_mode = mode;
-             allocate_mode = chain->group_mode[(int) class];
-           }
+  /* Aside from solitaires, consider all multi-reg groups first.  */
+  t = rld[r2].nregs - rld[r1].nregs;
+  if (t != 0)
+    return t;
 
-         /* Crash if two dissimilar machine modes both need
-            groups of consecutive regs of the same class.  */
+  /* Consider reloads in order of increasing reg-class number.  */
+  t = (int) rld[r1].class - (int) rld[r2].class;
+  if (t != 0)
+    return t;
 
-         if (other_mode != VOIDmode && other_mode != allocate_mode
-             && ! modes_equiv_for_class_p (allocate_mode,
-                                           other_mode, class))
-           fatal_insn ("Two dissimilar machine modes both need groups of consecutive regs of the same class",
-                       chain->insn);
-       }
-      else if (size == 1)
-       {
-         this_needs->regs[(unsigned char)reload_nongroup[i]][(int) class] += 1;
-         p = reg_class_superclasses[(int) class];
-         while (*p != LIM_REG_CLASSES)
-           this_needs->regs[(unsigned char)reload_nongroup[i]][(int) *p++] += 1;
-       }
-      else
-       abort ();
-    }
+  /* If reloads are equally urgent, sort by reload number,
+     so that the results of qsort leave nothing to chance.  */
+  return r1 - r2;
+}
+\f
+/* The cost of spilling each hard reg.  */
+static int spill_cost[FIRST_PSEUDO_REGISTER];
 
-  /* All reloads have been counted for this insn;
-     now merge the various times of use.
-     This sets insn_needs, etc., to the maximum total number
-     of registers needed at any point in this insn.  */
+/* When spilling multiple hard registers, we use SPILL_COST for the first
+   spilled hard reg and SPILL_ADD_COST for subsequent regs.  SPILL_ADD_COST
+   only the first hard reg for a multi-reg pseudo.  */
+static int spill_add_cost[FIRST_PSEUDO_REGISTER];
 
-  for (i = 0; i < N_REG_CLASSES; i++)
-    {
-      int j, in_max, out_max;
+/* Update the spill cost arrays, considering that pseudo REG is live.  */
+static void
+count_pseudo (reg)
+     int reg;
+{
+  int n_refs = REG_N_REFS (reg);
+  int r = reg_renumber[reg];
+  int nregs;
 
-      /* Compute normal and nongroup needs.  */
-      for (j = 0; j <= 1; j++)
-       {
-         int k;
-         for (in_max = 0, out_max = 0, k = 0; k < reload_n_operands; k++)
-           {
-             in_max = MAX (in_max,
-                           (insn_needs.in_addr[k].regs[j][i]
-                            + insn_needs.in_addr_addr[k].regs[j][i]));
-             out_max = MAX (out_max, insn_needs.out_addr[k].regs[j][i]);
-             out_max = MAX (out_max,
-                            insn_needs.out_addr_addr[k].regs[j][i]);
-           }
+  if (REGNO_REG_SET_P (&pseudos_counted, reg)
+      || REGNO_REG_SET_P (&spilled_pseudos, reg))
+    return;
 
-         /* RELOAD_FOR_INSN reloads conflict with inputs, outputs,
-            and operand addresses but not things used to reload
-            them.  Similarly, RELOAD_FOR_OPERAND_ADDRESS reloads
-            don't conflict with things needed to reload inputs or
-            outputs.  */
+  SET_REGNO_REG_SET (&pseudos_counted, reg);
 
-         in_max = MAX (MAX (insn_needs.op_addr.regs[j][i],
-                            insn_needs.op_addr_reload.regs[j][i]),
-                       in_max);
+  if (r < 0)
+    abort ();
+  
+  spill_add_cost[r] += n_refs;
 
-         out_max = MAX (out_max, insn_needs.insn.regs[j][i]);
+  nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (reg));
+  while (nregs-- > 0)
+    spill_cost[r + nregs] += n_refs;
+}
 
-         insn_needs.input.regs[j][i]
-           = MAX (insn_needs.input.regs[j][i]
-                  + insn_needs.op_addr.regs[j][i]
-                  + insn_needs.insn.regs[j][i],
-                  in_max + insn_needs.input.regs[j][i]);
+/* Calculate the SPILL_COST and SPILL_ADD_COST arrays and determine the
+   contents of BAD_SPILL_REGS for the insn described by CHAIN.  */
+static void
+order_regs_for_reload (chain)
+     struct insn_chain *chain;
+{
+  register int i, j;
 
-         insn_needs.output.regs[j][i] += out_max;
-         insn_needs.other.regs[j][i]
-           += MAX (MAX (insn_needs.input.regs[j][i],
-                        insn_needs.output.regs[j][i]),
-                   insn_needs.other_addr.regs[j][i]);
+  COPY_HARD_REG_SET (bad_spill_regs, bad_spill_regs_global);
 
-       }
+  memset (spill_cost, 0, sizeof spill_cost);
+  memset (spill_add_cost, 0, sizeof spill_add_cost);
 
-      /* Now compute group needs.  */
-      for (in_max = 0, out_max = 0, j = 0; j < reload_n_operands; j++)
-       {
-         in_max = MAX (in_max, insn_needs.in_addr[j].groups[i]);
-         in_max = MAX (in_max, insn_needs.in_addr_addr[j].groups[i]);
-         out_max = MAX (out_max, insn_needs.out_addr[j].groups[i]);
-         out_max = MAX (out_max, insn_needs.out_addr_addr[j].groups[i]);
-       }
+  /* Count number of uses of each hard reg by pseudo regs allocated to it
+     and then order them by decreasing use.  */
 
-      in_max = MAX (MAX (insn_needs.op_addr.groups[i],
-                        insn_needs.op_addr_reload.groups[i]),
-                   in_max);
-      out_max = MAX (out_max, insn_needs.insn.groups[i]);
-
-      insn_needs.input.groups[i]
-       = MAX (insn_needs.input.groups[i]
-              + insn_needs.op_addr.groups[i]
-              + insn_needs.insn.groups[i],
-              in_max + insn_needs.input.groups[i]);
-
-      insn_needs.output.groups[i] += out_max;
-      insn_needs.other.groups[i]
-       += MAX (MAX (insn_needs.input.groups[i],
-                    insn_needs.output.groups[i]),
-               insn_needs.other_addr.groups[i]);
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    {
+      /* Test the various reasons why we can't use a register for
+        spilling in this insn.  */
+      if (fixed_regs[i]
+         || REGNO_REG_SET_P (chain->live_throughout, i)
+         || REGNO_REG_SET_P (chain->dead_or_set, i))
+       SET_HARD_REG_BIT (bad_spill_regs, i);
     }
+  /* Now find out which pseudos are allocated to it, and update
+     hard_reg_n_uses.  */
+  CLEAR_REG_SET (&pseudos_counted);
 
-  /* Record the needs for later.  */
-  chain->need = insn_needs.other;
+  EXECUTE_IF_SET_IN_REG_SET
+    (chain->live_throughout, FIRST_PSEUDO_REGISTER, j,
+     {
+       count_pseudo (j);
+     });
+  EXECUTE_IF_SET_IN_REG_SET
+    (chain->dead_or_set, FIRST_PSEUDO_REGISTER, j,
+     {
+       count_pseudo (j);
+     });
+  CLEAR_REG_SET (&pseudos_counted);
 }
 \f
-/* Find a group of exactly 2 registers.
-
-   First try to fill out the group by spilling a single register which
-   would allow completion of the group.
-
-   Then try to create a new group from a pair of registers, neither of
-   which are explicitly used.
+/* Vector of reload-numbers showing the order in which the reloads should
+   be processed.  */
+static short reload_order[MAX_RELOADS];
 
-   Then try to create a group from any pair of registers.  */
+/* This is used to keep track of the spill regs used in one insn.  */
+static HARD_REG_SET used_spill_regs_local;
 
+/* We decided to spill hard register SPILLED, which has a size of
+   SPILLED_NREGS.  Determine how pseudo REG, which is live during the insn,
+   is affected.  We will add it to SPILLED_PSEUDOS if necessary, and we will
+   update SPILL_COST/SPILL_ADD_COST.  */
 static void
-find_tworeg_group (chain, class, dumpfile)
-     struct insn_chain *chain;
-     int class;
-     FILE *dumpfile;
+count_spilled_pseudo (spilled, spilled_nregs, reg)
+     int spilled, spilled_nregs, reg;
 {
-  int i;
-  /* First, look for a register that will complete a group.  */
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    {
-      int j, other;
-
-      j = potential_reload_regs[i];
-      if (j >= 0 && ! TEST_HARD_REG_BIT (bad_spill_regs, j)
-         && ((j > 0 && (other = j - 1, spill_reg_order[other] >= 0)
-              && TEST_HARD_REG_BIT (reg_class_contents[class], j)
-              && TEST_HARD_REG_BIT (reg_class_contents[class], other)
-              && HARD_REGNO_MODE_OK (other, chain->group_mode[class])
-              && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, other)
-              /* We don't want one part of another group.
-                 We could get "two groups" that overlap!  */
-              && ! TEST_HARD_REG_BIT (chain->counted_for_groups, other))
-             || (j < FIRST_PSEUDO_REGISTER - 1
-                 && (other = j + 1, spill_reg_order[other] >= 0)
-                 && TEST_HARD_REG_BIT (reg_class_contents[class], j)
-                 && TEST_HARD_REG_BIT (reg_class_contents[class], other)
-                 && HARD_REGNO_MODE_OK (j, chain->group_mode[class])
-                 && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, other)
-                 && ! TEST_HARD_REG_BIT (chain->counted_for_groups, other))))
-       {
-         register enum reg_class *p;
-
-         /* We have found one that will complete a group,
-            so count off one group as provided.  */
-         chain->need.groups[class]--;
-         p = reg_class_superclasses[class];
-         while (*p != LIM_REG_CLASSES)
-           {
-             if (chain->group_size [(int) *p] <= chain->group_size [class])
-               chain->need.groups[(int) *p]--;
-             p++;
-           }
+  int r = reg_renumber[reg];
+  int nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (reg));
 
-         /* Indicate both these regs are part of a group.  */
-         SET_HARD_REG_BIT (chain->counted_for_groups, j);
-         SET_HARD_REG_BIT (chain->counted_for_groups, other);
-         break;
-       }
-    }
-  /* We can't complete a group, so start one.  */
-  if (i == FIRST_PSEUDO_REGISTER)
-    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-      {
-       int j, k;
-       j = potential_reload_regs[i];
-       /* Verify that J+1 is a potential reload reg.  */
-       for (k = 0; k < FIRST_PSEUDO_REGISTER; k++)
-         if (potential_reload_regs[k] == j + 1)
-           break;
-       if (j >= 0 && j + 1 < FIRST_PSEUDO_REGISTER
-           && k < FIRST_PSEUDO_REGISTER
-           && spill_reg_order[j] < 0 && spill_reg_order[j + 1] < 0
-           && TEST_HARD_REG_BIT (reg_class_contents[class], j)
-           && TEST_HARD_REG_BIT (reg_class_contents[class], j + 1)
-           && HARD_REGNO_MODE_OK (j, chain->group_mode[class])
-           && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, j + 1)
-           && ! TEST_HARD_REG_BIT (bad_spill_regs, j + 1))
-         break;
-      }
+  if (REGNO_REG_SET_P (&spilled_pseudos, reg)
+      || spilled + spilled_nregs <= r || r + nregs <= spilled)
+    return;
 
-  /* I should be the index in potential_reload_regs
-     of the new reload reg we have found.  */
+  SET_REGNO_REG_SET (&spilled_pseudos, reg);
 
-  new_spill_reg (chain, i, class, 0, dumpfile);
+  spill_add_cost[r] -= REG_N_REFS (reg);
+  while (nregs-- > 0)
+    spill_cost[r + nregs] -= REG_N_REFS (reg);
 }
 
-/* Find a group of more than 2 registers.
-   Look for a sufficient sequence of unspilled registers, and spill them all
-   at once.  */
+/* Find reload register to use for reload number ORDER.  */
 
-static void
-find_group (chain, class, dumpfile)
+static int
+find_reg (chain, order, dumpfile)
      struct insn_chain *chain;
-     int class;
+     int order;
      FILE *dumpfile;
 {
-  int i;
+  int rnum = reload_order[order];
+  struct reload *rl = rld + rnum;
+  int best_cost = INT_MAX;
+  int best_reg = -1;
+  int i, j;
+  HARD_REG_SET not_usable;
+  HARD_REG_SET used_by_other_reload;
 
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+  COPY_HARD_REG_SET (not_usable, bad_spill_regs);
+  IOR_HARD_REG_SET (not_usable, bad_spill_regs_global);
+  IOR_COMPL_HARD_REG_SET (not_usable, reg_class_contents[rl->class]);
+
+  CLEAR_HARD_REG_SET (used_by_other_reload);
+  for (i = 0; i < order; i++)
     {
-      int j = potential_reload_regs[i];
+      int other = reload_order[i];
+      if (rld[other].regno >= 0 && reloads_conflict (other, rnum))
+       for (j = 0; j < rld[other].nregs; j++)
+         SET_HARD_REG_BIT (used_by_other_reload, rld[other].regno + j);
+    }
 
-      if (j >= 0
-         && j + chain->group_size[class] <= FIRST_PSEUDO_REGISTER
-         && HARD_REGNO_MODE_OK (j, chain->group_mode[class]))
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    {
+      int regno = i;
+      if (! TEST_HARD_REG_BIT (not_usable, regno)
+         && ! TEST_HARD_REG_BIT (used_by_other_reload, regno)
+         && HARD_REGNO_MODE_OK (regno, rl->mode))
        {
-         int k;
-         /* Check each reg in the sequence.  */
-         for (k = 0; k < chain->group_size[class]; k++)
-           if (! (spill_reg_order[j + k] < 0
-                  && ! TEST_HARD_REG_BIT (bad_spill_regs, j + k)
-                  && TEST_HARD_REG_BIT (reg_class_contents[class], j + k)))
-             break;
-         /* We got a full sequence, so spill them all.  */
-         if (k == chain->group_size[class])
-           {
-             register enum reg_class *p;
-             for (k = 0; k < chain->group_size[class]; k++)
-               {
-                 int idx;
-                 SET_HARD_REG_BIT (chain->counted_for_groups, j + k);
-                 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
-                   if (potential_reload_regs[idx] == j + k)
-                     break;
-                 new_spill_reg (chain, idx, class, 0, dumpfile);
-               }
+         int this_cost = spill_cost[regno];
+         int ok = 1;
+         int this_nregs = HARD_REGNO_NREGS (regno, rl->mode);
 
-             /* We have found one that will complete a group,
-                so count off one group as provided.  */
-             chain->need.groups[class]--;
-             p = reg_class_superclasses[class];
-             while (*p != LIM_REG_CLASSES)
-               {
-                 if (chain->group_size [(int) *p]
-                     <= chain->group_size [class])
-                   chain->need.groups[(int) *p]--;
-                 p++;
-               }
-             return;
+         for (j = 1; j < this_nregs; j++)
+           {
+             this_cost += spill_add_cost[regno + j];
+             if ((TEST_HARD_REG_BIT (not_usable, regno + j))
+                 || TEST_HARD_REG_BIT (used_by_other_reload, regno + j))
+               ok = 0;
+           }
+         if (! ok)
+           continue;
+         if (rl->in && GET_CODE (rl->in) == REG && REGNO (rl->in) == regno)
+           this_cost--;
+         if (rl->out && GET_CODE (rl->out) == REG && REGNO (rl->out) == regno)
+           this_cost--;
+         if (this_cost < best_cost
+             /* Among registers with equal cost, prefer caller-saved ones, or
+                use REG_ALLOC_ORDER if it is defined.  */
+             || (this_cost == best_cost
+#ifdef REG_ALLOC_ORDER
+                 && (inv_reg_alloc_order[regno]
+                     < inv_reg_alloc_order[best_reg])
+#else
+                 && call_used_regs[regno]
+                 && ! call_used_regs[best_reg]
+#endif
+                 ))
+           {
+             best_reg = regno;
+             best_cost = this_cost;
            }
        }
     }
-  /* There are no groups left.  */
-  spill_failure (chain->insn);
-  failure = 1;
-}
+  if (best_reg == -1)
+    return 0;
+  if (dumpfile)
+    fprintf (dumpfile, "Using reg %d for reload %d\n", best_reg, rnum);
+  rl->nregs = HARD_REGNO_NREGS (best_reg, rl->mode);
+  rl->regno = best_reg;
 
-/* If pseudo REG conflicts with one of our reload registers, mark it as
-   spilled.  */
-static void
-maybe_mark_pseudo_spilled (reg)
-     int reg;
-{
-  int i;
-  int r = reg_renumber[reg];
-  int nregs;
+  EXECUTE_IF_SET_IN_REG_SET
+    (chain->live_throughout, FIRST_PSEUDO_REGISTER, j,
+     {
+       count_spilled_pseudo (best_reg, rl->nregs, j);
+     });
+  EXECUTE_IF_SET_IN_REG_SET
+    (chain->dead_or_set, FIRST_PSEUDO_REGISTER, j,
+     {
+       count_spilled_pseudo (best_reg, rl->nregs, j);
+     });
 
-  if (r < 0)
-    abort ();
-  nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (reg));
-  for (i = 0; i < n_spills; i++)
-    if (r <= spill_regs[i] && r + nregs > spill_regs[i])
-      {
-       SET_REGNO_REG_SET (spilled_pseudos, reg);
-       return;
-      }
+  for (i = 0; i < rl->nregs; i++)
+    {
+      if (spill_cost[best_reg + i] != 0
+         || spill_add_cost[best_reg + i] != 0)
+       abort ();
+      SET_HARD_REG_BIT (used_spill_regs_local, best_reg + i);
+    }
+  return 1;
 }
 
 /* Find more reload regs to satisfy the remaining need of an insn, which
    is given by CHAIN.
    Do it by ascending class number, since otherwise a reg
    might be spilled for a big class and might fail to count
-   for a smaller class even though it belongs to that class.
-
-   Count spilled regs in `spills', and add entries to
-   `spill_regs' and `spill_reg_order'.
-
-   ??? Note there is a problem here.
-   When there is a need for a group in a high-numbered class,
-   and also need for non-group regs that come from a lower class,
-   the non-group regs are chosen first.  If there aren't many regs,
-   they might leave no room for a group.
-
-   This was happening on the 386.  To fix it, we added the code
-   that calls possible_group_p, so that the lower class won't
-   break up the last possible group.
-
-   Really fixing the problem would require changes above
-   in counting the regs already spilled, and in choose_reload_regs.
-   It might be hard to avoid introducing bugs there.  */
+   for a smaller class even though it belongs to that class.  */
 
 static void
 find_reload_regs (chain, dumpfile)
      struct insn_chain *chain;
      FILE *dumpfile;
 {
-  int i, class;
-  short *group_needs = chain->need.groups;
-  short *simple_needs = chain->need.regs[0];
-  short *nongroup_needs = chain->need.regs[1];
+  int i;
+
+  /* In order to be certain of getting the registers we need,
+     we must sort the reloads into order of increasing register class.
+     Then our grabbing of reload registers will parallel the process
+     that provided the reload registers.  */
+  for (i = 0; i < chain->n_reloads; i++)
+    {
+      /* Show whether this reload already has a hard reg.  */
+      if (chain->rld[i].reg_rtx)
+       {
+         int regno = REGNO (chain->rld[i].reg_rtx);
+         chain->rld[i].regno = regno;
+         chain->rld[i].nregs = HARD_REGNO_NREGS (regno, GET_MODE (chain->rld[i].reg_rtx));
+       }
+      else
+       chain->rld[i].regno = -1;
+      reload_order[i] = i;
+    }
+
+  n_reloads = chain->n_reloads;
+  memcpy (rld, chain->rld, n_reloads * sizeof (struct reload));
+
+  CLEAR_HARD_REG_SET (used_spill_regs_local);
 
   if (dumpfile)
     fprintf (dumpfile, "Spilling for insn %d.\n", INSN_UID (chain->insn));
 
-  /* Compute the order of preference for hard registers to spill.
-     Store them by decreasing preference in potential_reload_regs.  */
-
-  order_regs_for_reload (chain);
+  qsort (reload_order, n_reloads, sizeof (short), reload_reg_class_lower);
 
-  /* So far, no hard regs have been spilled.  */
-  n_spills = 0;
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    spill_reg_order[i] = -1;
+  /* Compute the order of preference for hard registers to spill.  */
 
-  CLEAR_HARD_REG_SET (chain->used_spill_regs);
-  CLEAR_HARD_REG_SET (chain->counted_for_groups);
-  CLEAR_HARD_REG_SET (chain->counted_for_nongroups);
+  order_regs_for_reload (chain);
 
-  for (class = 0; class < N_REG_CLASSES; class++)
+  for (i = 0; i < n_reloads; i++)
     {
-      /* First get the groups of registers.
-        If we got single registers first, we might fragment
-        possible groups.  */
-      while (group_needs[class] > 0)
-       {
-         /* If any single spilled regs happen to form groups,
-            count them now.  Maybe we don't really need
-            to spill another group.  */
-         count_possible_groups (chain, class);
+      int r = reload_order[i];
 
-         if (group_needs[class] <= 0)
-           break;
-
-         /* Groups of size 2, the only groups used on most machines,
-            are treated specially.  */
-         if (chain->group_size[class] == 2)
-           find_tworeg_group (chain, class, dumpfile);
-         else
-           find_group (chain, class, dumpfile);
-         if (failure)
+      /* Ignore reloads that got marked inoperative.  */
+      if ((rld[r].out != 0 || rld[r].in != 0 || rld[r].secondary_p)
+         && ! rld[r].optional
+         && rld[r].regno == -1)
+       if (! find_reg (chain, i, dumpfile))
+         {
+           spill_failure (chain->insn, rld[r].class);
+           failure = 1;
            return;
-       }
-
-      /* Now similarly satisfy all need for single registers.  */
-
-      while (simple_needs[class] > 0 || nongroup_needs[class] > 0)
-       {
-         /* If we spilled enough regs, but they weren't counted
-            against the non-group need, see if we can count them now.
-            If so, we can avoid some actual spilling.  */
-         if (simple_needs[class] <= 0 && nongroup_needs[class] > 0)
-           for (i = 0; i < n_spills; i++)
-             {
-               int regno = spill_regs[i];
-               if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
-                   && !TEST_HARD_REG_BIT (chain->counted_for_groups, regno)
-                   && !TEST_HARD_REG_BIT (chain->counted_for_nongroups, regno)
-                   && nongroup_needs[class] > 0)
-                 {
-                   register enum reg_class *p;
-
-                   SET_HARD_REG_BIT (chain->counted_for_nongroups, regno);
-                   nongroup_needs[class]--;
-                   p = reg_class_superclasses[class];
-                   while (*p != LIM_REG_CLASSES)
-                     nongroup_needs[(int) *p++]--;
-                 }
-             }
-
-         if (simple_needs[class] <= 0 && nongroup_needs[class] <= 0)
-           break;
-
-         /* Consider the potential reload regs that aren't
-            yet in use as reload regs, in order of preference.
-            Find the most preferred one that's in this class.  */
-
-         for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-           {
-             int regno = potential_reload_regs[i];
-             if (regno >= 0
-                 && TEST_HARD_REG_BIT (reg_class_contents[class], regno)
-                 /* If this reg will not be available for groups,
-                    pick one that does not foreclose possible groups.
-                    This is a kludge, and not very general,
-                    but it should be sufficient to make the 386 work,
-                    and the problem should not occur on machines with
-                    more registers.  */
-                 && (nongroup_needs[class] == 0
-                     || possible_group_p (chain, regno)))
-               break;
-           }
-
-         /* If we couldn't get a register, try to get one even if we
-            might foreclose possible groups.  This may cause problems
-            later, but that's better than aborting now, since it is
-            possible that we will, in fact, be able to form the needed
-            group even with this allocation.  */
-
-         if (i >= FIRST_PSEUDO_REGISTER
-             && asm_noperands (chain->insn) < 0)
-           for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-             if (potential_reload_regs[i] >= 0
-                 && TEST_HARD_REG_BIT (reg_class_contents[class],
-                                       potential_reload_regs[i]))
-               break;
-
-         /* I should be the index in potential_reload_regs
-            of the new reload reg we have found.  */
-
-         new_spill_reg (chain, i, class, 1, dumpfile);
-         if (failure)
-           return;
-       }
+         }
     }
 
-  /* We know which hard regs to use, now mark the pseudos that live in them
-     as needing to be kicked out.  */
-  EXECUTE_IF_SET_IN_REG_SET
-    (chain->live_before, FIRST_PSEUDO_REGISTER, i,
-     {
-       maybe_mark_pseudo_spilled (i);
-     });
-  EXECUTE_IF_SET_IN_REG_SET
-    (chain->live_after, FIRST_PSEUDO_REGISTER, i,
-     {
-       maybe_mark_pseudo_spilled (i);
-     });
+  COPY_HARD_REG_SET (chain->used_spill_regs, used_spill_regs_local);
+  IOR_HARD_REG_SET (used_spill_regs, used_spill_regs_local);
 
-  IOR_HARD_REG_SET (used_spill_regs, chain->used_spill_regs);
+  memcpy (chain->rld, rld, n_reloads * sizeof (struct reload));
 }
 
-void
-dump_needs (chain, dumpfile)
-     struct insn_chain *chain;
+static void
+select_reload_regs (dumpfile)
      FILE *dumpfile;
 {
-  static const char * const reg_class_names[] = REG_CLASS_NAMES;
-  int i;
-  struct needs *n = &chain->need;
+  struct insn_chain *chain;
 
-  for (i = 0; i < N_REG_CLASSES; i++)
-    {
-      if (n->regs[i][0] > 0)
-       fprintf (dumpfile,
-                ";; Need %d reg%s of class %s.\n",
-                n->regs[i][0], n->regs[i][0] == 1 ? "" : "s",
-                reg_class_names[i]);
-      if (n->regs[i][1] > 0)
-       fprintf (dumpfile,
-                ";; Need %d nongroup reg%s of class %s.\n",
-                n->regs[i][1], n->regs[i][1] == 1 ? "" : "s",
-                reg_class_names[i]);
-      if (n->groups[i] > 0)
-       fprintf (dumpfile,
-                ";; Need %d group%s (%smode) of class %s.\n",
-                n->groups[i], n->groups[i] == 1 ? "" : "s",
-                GET_MODE_NAME(chain->group_mode[i]),
-                reg_class_names[i]);
-    }
+  /* Try to satisfy the needs for each insn.  */
+  for (chain = insns_need_reload; chain != 0;
+       chain = chain->next_need_reload)
+    find_reload_regs (chain, dumpfile);
 }
 \f
 /* Delete all insns that were inserted by emit_caller_save_insns during
@@ -2090,250 +1783,24 @@ delete_caller_save_insns ()
     }
 }
 \f
-/* Nonzero if, after spilling reg REGNO for non-groups,
-   it will still be possible to find a group if we still need one.  */
-
-static int
-possible_group_p (chain, regno)
-     struct insn_chain *chain;
-     int regno;
-{
-  int i;
-  int class = (int) NO_REGS;
-
-  for (i = 0; i < (int) N_REG_CLASSES; i++)
-    if (chain->need.groups[i] > 0)
-      {
-       class = i;
-       break;
-      }
-
-  if (class == (int) NO_REGS)
-    return 1;
-
-  /* Consider each pair of consecutive registers.  */
-  for (i = 0; i < FIRST_PSEUDO_REGISTER - 1; i++)
-    {
-      /* Ignore pairs that include reg REGNO.  */
-      if (i == regno || i + 1 == regno)
-       continue;
-
-      /* Ignore pairs that are outside the class that needs the group.
-        ??? Here we fail to handle the case where two different classes
-        independently need groups.  But this never happens with our
-        current machine descriptions.  */
-      if (! (TEST_HARD_REG_BIT (reg_class_contents[class], i)
-            && TEST_HARD_REG_BIT (reg_class_contents[class], i + 1)))
-       continue;
-
-      /* A pair of consecutive regs we can still spill does the trick.  */
-      if (spill_reg_order[i] < 0 && spill_reg_order[i + 1] < 0
-         && ! TEST_HARD_REG_BIT (bad_spill_regs, i)
-         && ! TEST_HARD_REG_BIT (bad_spill_regs, i + 1))
-       return 1;
-
-      /* A pair of one already spilled and one we can spill does it
-        provided the one already spilled is not otherwise reserved.  */
-      if (spill_reg_order[i] < 0
-         && ! TEST_HARD_REG_BIT (bad_spill_regs, i)
-         && spill_reg_order[i + 1] >= 0
-         && ! TEST_HARD_REG_BIT (chain->counted_for_groups, i + 1)
-         && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, i + 1))
-       return 1;
-      if (spill_reg_order[i + 1] < 0
-         && ! TEST_HARD_REG_BIT (bad_spill_regs, i + 1)
-         && spill_reg_order[i] >= 0
-         && ! TEST_HARD_REG_BIT (chain->counted_for_groups, i)
-         && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, i))
-       return 1;
-    }
-
-  return 0;
-}
-
-/* Count any groups of CLASS that can be formed from the registers recently
-   spilled.  */
-
-static void
-count_possible_groups (chain, class)
-     struct insn_chain *chain;
-     int class;
-{
-  HARD_REG_SET new;
-  int i, j;
-
-  /* Now find all consecutive groups of spilled registers
-     and mark each group off against the need for such groups.
-     But don't count them against ordinary need, yet.  */
-
-  if (chain->group_size[class] == 0)
-    return;
-
-  CLEAR_HARD_REG_SET (new);
-
-  /* Make a mask of all the regs that are spill regs in class I.  */
-  for (i = 0; i < n_spills; i++)
-    {
-      int regno = spill_regs[i];
-
-      if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
-         && ! TEST_HARD_REG_BIT (chain->counted_for_groups, regno)
-         && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, regno))
-       SET_HARD_REG_BIT (new, regno);
-    }
-
-  /* Find each consecutive group of them.  */
-  for (i = 0; i < FIRST_PSEUDO_REGISTER && chain->need.groups[class] > 0; i++)
-    if (TEST_HARD_REG_BIT (new, i)
-       && i + chain->group_size[class] <= FIRST_PSEUDO_REGISTER
-       && HARD_REGNO_MODE_OK (i, chain->group_mode[class]))
-      {
-       for (j = 1; j < chain->group_size[class]; j++)
-         if (! TEST_HARD_REG_BIT (new, i + j))
-           break;
-
-       if (j == chain->group_size[class])
-         {
-           /* We found a group.  Mark it off against this class's need for
-              groups, and against each superclass too.  */
-           register enum reg_class *p;
-
-           chain->need.groups[class]--;
-           p = reg_class_superclasses[class];
-           while (*p != LIM_REG_CLASSES)
-             {
-               if (chain->group_size [(int) *p] <= chain->group_size [class])
-                 chain->need.groups[(int) *p]--;
-               p++;
-             }
-
-           /* Don't count these registers again.  */
-           for (j = 0; j < chain->group_size[class]; j++)
-             SET_HARD_REG_BIT (chain->counted_for_groups, i + j);
-         }
-
-       /* Skip to the last reg in this group.  When i is incremented above,
-          it will then point to the first reg of the next possible group.  */
-       i += j - 1;
-      }
-}
-\f
-/* ALLOCATE_MODE is a register mode that needs to be reloaded.  OTHER_MODE is
-   another mode that needs to be reloaded for the same register class CLASS.
-   If any reg in CLASS allows ALLOCATE_MODE but not OTHER_MODE, fail.
-   ALLOCATE_MODE will never be smaller than OTHER_MODE.
-
-   This code used to also fail if any reg in CLASS allows OTHER_MODE but not
-   ALLOCATE_MODE.  This test is unnecessary, because we will never try to put
-   something of mode ALLOCATE_MODE into an OTHER_MODE register.  Testing this
-   causes unnecessary failures on machines requiring alignment of register
-   groups when the two modes are different sizes, because the larger mode has
-   more strict alignment rules than the smaller mode.  */
-
-static int
-modes_equiv_for_class_p (allocate_mode, other_mode, class)
-     enum machine_mode allocate_mode, other_mode;
-     enum reg_class class;
-{
-  register int regno;
-  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-    {
-      if (TEST_HARD_REG_BIT (reg_class_contents[(int) class], regno)
-         && HARD_REGNO_MODE_OK (regno, allocate_mode)
-         && ! HARD_REGNO_MODE_OK (regno, other_mode))
-       return 0;
-    }
-  return 1;
-}
-\f
 /* Handle the failure to find a register to spill.
    INSN should be one of the insns which needed this particular spill reg.  */
 
 static void
-spill_failure (insn)
+spill_failure (insn, class)
      rtx insn;
+     enum reg_class class;
 {
+  static const char *const reg_class_names[] = REG_CLASS_NAMES;
   if (asm_noperands (PATTERN (insn)) >= 0)
-    error_for_asm (insn, "`asm' needs too many reloads");
+    error_for_asm (insn, "Can't find a register in class `%s' while reloading `asm'.",
+                  reg_class_names[class]);
   else
-    fatal_insn ("Unable to find a register to spill.", insn);
-}
-
-/* Add a new register to the tables of available spill-registers.
-   CHAIN is the insn for which the register will be used; we decrease the
-   needs of that insn.
-   I is the index of this register in potential_reload_regs.
-   CLASS is the regclass whose need is being satisfied.
-   NONGROUP is 0 if this register is part of a group.
-   DUMPFILE is the same as the one that `reload' got.  */
-
-static void
-new_spill_reg (chain, i, class, nongroup, dumpfile)
-     struct insn_chain *chain;
-     int i;
-     int class;
-     int nongroup;
-     FILE *dumpfile;
-{
-  register enum reg_class *p;
-  int regno = potential_reload_regs[i];
-
-  if (i >= FIRST_PSEUDO_REGISTER)
-    {
-      spill_failure (chain->insn);
-      failure = 1;
-      return;
-    }
-
-  if (TEST_HARD_REG_BIT (bad_spill_regs, regno))
-    {
-      static const char * const reg_class_names[] = REG_CLASS_NAMES;
-
-      if (asm_noperands (PATTERN (chain->insn)) < 0)
-       {
-         /* The error message is still correct - we know only that it wasn't
-            an asm statement that caused the problem, but one of the global
-            registers declared by the users might have screwed us.  */
-         error ("fixed or forbidden register %d (%s) was spilled for class %s.",
-                regno, reg_names[regno], reg_class_names[class]);
-         error ("This may be due to a compiler bug or to impossible asm");
-         error ("statements or clauses.");
-         fatal_insn ("This is the instruction:", chain->insn);
-       }
-      error_for_asm (chain->insn, "Invalid `asm' statement:");
-      error_for_asm (chain->insn,
-                    "fixed or forbidden register %d (%s) was spilled for class %s.",
-                    regno, reg_names[regno], reg_class_names[class]);
-      failure = 1;
-      return;
-    }
-
-  /* Make reg REGNO an additional reload reg.  */
-
-  potential_reload_regs[i] = -1;
-  spill_regs[n_spills] = regno;
-  spill_reg_order[regno] = n_spills;
-  if (dumpfile)
-    fprintf (dumpfile, "Spilling reg %d.\n", regno);
-  SET_HARD_REG_BIT (chain->used_spill_regs, regno);
-
-  /* Clear off the needs we just satisfied.  */
-
-  chain->need.regs[0][class]--;
-  p = reg_class_superclasses[class];
-  while (*p != LIM_REG_CLASSES)
-    chain->need.regs[0][(int) *p++]--;
-
-  if (nongroup && chain->need.regs[1][class] > 0)
     {
-      SET_HARD_REG_BIT (chain->counted_for_nongroups, regno);
-      chain->need.regs[1][class]--;
-      p = reg_class_superclasses[class];
-      while (*p != LIM_REG_CLASSES)
-       chain->need.regs[1][(int) *p++]--;
+      error ("Unable to find a register to spill in class `%s'.",
+            reg_class_names[class]);
+      fatal_insn ("This is the insn:", insn);
     }
-
-  n_spills++;
 }
 \f
 /* Delete an unneeded INSN and any previous insns who sole purpose is loading
@@ -2657,11 +2124,6 @@ set_label_offsets (x, insn, initial_p)
     }
 }
 \f
-/* Used for communication between the next two function to properly share
-   the vector for an ASM_OPERANDS.  */
-
-static struct rtvec_def *old_asm_operands_vec, *new_asm_operands_vec;
-
 /* Scan X and replace any eliminable registers (such as fp) with a
    replacement (such as sp), plus an offset.
 
@@ -2681,9 +2143,6 @@ static struct rtvec_def *old_asm_operands_vec, *new_asm_operands_vec;
    This means, do not set ref_outside_mem even if the reference
    is outside of MEMs.
 
-   If we see a modification to a register we know about, take the
-   appropriate action (see case SET, below).
-
    REG_EQUIV_MEM and REG_EQUIV_ADDRESS contain address that have had
    replacements done assuming all offsets are at their initial values.  If
    they are not, or if REG_EQUIV_ADDRESS is nonzero for a pseudo we
@@ -2741,14 +2200,7 @@ eliminate_regs (x, mem_mode, insn)
          for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
               ep++)
            if (ep->from_rtx == x && ep->can_eliminate)
-             {
-               if (! mem_mode
-                   /* Refs inside notes don't count for this purpose.  */
-                   && ! (insn != 0 && (GET_CODE (insn) == EXPR_LIST
-                                       || GET_CODE (insn) == INSN_LIST)))
-                 ep->ref_outside_mem = 1;
-               return plus_constant (ep->to_rtx, ep->previous_offset);
-             }
+             return plus_constant (ep->to_rtx, ep->previous_offset);
 
        }
       else if (reg_renumber[regno] < 0 && reg_equiv_constant
@@ -2783,12 +2235,6 @@ eliminate_regs (x, mem_mode, insn)
               ep++)
            if (ep->from_rtx == XEXP (x, 0) && ep->can_eliminate)
              {
-               if (! mem_mode
-                   /* Refs inside notes don't count for this purpose.  */
-                   && ! (insn != 0 && (GET_CODE (insn) == EXPR_LIST
-                                       || GET_CODE (insn) == INSN_LIST)))
-                 ep->ref_outside_mem = 1;
-
                /* The only time we want to replace a PLUS with a REG (this
                   occurs when the constant operand of the PLUS is the negative
                   of the offset) is when we are inside a MEM.  We won't want
@@ -2815,14 +2261,10 @@ eliminate_regs (x, mem_mode, insn)
         outermost PLUS.  We will do this by doing register replacement in
         our operands and seeing if a constant shows up in one of them.
 
-        We assume here this is part of an address (or a "load address" insn)
-        since an eliminable register is not likely to appear in any other
-        context.
-
-        If we have (plus (eliminable) (reg)), we want to produce
-        (plus (plus (replacement) (reg) (const))).  If this was part of a
-        normal add insn, (plus (replacement) (reg)) will be pushed as a
-        reload.  This is the desired action.  */
+        Note that there is no risk of modifying the structure of the insn,
+        since we only get called for its operands, thus we are either
+        modifying the address inside a MEM, or something like an address
+        operand of a load-address insn.  */
 
       {
        rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn);
@@ -2944,23 +2386,6 @@ eliminate_regs (x, mem_mode, insn)
     case POST_INC:
     case PRE_DEC:
     case POST_DEC:
-      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
-       if (ep->to_rtx == XEXP (x, 0))
-         {
-           int size = GET_MODE_SIZE (mem_mode);
-
-           /* If more bytes than MEM_MODE are pushed, account for them.  */
-#ifdef PUSH_ROUNDING
-           if (ep->to_rtx == stack_pointer_rtx)
-             size = PUSH_ROUNDING (size);
-#endif
-           if (code == PRE_DEC || code == POST_DEC)
-             ep->offset += size;
-           else
-             ep->offset -= size;
-         }
-
-      /* Fall through to generic unary operation case.  */
     case STRICT_LOW_PART:
     case NEG:          case NOT:
     case SIGN_EXTEND:  case ZERO_EXTEND:
@@ -2988,30 +2413,7 @@ eliminate_regs (x, mem_mode, insn)
          && reg_equiv_memory_loc != 0
          && reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0)
        {
-#if 0
-         new = eliminate_regs (reg_equiv_memory_loc[REGNO (SUBREG_REG (x))],
-                               mem_mode, insn);
-
-         /* If we didn't change anything, we must retain the pseudo.  */
-         if (new == reg_equiv_memory_loc[REGNO (SUBREG_REG (x))])
-           new = SUBREG_REG (x);
-         else
-           {
-             /* In this case, we must show that the pseudo is used in this
-                insn so that delete_output_reload will do the right thing.  */
-             if (insn != 0 && GET_CODE (insn) != EXPR_LIST
-                 && GET_CODE (insn) != INSN_LIST)
-               REG_NOTES (emit_insn_before (gen_rtx_USE (VOIDmode,
-                                                         SUBREG_REG (x)),
-                                            insn))
-                 = gen_rtx_EXPR_LIST (REG_EQUAL, new, NULL_RTX);
-
-             /* Ensure NEW isn't shared in case we have to reload it.  */
-             new = copy_rtx (new);
-           }
-#else
          new = SUBREG_REG (x);
-#endif
        }
       else
        new = eliminate_regs (SUBREG_REG (x), mem_mode, insn);
@@ -3055,133 +2457,6 @@ eliminate_regs (x, mem_mode, insn)
 
       return x;
 
-    case USE:
-      /* If using a register that is the source of an eliminate we still
-        think can be performed, note it cannot be performed since we don't
-        know how this register is used.  */
-      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
-       if (ep->from_rtx == XEXP (x, 0))
-         ep->can_eliminate = 0;
-
-      new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
-      if (new != XEXP (x, 0))
-       return gen_rtx_fmt_e (code, GET_MODE (x), new);
-      return x;
-
-    case CLOBBER:
-      /* If clobbering a register that is the replacement register for an
-        elimination we still think can be performed, note that it cannot
-        be performed.  Otherwise, we need not be concerned about it.  */
-      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
-       if (ep->to_rtx == XEXP (x, 0))
-         ep->can_eliminate = 0;
-
-      new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
-      if (new != XEXP (x, 0))
-       return gen_rtx_fmt_e (code, GET_MODE (x), new);
-      return x;
-
-    case ASM_OPERANDS:
-      {
-       rtx *temp_vec;
-       /* Properly handle sharing input and constraint vectors.  */
-       if (ASM_OPERANDS_INPUT_VEC (x) != old_asm_operands_vec)
-         {
-           /* When we come to a new vector not seen before,
-              scan all its elements; keep the old vector if none
-              of them changes; otherwise, make a copy.  */
-           old_asm_operands_vec = ASM_OPERANDS_INPUT_VEC (x);
-           temp_vec = (rtx *) alloca (XVECLEN (x, 3) * sizeof (rtx));
-           for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
-             temp_vec[i] = eliminate_regs (ASM_OPERANDS_INPUT (x, i),
-                                           mem_mode, insn);
-
-           for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
-             if (temp_vec[i] != ASM_OPERANDS_INPUT (x, i))
-               break;
-
-           if (i == ASM_OPERANDS_INPUT_LENGTH (x))
-             new_asm_operands_vec = old_asm_operands_vec;
-           else
-             new_asm_operands_vec
-               = gen_rtvec_v (ASM_OPERANDS_INPUT_LENGTH (x), temp_vec);
-         }
-
-       /* If we had to copy the vector, copy the entire ASM_OPERANDS.  */
-       if (new_asm_operands_vec == old_asm_operands_vec)
-         return x;
-
-       new = gen_rtx_ASM_OPERANDS (VOIDmode, ASM_OPERANDS_TEMPLATE (x),
-                                   ASM_OPERANDS_OUTPUT_CONSTRAINT (x),
-                                   ASM_OPERANDS_OUTPUT_IDX (x),
-                                   new_asm_operands_vec,
-                                   ASM_OPERANDS_INPUT_CONSTRAINT_VEC (x),
-                                   ASM_OPERANDS_SOURCE_FILE (x),
-                                   ASM_OPERANDS_SOURCE_LINE (x));
-       new->volatil = x->volatil;
-       return new;
-      }
-
-    case SET:
-      /* Check for setting a register that we know about.  */
-      if (GET_CODE (SET_DEST (x)) == REG)
-       {
-         /* See if this is setting the replacement register for an
-            elimination.
-
-            If DEST is the hard frame pointer, we do nothing because we
-            assume that all assignments to the frame pointer are for
-            non-local gotos and are being done at a time when they are valid
-            and do not disturb anything else.  Some machines want to
-            eliminate a fake argument pointer (or even a fake frame pointer)
-            with either the real frame or the stack pointer.  Assignments to
-            the hard frame pointer must not prevent this elimination.  */
-
-         for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
-              ep++)
-           if (ep->to_rtx == SET_DEST (x)
-               && SET_DEST (x) != hard_frame_pointer_rtx)
-             {
-               /* If it is being incremented, adjust the offset.  Otherwise,
-                  this elimination can't be done.  */
-               rtx src = SET_SRC (x);
-
-               if (GET_CODE (src) == PLUS
-                   && XEXP (src, 0) == SET_DEST (x)
-                   && GET_CODE (XEXP (src, 1)) == CONST_INT)
-                 ep->offset -= INTVAL (XEXP (src, 1));
-               else
-                 ep->can_eliminate = 0;
-             }
-
-         /* Now check to see we are assigning to a register that can be
-            eliminated.  If so, it must be as part of a PARALLEL, since we
-            will not have been called if this is a single SET.  So indicate
-            that we can no longer eliminate this reg.  */
-         for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
-              ep++)
-           if (ep->from_rtx == SET_DEST (x) && ep->can_eliminate)
-             ep->can_eliminate = 0;
-       }
-
-      /* Now avoid the loop below in this common case.  */
-      {
-       rtx new0 = eliminate_regs (SET_DEST (x), 0, insn);
-       rtx new1 = eliminate_regs (SET_SRC (x), 0, insn);
-
-       /* If SET_DEST changed from a REG to a MEM and INSN is an insn,
-          write a CLOBBER insn.  */
-       if (GET_CODE (SET_DEST (x)) == REG && GET_CODE (new0) == MEM
-           && insn != 0 && GET_CODE (insn) != EXPR_LIST
-           && GET_CODE (insn) != INSN_LIST)
-         emit_insn_after (gen_rtx_CLOBBER (VOIDmode, SET_DEST (x)), insn);
-
-       if (new0 != SET_DEST (x) || new1 != SET_SRC (x))
-         return gen_rtx_SET (VOIDmode, new0, new1);
-      }
-
-      return x;
-
     case MEM:
       /* This is only for the benefit of the debugging backends, which call
         eliminate_regs on DECL_RTL; any ADDRESSOFs in the actual insns are
@@ -3204,6 +2479,12 @@ eliminate_regs (x, mem_mode, insn)
       else
        return x;
 
+    case USE:
+    case CLOBBER:
+    case ASM_OPERANDS:
+    case SET:
+      abort ();
+
     default:
       break;
     }
@@ -3257,15 +2538,239 @@ eliminate_regs (x, mem_mode, insn)
 
   return x;
 }
-\f
-/* Scan INSN and eliminate all eliminable registers in it.
 
-   If REPLACE is nonzero, do the replacement destructively.  Also
-   delete the insn as dead it if it is setting an eliminable register.
+/* Scan rtx X for modifications of elimination target registers.  Update
+   the table of eliminables to reflect the changed state.  MEM_MODE is
+   the mode of an enclosing MEM rtx, or VOIDmode if not within a MEM.  */
 
-   If REPLACE is zero, do all our allocations in reload_obstack.
+static void
+elimination_effects (x, mem_mode)
+     rtx x;
+     enum machine_mode mem_mode;
 
-   If no eliminations were done and this insn doesn't require any elimination
+{
+  enum rtx_code code = GET_CODE (x);
+  struct elim_table *ep;
+  int regno;
+  int i, j;
+  const char *fmt;
+
+  switch (code)
+    {
+    case CONST_INT:
+    case CONST_DOUBLE:
+    case CONST:
+    case SYMBOL_REF:
+    case CODE_LABEL:
+    case PC:
+    case CC0:
+    case ASM_INPUT:
+    case ADDR_VEC:
+    case ADDR_DIFF_VEC:
+    case RETURN:
+      return;
+
+    case ADDRESSOF:
+      abort ();
+
+    case REG:
+      regno = REGNO (x);
+
+      /* First handle the case where we encounter a bare register that
+        is eliminable.  Replace it with a PLUS.  */
+      if (regno < FIRST_PSEUDO_REGISTER)
+       {
+         for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
+              ep++)
+           if (ep->from_rtx == x && ep->can_eliminate)
+             {
+               if (! mem_mode)
+                 ep->ref_outside_mem = 1;
+               return;
+             }
+
+       }
+      else if (reg_renumber[regno] < 0 && reg_equiv_constant
+              && reg_equiv_constant[regno]
+              && ! CONSTANT_P (reg_equiv_constant[regno]))
+       elimination_effects (reg_equiv_constant[regno], mem_mode);
+      return;
+
+    case PRE_INC:
+    case POST_INC:
+    case PRE_DEC:
+    case POST_DEC:
+      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
+       if (ep->to_rtx == XEXP (x, 0))
+         {
+           int size = GET_MODE_SIZE (mem_mode);
+
+           /* If more bytes than MEM_MODE are pushed, account for them.  */
+#ifdef PUSH_ROUNDING
+           if (ep->to_rtx == stack_pointer_rtx)
+             size = PUSH_ROUNDING (size);
+#endif
+           if (code == PRE_DEC || code == POST_DEC)
+             ep->offset += size;
+           else
+             ep->offset -= size;
+         }
+
+      /* Fall through to generic unary operation case.  */
+    case STRICT_LOW_PART:
+    case NEG:          case NOT:
+    case SIGN_EXTEND:  case ZERO_EXTEND:
+    case TRUNCATE:     case FLOAT_EXTEND: case FLOAT_TRUNCATE:
+    case FLOAT:        case FIX:
+    case UNSIGNED_FIX: case UNSIGNED_FLOAT:
+    case ABS:
+    case SQRT:
+    case FFS:
+      elimination_effects (XEXP (x, 0), mem_mode);
+      return;
+
+    case SUBREG:
+      if (GET_CODE (SUBREG_REG (x)) == REG
+         && (GET_MODE_SIZE (GET_MODE (x))
+             <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+         && reg_equiv_memory_loc != 0
+         && reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0)
+       return;
+
+      elimination_effects (SUBREG_REG (x), mem_mode);
+      return;
+
+    case USE:
+      /* If using a register that is the source of an eliminate we still
+        think can be performed, note it cannot be performed since we don't
+        know how this register is used.  */
+      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
+       if (ep->from_rtx == XEXP (x, 0))
+         ep->can_eliminate = 0;
+
+      elimination_effects (XEXP (x, 0), mem_mode);
+      return;
+
+    case CLOBBER:
+      /* If clobbering a register that is the replacement register for an
+        elimination we still think can be performed, note that it cannot
+        be performed.  Otherwise, we need not be concerned about it.  */
+      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
+       if (ep->to_rtx == XEXP (x, 0))
+         ep->can_eliminate = 0;
+
+      elimination_effects (XEXP (x, 0), mem_mode);
+      return;
+
+    case SET:
+      /* Check for setting a register that we know about.  */
+      if (GET_CODE (SET_DEST (x)) == REG)
+       {
+         /* See if this is setting the replacement register for an
+            elimination.
+
+            If DEST is the hard frame pointer, we do nothing because we
+            assume that all assignments to the frame pointer are for
+            non-local gotos and are being done at a time when they are valid
+            and do not disturb anything else.  Some machines want to
+            eliminate a fake argument pointer (or even a fake frame pointer)
+            with either the real frame or the stack pointer.  Assignments to
+            the hard frame pointer must not prevent this elimination.  */
+
+         for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
+              ep++)
+           if (ep->to_rtx == SET_DEST (x)
+               && SET_DEST (x) != hard_frame_pointer_rtx)
+             {
+               /* If it is being incremented, adjust the offset.  Otherwise,
+                  this elimination can't be done.  */
+               rtx src = SET_SRC (x);
+
+               if (GET_CODE (src) == PLUS
+                   && XEXP (src, 0) == SET_DEST (x)
+                   && GET_CODE (XEXP (src, 1)) == CONST_INT)
+                 ep->offset -= INTVAL (XEXP (src, 1));
+               else
+                 ep->can_eliminate = 0;
+             }
+       }
+
+      elimination_effects (SET_DEST (x), 0);
+      elimination_effects (SET_SRC (x), 0);
+      return;
+
+    case MEM:
+      if (GET_CODE (XEXP (x, 0)) == ADDRESSOF)
+       abort ();
+
+      /* Our only special processing is to pass the mode of the MEM to our
+        recursive call.  */
+      elimination_effects (XEXP (x, 0), GET_MODE (x));
+      return;
+
+    default:
+      break;
+    }
+
+  fmt = GET_RTX_FORMAT (code);
+  for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
+    {
+      if (*fmt == 'e')
+       elimination_effects (XEXP (x, i), mem_mode);
+      else if (*fmt == 'E')
+       for (j = 0; j < XVECLEN (x, i); j++)
+         elimination_effects (XVECEXP (x, i, j), mem_mode);
+    }
+}
+
+/* Descend through rtx X and verify that no references to eliminable registers
+   remain.  If any do remain, mark the involved register as not
+   eliminable.  */
+static void
+check_eliminable_occurrences (x)
+     rtx x;
+{
+  const char *fmt;
+  int i;
+  enum rtx_code code;
+
+  if (x == 0)
+    return;
+  
+  code = GET_CODE (x);
+
+  if (code == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
+    {
+      struct elim_table *ep;
+
+      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
+       if (ep->from_rtx == x && ep->can_eliminate)
+         ep->can_eliminate = 0;
+      return;
+    }
+  
+  fmt = GET_RTX_FORMAT (code);
+  for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
+    {
+      if (*fmt == 'e')
+       check_eliminable_occurrences (XEXP (x, i));
+      else if (*fmt == 'E')
+       {
+         int j;
+         for (j = 0; j < XVECLEN (x, i); j++)
+           check_eliminable_occurrences (XVECEXP (x, i, j));
+       }
+    }
+}
+\f
+/* Scan INSN and eliminate all eliminable registers in it.
+
+   If REPLACE is nonzero, do the replacement destructively.  Also
+   delete the insn as dead it if it is setting an eliminable register.
+
+   If REPLACE is zero, do all our allocations in reload_obstack.
+
+   If no eliminations were done and this insn doesn't require any elimination
    processing (these are not identical conditions: it might be updating sp,
    but not referencing fp; this needs to be seen during reload_as_needed so
    that the offset between fp and sp can be taken into consideration), zero
@@ -3276,12 +2781,28 @@ eliminate_regs_in_insn (insn, replace)
      rtx insn;
      int replace;
 {
+  int icode = recog_memoized (insn);
   rtx old_body = PATTERN (insn);
+  int insn_is_asm = asm_noperands (old_body) >= 0;
   rtx old_set = single_set (insn);
   rtx new_body;
   int val = 0;
+  int i, any_changes;
+  rtx substed_operand[MAX_RECOG_OPERANDS];
+  rtx orig_operand[MAX_RECOG_OPERANDS];
   struct elim_table *ep;
 
+  if (! insn_is_asm && icode < 0)
+    {
+      if (GET_CODE (PATTERN (insn)) == USE
+         || GET_CODE (PATTERN (insn)) == CLOBBER
+         || GET_CODE (PATTERN (insn)) == ADDR_VEC
+         || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
+         || GET_CODE (PATTERN (insn)) == ASM_INPUT)
+       return 0;
+      abort ();
+    }
+
   if (! replace)
     push_obstacks (&reload_obstack, &reload_obstack);
 
@@ -3409,62 +2930,136 @@ eliminate_regs_in_insn (insn, replace)
            }
     }
 
-  old_asm_operands_vec = 0;
+  /* Determine the effects of this insn on elimination offsets.  */
+  elimination_effects (old_body, 0);
 
-  /* Replace the body of this insn with a substituted form.  If we changed
-     something, return non-zero.
+  /* Eliminate all eliminable registers occurring in operands that
+     can be handled by reload.  */
+  extract_insn (insn);
+  any_changes = 0;
+  for (i = 0; i < recog_data.n_operands; i++)
+    {
+      orig_operand[i] = recog_data.operand[i];
+      substed_operand[i] = recog_data.operand[i];
 
-     If we are replacing a body that was a (set X (plus Y Z)), try to
+      /* For an asm statement, every operand is eliminable.  */
+      if (insn_is_asm || insn_data[icode].operand[i].eliminable)
+       {
+         /* Check for setting a register that we know about.  */
+         if (recog_data.operand_type[i] != OP_IN
+             && GET_CODE (orig_operand[i]) == REG)
+           {
+             /* If we are assigning to a register that can be eliminated, it
+                must be as part of a PARALLEL, since the code above handles
+                single SETs.  We must indicate that we can no longer
+                eliminate this reg.  */
+             for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
+                  ep++)
+               if (ep->from_rtx == orig_operand[i] && ep->can_eliminate)
+                 ep->can_eliminate = 0;
+           }
+
+         substed_operand[i] = eliminate_regs (recog_data.operand[i], 0,
+                                              replace ? insn : NULL_RTX);
+         if (substed_operand[i] != orig_operand[i])
+           val = any_changes = 1;
+         /* Terminate the search in check_eliminable_occurrences at
+            this point.  */
+         *recog_data.operand_loc[i] = 0;
+
+       /* If an output operand changed from a REG to a MEM and INSN is an
+          insn, write a CLOBBER insn.  */
+         if (recog_data.operand_type[i] != OP_IN
+             && GET_CODE (orig_operand[i]) == REG
+             && GET_CODE (substed_operand[i]) == MEM
+             && replace)
+           emit_insn_after (gen_rtx_CLOBBER (VOIDmode, orig_operand[i]),
+                            insn);
+       }
+    }
+
+  for (i = 0; i < recog_data.n_dups; i++)
+    *recog_data.dup_loc[i]
+       = *recog_data.operand_loc[(int)recog_data.dup_num[i]];
+
+  /* If any eliminable remain, they aren't eliminable anymore.  */
+  check_eliminable_occurrences (old_body);
+
+  /* Substitute the operands; the new values are in the substed_operand
+     array.  */
+  for (i = 0; i < recog_data.n_operands; i++)
+    *recog_data.operand_loc[i] = substed_operand[i];
+  for (i = 0; i < recog_data.n_dups; i++)
+    *recog_data.dup_loc[i] = substed_operand[(int)recog_data.dup_num[i]];
+
+  /* If we are replacing a body that was a (set X (plus Y Z)), try to
      re-recognize the insn.  We do this in case we had a simple addition
      but now can do this as a load-address.  This saves an insn in this
-     common case.  */
+     common case.
+     If re-recognition fails, the old insn code number will still be used,
+     and some register operands may have changed into PLUS expressions.
+     These will be handled by find_reloads by loading them into a register
+     again.*/
 
-  new_body = eliminate_regs (old_body, 0, replace ? insn : NULL_RTX);
-  if (new_body != old_body)
+  if (val)
     {
       /* If we aren't replacing things permanently and we changed something,
         make another copy to ensure that all the RTL is new.  Otherwise
         things can go wrong if find_reload swaps commutative operands
         and one is inside RTL that has been copied while the other is not.  */
-
-      /* Don't copy an asm_operands because (1) there's no need and (2)
-        copy_rtx can't do it properly when there are multiple outputs.  */
-      if (! replace && asm_noperands (old_body) < 0)
-       new_body = copy_rtx (new_body);
+      new_body = old_body;
+      if (! replace)
+       {
+         new_body = copy_insn (old_body);
+         if (REG_NOTES (insn))
+           REG_NOTES (insn) = copy_insn_1 (REG_NOTES (insn));
+       }
+      PATTERN (insn) = new_body;
 
       /* If we had a move insn but now we don't, rerecognize it.  This will
         cause spurious re-recognition if the old move had a PARALLEL since
         the new one still will, but we can't call single_set without
         having put NEW_BODY into the insn and the re-recognition won't
         hurt in this rare case.  */
-      if (old_set != 0
+      /* ??? Why this huge if statement - why don't we just rerecognize the
+        thing always?  */
+      if (! insn_is_asm
+         && old_set != 0
          && ((GET_CODE (SET_SRC (old_set)) == REG
               && (GET_CODE (new_body) != SET
                   || GET_CODE (SET_SRC (new_body)) != REG))
              /* If this was a load from or store to memory, compare
-                the MEM in recog_operand to the one in the insn.  If they
-                are not equal, then rerecognize the insn.  */
+                the MEM in recog_data.operand to the one in the insn.
+                If they are not equal, then rerecognize the insn.  */
              || (old_set != 0
                  && ((GET_CODE (SET_SRC (old_set)) == MEM
-                      && SET_SRC (old_set) != recog_operand[1])
+                      && SET_SRC (old_set) != recog_data.operand[1])
                      || (GET_CODE (SET_DEST (old_set)) == MEM
-                         && SET_DEST (old_set) != recog_operand[0])))
+                         && SET_DEST (old_set) != recog_data.operand[0])))
              /* If this was an add insn before, rerecognize.  */
              || GET_CODE (SET_SRC (old_set)) == PLUS))
        {
-         if (! validate_change (insn, &PATTERN (insn), new_body, 0))
-           /* If recognition fails, store the new body anyway.
-              It's normal to have recognition failures here
-              due to bizarre memory addresses; reloading will fix them.  */
-           PATTERN (insn) = new_body;
+         int new_icode = recog (PATTERN (insn), insn, 0);
+         if (new_icode < 0)
+           INSN_CODE (insn) = icode;
        }
-      else
-       PATTERN (insn) = new_body;
+    }
 
-      val = 1;
+  /* Restore the old body.  If there were any changes to it, we made a copy
+     of it while the changes were still in place, so we'll correctly return
+     a modified insn below.  */
+  if (! replace)
+    {
+      /* Restore the old body.  */
+      for (i = 0; i < recog_data.n_operands; i++)
+       *recog_data.operand_loc[i] = orig_operand[i];
+      for (i = 0; i < recog_data.n_dups; i++)
+       *recog_data.dup_loc[i] = orig_operand[(int)recog_data.dup_num[i]];
     }
 
-  /* Loop through all elimination pairs.  See if any have changed.
+  /* Update all elimination pairs to reflect the status after the current
+     insn.  The changes we make were determined by the earlier call to
+     elimination_effects.
 
      We also detect a cases where register elimination cannot be done,
      namely, if a register would be both changed and referenced outside a MEM
@@ -3536,9 +3131,10 @@ update_eliminable_offsets ()
    the insns of the function.  */
 
 static void
-mark_not_eliminable (dest, x)
+mark_not_eliminable (dest, x, data)
      rtx dest;
      rtx x;
+     void *data ATTRIBUTE_UNUSED;
 {
   register unsigned int i;
 
@@ -3824,7 +3420,7 @@ spill_hard_reg (regno, dumpfile, cant_eliminate)
            + HARD_REGNO_NREGS (reg_renumber[i],
                                PSEUDO_REGNO_MODE (i))
            > regno))
-      SET_REGNO_REG_SET (spilled_pseudos, i);
+      SET_REGNO_REG_SET (&spilled_pseudos, i);
 }
 
 /* I'm getting weird preprocessor errors if I use IOR_HARD_REG_SET
@@ -3876,7 +3472,7 @@ finish_spills (global, dumpfile)
       spill_reg_order[i] = -1;
 
   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
-    if (REGNO_REG_SET_P (spilled_pseudos, i))
+    if (REGNO_REG_SET_P (&spilled_pseudos, i))
       {
        /* Record the current hard register the pseudo is allocated to in
           pseudo_previous_regs so we avoid reallocating it to the same
@@ -3900,13 +3496,13 @@ finish_spills (global, dumpfile)
       for (chain = insns_need_reload; chain; chain = chain->next_need_reload)
        {
          EXECUTE_IF_SET_IN_REG_SET
-           (chain->live_before, FIRST_PSEUDO_REGISTER, i,
+           (chain->live_throughout, FIRST_PSEUDO_REGISTER, i,
             {
               ior_hard_reg_set (pseudo_forbidden_regs + i,
                                 &chain->used_spill_regs);
             });
          EXECUTE_IF_SET_IN_REG_SET
-           (chain->live_after, FIRST_PSEUDO_REGISTER, i,
+           (chain->dead_or_set, FIRST_PSEUDO_REGISTER, i,
             {
               ior_hard_reg_set (pseudo_forbidden_regs + i,
                                 &chain->used_spill_regs);
@@ -3927,7 +3523,7 @@ finish_spills (global, dumpfile)
            IOR_HARD_REG_SET (forbidden, pseudo_previous_regs[i]);
            retry_global_alloc (i, forbidden);
            if (reg_renumber[i] >= 0)
-             CLEAR_REGNO_REG_SET (spilled_pseudos, i);
+             CLEAR_REGNO_REG_SET (&spilled_pseudos, i);
          }
     }
 
@@ -3939,22 +3535,22 @@ finish_spills (global, dumpfile)
       HARD_REG_SET used_by_pseudos;
       HARD_REG_SET used_by_pseudos2;
 
-      AND_COMPL_REG_SET (chain->live_before, spilled_pseudos);
-      AND_COMPL_REG_SET (chain->live_after, spilled_pseudos);
+      AND_COMPL_REG_SET (chain->live_throughout, &spilled_pseudos);
+      AND_COMPL_REG_SET (chain->dead_or_set, &spilled_pseudos);
 
       /* Mark any unallocated hard regs as available for spills.  That
         makes inheritance work somewhat better.  */
       if (chain->need_reload)
        {
-         REG_SET_TO_HARD_REG_SET (used_by_pseudos, chain->live_before);
-         REG_SET_TO_HARD_REG_SET (used_by_pseudos2, chain->live_after);
+         REG_SET_TO_HARD_REG_SET (used_by_pseudos, chain->live_throughout);
+         REG_SET_TO_HARD_REG_SET (used_by_pseudos2, chain->dead_or_set);
          IOR_HARD_REG_SET (used_by_pseudos, used_by_pseudos2);
 
          /* Save the old value for the sanity test below.  */
          COPY_HARD_REG_SET (used_by_pseudos2, chain->used_spill_regs);
 
-         compute_use_by_pseudos (&used_by_pseudos, chain->live_before);
-         compute_use_by_pseudos (&used_by_pseudos, chain->live_after);
+         compute_use_by_pseudos (&used_by_pseudos, chain->live_throughout);
+         compute_use_by_pseudos (&used_by_pseudos, chain->dead_or_set);
          COMPL_HARD_REG_SET (chain->used_spill_regs, used_by_pseudos);
          AND_HARD_REG_SET (chain->used_spill_regs, used_spill_regs);
 
@@ -3995,200 +3591,54 @@ static void
 scan_paradoxical_subregs (x)
      register rtx x;
 {
-  register int i;
-  register const char *fmt;
-  register enum rtx_code code = GET_CODE (x);
-
-  switch (code)
-    {
-    case REG:
-#if 0
-      if (SMALL_REGISTER_CLASSES && REGNO (x) < FIRST_PSEUDO_REGISTER
-         && REG_USERVAR_P (x))
-       SET_HARD_REG_BIT (bad_spill_regs_global, REGNO (x));
-#endif
-      return;
-
-    case CONST_INT:
-    case CONST:
-    case SYMBOL_REF:
-    case LABEL_REF:
-    case CONST_DOUBLE:
-    case CC0:
-    case PC:
-    case USE:
-    case CLOBBER:
-      return;
-
-    case SUBREG:
-      if (GET_CODE (SUBREG_REG (x)) == REG
-         && GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
-       reg_max_ref_width[REGNO (SUBREG_REG (x))]
-         = GET_MODE_SIZE (GET_MODE (x));
-      return;
-
-    default:
-      break;
-    }
-
-  fmt = GET_RTX_FORMAT (code);
-  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-    {
-      if (fmt[i] == 'e')
-       scan_paradoxical_subregs (XEXP (x, i));
-      else if (fmt[i] == 'E')
-       {
-         register int j;
-         for (j = XVECLEN (x, i) - 1; j >=0; j--)
-           scan_paradoxical_subregs (XVECEXP (x, i, j));
-       }
-    }
-}
-\f
-static int
-hard_reg_use_compare (p1p, p2p)
-     const PTR p1p;
-     const PTR p2p;
-{
-  struct hard_reg_n_uses *p1 = (struct hard_reg_n_uses *)p1p;
-  struct hard_reg_n_uses *p2 = (struct hard_reg_n_uses *)p2p;
-  int bad1 = TEST_HARD_REG_BIT (bad_spill_regs, p1->regno);
-  int bad2 = TEST_HARD_REG_BIT (bad_spill_regs, p2->regno);
-  if (bad1 && bad2)
-    return p1->regno - p2->regno;
-  if (bad1)
-    return 1;
-  if (bad2)
-    return -1;
-  if (p1->uses > p2->uses)
-    return 1;
-  if (p1->uses < p2->uses)
-    return -1;
-  /* If regs are equally good, sort by regno,
-     so that the results of qsort leave nothing to chance.  */
-  return p1->regno - p2->regno;
-}
-
-/* Used for communication between order_regs_for_reload and count_pseudo.
-   Used to avoid counting one pseudo twice.  */
-static regset pseudos_counted;
-
-/* Update the costs in N_USES, considering that pseudo REG is live.  */
-static void
-count_pseudo (n_uses, reg)
-     struct hard_reg_n_uses *n_uses;
-     int reg;
-{
-  int r = reg_renumber[reg];
-  int nregs;
-
-  if (REGNO_REG_SET_P (pseudos_counted, reg))
-    return;
-  SET_REGNO_REG_SET (pseudos_counted, reg);
-
-  if (r < 0)
-    abort ();
-
-  nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (reg));
-  while (nregs-- > 0)
-    n_uses[r++].uses += REG_N_REFS (reg);
-}
-/* Choose the order to consider regs for use as reload registers
-   based on how much trouble would be caused by spilling one.
-   Store them in order of decreasing preference in potential_reload_regs.  */
-
-static void
-order_regs_for_reload (chain)
-     struct insn_chain *chain;
-{
-  register int i;
-  register int o = 0;
-  struct hard_reg_n_uses hard_reg_n_uses[FIRST_PSEUDO_REGISTER];
-
-  pseudos_counted = ALLOCA_REG_SET ();
-
-  COPY_HARD_REG_SET (bad_spill_regs, bad_spill_regs_global);
-
-  /* Count number of uses of each hard reg by pseudo regs allocated to it
-     and then order them by decreasing use.  */
-
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    {
-      int j;
-
-      hard_reg_n_uses[i].regno = i;
-      hard_reg_n_uses[i].uses = 0;
-
-      /* Test the various reasons why we can't use a register for
-        spilling in this insn.  */
-      if (fixed_regs[i]
-         || REGNO_REG_SET_P (chain->live_before, i)
-         || REGNO_REG_SET_P (chain->live_after, i))
-       {
-         SET_HARD_REG_BIT (bad_spill_regs, i);
-         continue;
-       }
-
-      /* Now find out which pseudos are allocated to it, and update
-        hard_reg_n_uses.  */
-      CLEAR_REG_SET (pseudos_counted);
-
-      EXECUTE_IF_SET_IN_REG_SET
-       (chain->live_before, FIRST_PSEUDO_REGISTER, j,
-        {
-          count_pseudo (hard_reg_n_uses, j);
-        });
-      EXECUTE_IF_SET_IN_REG_SET
-       (chain->live_after, FIRST_PSEUDO_REGISTER, j,
-        {
-          count_pseudo (hard_reg_n_uses, j);
-        });
-    }
-
-  FREE_REG_SET (pseudos_counted);
-
-  /* Prefer registers not so far used, for use in temporary loading.
-     Among them, if REG_ALLOC_ORDER is defined, use that order.
-     Otherwise, prefer registers not preserved by calls.  */
-
-#ifdef REG_ALLOC_ORDER
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    {
-      int regno = reg_alloc_order[i];
+  register int i;
+  register const char *fmt;
+  register enum rtx_code code = GET_CODE (x);
 
-      if (hard_reg_n_uses[regno].uses == 0
-         && ! TEST_HARD_REG_BIT (bad_spill_regs, regno))
-       potential_reload_regs[o++] = regno;
-    }
-#else
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    {
-      if (hard_reg_n_uses[i].uses == 0 && call_used_regs[i]
-         && ! TEST_HARD_REG_BIT (bad_spill_regs, i))
-       potential_reload_regs[o++] = i;
-    }
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+  switch (code)
     {
-      if (hard_reg_n_uses[i].uses == 0 && ! call_used_regs[i]
-         && ! TEST_HARD_REG_BIT (bad_spill_regs, i))
-       potential_reload_regs[o++] = i;
-    }
+    case REG:
+#if 0
+      if (SMALL_REGISTER_CLASSES && REGNO (x) < FIRST_PSEUDO_REGISTER
+         && REG_USERVAR_P (x))
+       SET_HARD_REG_BIT (bad_spill_regs_global, REGNO (x));
 #endif
+      return;
+
+    case CONST_INT:
+    case CONST:
+    case SYMBOL_REF:
+    case LABEL_REF:
+    case CONST_DOUBLE:
+    case CC0:
+    case PC:
+    case USE:
+    case CLOBBER:
+      return;
 
-  qsort (hard_reg_n_uses, FIRST_PSEUDO_REGISTER,
-        sizeof hard_reg_n_uses[0], hard_reg_use_compare);
+    case SUBREG:
+      if (GET_CODE (SUBREG_REG (x)) == REG
+         && GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+       reg_max_ref_width[REGNO (SUBREG_REG (x))]
+         = GET_MODE_SIZE (GET_MODE (x));
+      return;
 
-  /* Now add the regs that are already used,
-     preferring those used less often.  The fixed and otherwise forbidden
-     registers will be at the end of this list.  */
+    default:
+      break;
+    }
 
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    if (hard_reg_n_uses[i].uses != 0
-       && ! TEST_HARD_REG_BIT (bad_spill_regs, hard_reg_n_uses[i].regno))
-      potential_reload_regs[o++] = hard_reg_n_uses[i].regno;
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    if (TEST_HARD_REG_BIT (bad_spill_regs, hard_reg_n_uses[i].regno))
-      potential_reload_regs[o++] = hard_reg_n_uses[i].regno;
+  fmt = GET_RTX_FORMAT (code);
+  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+    {
+      if (fmt[i] == 'e')
+       scan_paradoxical_subregs (XEXP (x, i));
+      else if (fmt[i] == 'E')
+       {
+         register int j;
+         for (j = XVECLEN (x, i) - 1; j >=0; j--)
+           scan_paradoxical_subregs (XVECEXP (x, i, j));
+       }
+    }
 }
 \f
 /* Reload pseudo-registers into hard regs around each insn as needed.
@@ -4205,16 +3655,15 @@ reload_as_needed (live_known)
      int live_known;
 {
   struct insn_chain *chain;
-#if defined (AUTO_INC_DEC) || defined (INSN_CLOBBERS_REGNO_P)
+#if defined (AUTO_INC_DEC)
   register int i;
 #endif
   rtx x;
 
   bzero ((char *) spill_reg_rtx, sizeof spill_reg_rtx);
   bzero ((char *) spill_reg_store, sizeof spill_reg_store);
-  reg_last_reload_reg = (rtx *) alloca (max_regno * sizeof (rtx));
-  bzero ((char *) reg_last_reload_reg, max_regno * sizeof (rtx));
-  reg_has_output_reload = (char *) alloca (max_regno);
+  reg_last_reload_reg = (rtx *) xcalloc (max_regno, sizeof (rtx));
+  reg_has_output_reload = (char *) xmalloc (max_regno);
   CLEAR_HARD_REG_SET (reg_reloaded_valid);
 
   set_initial_elim_offsets ();
@@ -4335,13 +3784,13 @@ reload_as_needed (live_known)
             for this insn in order to be stored in
             (obeying register constraints).  That is correct; such reload
             registers ARE still valid.  */
-         note_stores (oldpat, forget_old_reloads_1);
+         note_stores (oldpat, forget_old_reloads_1, NULL);
 
          /* There may have been CLOBBER insns placed after INSN.  So scan
             between INSN and NEXT and use them to forget old reloads.  */
          for (x = NEXT_INSN (insn); x != old_next; x = NEXT_INSN (x))
            if (GET_CODE (x) == INSN && GET_CODE (PATTERN (x)) == CLOBBER)
-             note_stores (PATTERN (x), forget_old_reloads_1);
+             note_stores (PATTERN (x), forget_old_reloads_1, NULL);
 
 #ifdef AUTO_INC_DEC
          /* Likewise for regs altered by auto-increment in this insn.
@@ -4350,7 +3799,7 @@ reload_as_needed (live_known)
             which have been performed by subst_reloads above.  */
          for (i = n_reloads - 1; i >= 0; i--)
            {
-             rtx in_reg = reload_in_reg[i];
+             rtx in_reg = rld[i].in_reg;
              if (in_reg)
                {
                  enum rtx_code code = GET_CODE (in_reg);
@@ -4361,14 +3810,14 @@ reload_as_needed (live_known)
                     or we can't use the reload register for inheritance.  */
                  if ((code == POST_INC || code == POST_DEC)
                      && TEST_HARD_REG_BIT (reg_reloaded_valid,
-                                           REGNO (reload_reg_rtx[i]))
+                                           REGNO (rld[i].reg_rtx))
                      /* Make sure it is the inc/dec pseudo, and not
                         some other (e.g. output operand) pseudo.  */
-                     && (reg_reloaded_contents[REGNO (reload_reg_rtx[i])]
+                     && (reg_reloaded_contents[REGNO (rld[i].reg_rtx)]
                          == REGNO (XEXP (in_reg, 0))))
 
                    {
-                     rtx reload_reg = reload_reg_rtx[i];
+                     rtx reload_reg = rld[i].reg_rtx;
                      enum machine_mode mode = GET_MODE (reload_reg);
                      int n = 0;
                      rtx p;
@@ -4423,18 +3872,19 @@ reload_as_needed (live_known)
                          reg_has_output_reload[REGNO (XEXP (in_reg, 0))] = 1;
                        }
                      else
-                       forget_old_reloads_1 (XEXP (in_reg, 0), NULL_RTX);
+                       forget_old_reloads_1 (XEXP (in_reg, 0), NULL_RTX, 
+                                             NULL);
                    }
                  else if ((code == PRE_INC || code == PRE_DEC)
                           && TEST_HARD_REG_BIT (reg_reloaded_valid,
-                                                REGNO (reload_reg_rtx[i]))
+                                                REGNO (rld[i].reg_rtx))
                           /* Make sure it is the inc/dec pseudo, and not
                              some other (e.g. output operand) pseudo.  */
-                          && (reg_reloaded_contents[REGNO (reload_reg_rtx[i])]
+                          && (reg_reloaded_contents[REGNO (rld[i].reg_rtx)]
                               == REGNO (XEXP (in_reg, 0))))
                    {
                      SET_HARD_REG_BIT (reg_is_output_reload,
-                                       REGNO (reload_reg_rtx[i]));
+                                       REGNO (rld[i].reg_rtx));
                      reg_has_output_reload[REGNO (XEXP (in_reg, 0))] = 1;
                    }
                }
@@ -4449,11 +3899,11 @@ reload_as_needed (live_known)
                   If so, its last-reload info is still valid
                   because it is based on this insn's reload.  */
                for (i = 0; i < n_reloads; i++)
-                 if (reload_out[i] == XEXP (x, 0))
+                 if (rld[i].out == XEXP (x, 0))
                    break;
 
                if (i == n_reloads)
-                 forget_old_reloads_1 (XEXP (x, 0), NULL_RTX);
+                 forget_old_reloads_1 (XEXP (x, 0), NULL_RTX, NULL);
              }
 #endif
        }
@@ -4465,21 +3915,11 @@ reload_as_needed (live_known)
         if it is a call-used reg.  */
       else if (GET_CODE (insn) == CALL_INSN)
        AND_COMPL_HARD_REG_SET(reg_reloaded_valid, call_used_reg_set);
-
-      /* In case registers overlap, allow certain insns to invalidate
-        particular hard registers.  */
-
-#ifdef INSN_CLOBBERS_REGNO_P
-      for (i = 0 ; i < FIRST_PSEUDO_REGISTER; i++)
-       if (TEST_HARD_REG_BIT (reg_reloaded_valid, i)
-           && INSN_CLOBBERS_REGNO_P (insn, i))
-         CLEAR_HARD_REG_BIT (reg_reloaded_valid, i);
-#endif
-
-#ifdef USE_C_ALLOCA
-      alloca (0);
-#endif
     }
+
+  /* Clean up.  */
+  free (reg_last_reload_reg);
+  free (reg_has_output_reload);
 }
 
 /* Discard all record of any value reloaded from X,
@@ -4490,9 +3930,10 @@ reload_as_needed (live_known)
    or it may be a pseudo reg that was reloaded from.  */
 
 static void
-forget_old_reloads_1 (x, ignored)
+forget_old_reloads_1 (x, ignored, data)
      rtx x;
      rtx ignored ATTRIBUTE_UNUSED;
+     void *data ATTRIBUTE_UNUSED;
 {
   register int regno;
   int nr;
@@ -4538,49 +3979,6 @@ forget_old_reloads_1 (x, ignored)
       reg_last_reload_reg[regno + nr] = 0;
 }
 \f
-/* For each reload, the mode of the reload register.  */
-static enum machine_mode reload_mode[MAX_RELOADS];
-
-/* For each reload, the largest number of registers it will require.  */
-static int reload_nregs[MAX_RELOADS];
-
-/* Comparison function for qsort to decide which of two reloads
-   should be handled first.  *P1 and *P2 are the reload numbers.  */
-
-static int
-reload_reg_class_lower (r1p, r2p)
-     const PTR r1p;
-     const PTR r2p;
-{
-  register int r1 = *(short *)r1p, r2 = *(short *)r2p;
-  register int t;
-
-  /* Consider required reloads before optional ones.  */
-  t = reload_optional[r1] - reload_optional[r2];
-  if (t != 0)
-    return t;
-
-  /* Count all solitary classes before non-solitary ones.  */
-  t = ((reg_class_size[(int) reload_reg_class[r2]] == 1)
-       - (reg_class_size[(int) reload_reg_class[r1]] == 1));
-  if (t != 0)
-    return t;
-
-  /* Aside from solitaires, consider all multi-reg groups first.  */
-  t = reload_nregs[r2] - reload_nregs[r1];
-  if (t != 0)
-    return t;
-
-  /* Consider reloads in order of increasing reg-class number.  */
-  t = (int) reload_reg_class[r1] - (int) reload_reg_class[r2];
-  if (t != 0)
-    return t;
-
-  /* If reloads are equally urgent, sort by reload number,
-     so that the results of qsort leave nothing to chance.  */
-  return r1 - r2;
-}
-\f
 /* The following HARD_REG_SETs indicate when each hard register is
    used for a reload of various parts of the current insn.  */
 
@@ -4771,14 +4169,14 @@ clear_reload_reg_in_use (regno, opnum, type, mode)
     {
       for (i = n_reloads - 1; i >= 0; i--)
        {
-         if (reload_when_needed[i] == type
-             && (check_any || reload_opnum[i] == opnum)
-             && reload_reg_rtx[i])
+         if (rld[i].when_needed == type
+             && (check_any || rld[i].opnum == opnum)
+             && rld[i].reg_rtx)
            {
-             int conflict_start = true_regnum (reload_reg_rtx[i]);
+             int conflict_start = true_regnum (rld[i].reg_rtx);
              int conflict_end
                = (conflict_start
-                  + HARD_REGNO_NREGS (conflict_start, reload_mode[i]));
+                  + HARD_REGNO_NREGS (conflict_start, rld[i].mode));
 
              /* If there is an overlap with the first to-be-freed register,
                 adjust the interval start.  */
@@ -5090,10 +4488,10 @@ int
 reloads_conflict (r1, r2)
      int r1, r2;
 {
-  enum reload_type r1_type = reload_when_needed[r1];
-  enum reload_type r2_type = reload_when_needed[r2];
-  int r1_opnum = reload_opnum[r1];
-  int r2_opnum = reload_opnum[r2];
+  enum reload_type r1_type = rld[r1].when_needed;
+  enum reload_type r2_type = rld[r2].when_needed;
+  int r1_opnum = rld[r1].opnum;
+  int r2_opnum = rld[r2].opnum;
 
   /* RELOAD_OTHER conflicts with everything.  */
   if (r2_type == RELOAD_OTHER)
@@ -5140,7 +4538,7 @@ reloads_conflict (r1, r2)
       return (r2_type == RELOAD_FOR_INSN || r2_type == RELOAD_FOR_OUTPUT
              || ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS
                   || r2_type == RELOAD_FOR_OUTADDR_ADDRESS)
-                 && r2_opnum >= r1_opnum));
+                 && r2_opnum <= r1_opnum));
 
     case RELOAD_FOR_INSN:
       return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_OUTPUT
@@ -5158,10 +4556,6 @@ reloads_conflict (r1, r2)
     }
 }
 \f
-/* Vector of reload-numbers showing the order in which the reloads should
-   be processed.  */
-short reload_order[MAX_RELOADS];
-
 /* Indexed by reload number, 1 if incoming value
    inherited from previous insns.  */
 char reload_inherited[MAX_RELOADS];
@@ -5208,9 +4602,20 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
      int ignore_address_reloads;
 {
   int time1;
+  /* Set if we see an input reload that must not share its reload register
+     with any new earlyclobber, but might otherwise share the reload
+     register with an output or input-output reload.  */
+  int check_earlyclobber = 0;
   int i;
   int copy = 0;
 
+  /* ??? reload_reg_used is abused to hold the registers that are not
+     available as spill registers, including hard registers that are
+     earlyclobbered in asms.  As a temporary measure, reject anything
+     in reload_reg_used.  */
+  if (TEST_HARD_REG_BIT (reload_reg_used, regno))
+    return 0;
+
   if (out == const0_rtx)
     {
       copy = 1;
@@ -5235,7 +4640,8 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
   switch (type)
     {
     case RELOAD_FOR_OTHER_ADDRESS:
-      time1 = 0;
+      /* RELOAD_FOR_OTHER_ADDRESS conflits with RELOAD_OTHER reloads.  */
+      time1 = copy ? 0 : 1;
       break;
     case RELOAD_OTHER:
       time1 = copy ? 1 : MAX_RECOG_OPERANDS * 5 + 5;
@@ -5279,17 +4685,17 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
 
   for (i = 0; i < n_reloads; i++)
     {
-      rtx reg = reload_reg_rtx[i];
+      rtx reg = rld[i].reg_rtx;
       if (reg && GET_CODE (reg) == REG
          && ((unsigned) regno - true_regnum (reg)
              <= HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)) - (unsigned)1)
          && i != reloadnum)
        {
-         if (! reload_in[i] || ! rtx_equal_p (reload_in[i], value)
-             || reload_out[i] || out)
+         if (! rld[i].in || ! rtx_equal_p (rld[i].in, value)
+             || rld[i].out || out)
            {
              int time2;
-             switch (reload_when_needed[i])
+             switch (rld[i].when_needed)
                {
                case RELOAD_FOR_OTHER_ADDRESS:
                  time2 = 0;
@@ -5306,39 +4712,41 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
                      /* Unless the RELOAD_FOR_INPUT is an auto_inc expression.
                         Then the address address is still needed to store
                         back the new address.  */
-                     && ! reload_out[reloadnum])
+                     && ! rld[reloadnum].out)
                    continue;
                  /* Likewise, if a RELOAD_FOR_INPUT can inherit a value, its
                     RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS
                     reloads go away.  */
-                 if (type == RELOAD_FOR_INPUT && opnum == reload_opnum[i]
+                 if (type == RELOAD_FOR_INPUT && opnum == rld[i].opnum
                      && ignore_address_reloads
                      /* Unless we are reloading an auto_inc expression.  */
-                     && ! reload_out[reloadnum])
+                     && ! rld[reloadnum].out)
                    continue;
-                 time2 = reload_opnum[i] * 4 + 2;
+                 time2 = rld[i].opnum * 4 + 2;
                  break;
                case RELOAD_FOR_INPUT_ADDRESS:
-                 if (type == RELOAD_FOR_INPUT && opnum == reload_opnum[i]
+                 if (type == RELOAD_FOR_INPUT && opnum == rld[i].opnum
                      && ignore_address_reloads
-                     && ! reload_out[reloadnum])
+                     && ! rld[reloadnum].out)
                    continue;
-                 time2 = reload_opnum[i] * 4 + 3;
+                 time2 = rld[i].opnum * 4 + 3;
                  break;
                case RELOAD_FOR_INPUT:
-                 time2 = reload_opnum[i] * 4 + 4;
+                 time2 = rld[i].opnum * 4 + 4;
+                 check_earlyclobber = 1;
                  break;
-                 /* reload_opnum[i] * 4 + 4 <= (MAX_RECOG_OPERAND - 1) * 4 + 4
+                 /* rld[i].opnum * 4 + 4 <= (MAX_RECOG_OPERAND - 1) * 4 + 4
                     == MAX_RECOG_OPERAND * 4  */
                case RELOAD_FOR_OPADDR_ADDR:
                  if (type == RELOAD_FOR_OPERAND_ADDRESS && reloadnum == i + 1
                      && ignore_address_reloads
-                     && ! reload_out[reloadnum])
+                     && ! rld[reloadnum].out)
                    continue;
                  time2 = MAX_RECOG_OPERANDS * 4 + 1;
                  break;
                case RELOAD_FOR_OPERAND_ADDRESS:
                  time2 = MAX_RECOG_OPERANDS * 4 + 2;
+                 check_earlyclobber = 1;
                  break;
                case RELOAD_FOR_INSN:
                  time2 = MAX_RECOG_OPERANDS * 4 + 3;
@@ -5354,19 +4762,23 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
                case RELOAD_FOR_OUTADDR_ADDRESS:
                  if (type == RELOAD_FOR_OUTPUT_ADDRESS && reloadnum == i + 1
                      && ignore_address_reloads
-                     && ! reload_out[reloadnum])
+                     && ! rld[reloadnum].out)
                    continue;
-                 time2 = MAX_RECOG_OPERANDS * 4 + 4 + reload_opnum[i];
+                 time2 = MAX_RECOG_OPERANDS * 4 + 4 + rld[i].opnum;
                  break;
                case RELOAD_FOR_OUTPUT_ADDRESS:
-                 time2 = MAX_RECOG_OPERANDS * 4 + 5 + reload_opnum[i];
+                 time2 = MAX_RECOG_OPERANDS * 4 + 5 + rld[i].opnum;
                  break;
                case RELOAD_OTHER:
                  /* If there is no conflict in the input part, handle this
                     like an output reload.  */
-                 if (! reload_in[i] || rtx_equal_p (reload_in[i], value))
+                 if (! rld[i].in || rtx_equal_p (rld[i].in, value))
                    {
                      time2 = MAX_RECOG_OPERANDS * 4 + 4;
+                     /* Earlyclobbered outputs must conflict with inputs.  */
+                     if (earlyclobber_operand_p (rld[i].out))
+                       time2 = MAX_RECOG_OPERANDS * 4 + 3;
+                         
                      break;
                    }
                  time2 = 1;
@@ -5381,36 +4793,111 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
                  return 0;
                }
              if ((time1 >= time2
-                  && (! reload_in[i] || reload_out[i]
-                      || ! rtx_equal_p (reload_in[i], value)))
-                 || (out && reload_out_reg[reloadnum]
+                  && (! rld[i].in || rld[i].out
+                      || ! rtx_equal_p (rld[i].in, value)))
+                 || (out && rld[reloadnum].out_reg
                      && time2 >= MAX_RECOG_OPERANDS * 4 + 3))
                return 0;
            }
        }
     }
+
+  /* Earlyclobbered outputs must conflict with inputs.  */
+  if (check_earlyclobber && out && earlyclobber_operand_p (out))
+    return 0;
+
   return 1;
 }
 
+/* Give an error message saying we failed to find a reload for INSN,
+   and clear out reload R.  */
+static void
+failed_reload (insn, r)
+     rtx insn;
+     int r;
+{
+  if (asm_noperands (PATTERN (insn)) < 0)
+    /* It's the compiler's fault.  */
+    fatal_insn ("Could not find a spill register", insn);
+
+  /* It's the user's fault; the operand's mode and constraint
+     don't match.  Disable this reload so we don't crash in final.  */
+  error_for_asm (insn,
+                "`asm' operand constraint incompatible with operand size");
+  rld[r].in = 0;
+  rld[r].out = 0;
+  rld[r].reg_rtx = 0;
+  rld[r].optional = 1;
+  rld[r].secondary_p = 1;
+}
+
+/* I is the index in SPILL_REG_RTX of the reload register we are to allocate
+   for reload R.  If it's valid, get an rtx for it.  Return nonzero if
+   successful.  */
+static int
+set_reload_reg (i, r)
+     int i, r;
+{
+  int regno;
+  rtx reg = spill_reg_rtx[i];
+
+  if (reg == 0 || GET_MODE (reg) != rld[r].mode)
+    spill_reg_rtx[i] = reg
+      = gen_rtx_REG (rld[r].mode, spill_regs[i]);
+
+  regno = true_regnum (reg);
+
+  /* Detect when the reload reg can't hold the reload mode.
+     This used to be one `if', but Sequent compiler can't handle that.  */
+  if (HARD_REGNO_MODE_OK (regno, rld[r].mode))
+    {
+      enum machine_mode test_mode = VOIDmode;
+      if (rld[r].in)
+       test_mode = GET_MODE (rld[r].in);
+      /* If rld[r].in has VOIDmode, it means we will load it
+        in whatever mode the reload reg has: to wit, rld[r].mode.
+        We have already tested that for validity.  */
+      /* Aside from that, we need to test that the expressions
+        to reload from or into have modes which are valid for this
+        reload register.  Otherwise the reload insns would be invalid.  */
+      if (! (rld[r].in != 0 && test_mode != VOIDmode
+            && ! HARD_REGNO_MODE_OK (regno, test_mode)))
+       if (! (rld[r].out != 0
+              && ! HARD_REGNO_MODE_OK (regno, GET_MODE (rld[r].out))))
+         {
+           /* The reg is OK.  */
+           last_spill_reg = i;
+
+           /* Mark as in use for this insn the reload regs we use
+              for this.  */
+           mark_reload_reg_in_use (spill_regs[i], rld[r].opnum,
+                                   rld[r].when_needed, rld[r].mode);
+
+           rld[r].reg_rtx = reg;
+           reload_spill_index[r] = spill_regs[i];
+           return 1;
+         }
+    }
+  return 0;
+}
+
 /* Find a spill register to use as a reload register for reload R.
    LAST_RELOAD is non-zero if this is the last reload for the insn being
    processed.
 
-   Set reload_reg_rtx[R] to the register allocated.
+   Set rld[R].reg_rtx to the register allocated.
 
-   If NOERROR is nonzero, we return 1 if successful,
-   or 0 if we couldn't find a spill reg and we didn't change anything.  */
+   We return 1 if successful, or 0 if we couldn't find a spill reg and
+   we didn't change anything.  */
 
 static int
-allocate_reload_reg (chain, r, last_reload, noerror)
+allocate_reload_reg (chain, r, last_reload)
      struct insn_chain *chain;
      int r;
      int last_reload;
-     int noerror;
 {
   rtx insn = chain->insn;
-  int i, pass, count, regno;
-  rtx new;
+  int i, pass, count;
 
   /* If we put this reload ahead, thinking it is a group,
      then insist on finding a group.  Otherwise we can grab a
@@ -5425,7 +4912,7 @@ allocate_reload_reg (chain, r, last_reload, noerror)
      Perhaps those classes should be avoided for reloading
      by use of more alternatives.  */
 
-  int force_group = reload_nregs[r] > 1 && ! last_reload;
+  int force_group = rld[r].nregs > 1 && ! last_reload;
 
   /* If we want a single register and haven't yet found one,
      take any reg in the right class and not in use.
@@ -5444,21 +4931,13 @@ allocate_reload_reg (chain, r, last_reload, noerror)
       /* I is the index in spill_regs.
         We advance it round-robin between insns to use all spill regs
         equally, so that inherited reloads have a chance
-        of leapfrogging each other.  Don't do this, however, when we have
-        group needs and failure would be fatal; if we only have a relatively
-        small number of spill registers, and more than one of them has
-        group needs, then by starting in the middle, we may end up
-        allocating the first one in such a way that we are not left with
-        sufficient groups to handle the rest.  */
-
-      if (noerror || ! force_group)
-       i = last_spill_reg;
-      else
-       i = -1;
+        of leapfrogging each other.  */
+
+      i = last_spill_reg;
 
       for (count = 0; count < n_spills; count++)
        {
-         int class = (int) reload_reg_class[r];
+         int class = (int) rld[r].class;
          int regnum;
 
          i++;
@@ -5466,19 +4945,19 @@ allocate_reload_reg (chain, r, last_reload, noerror)
            i -= n_spills;
          regnum = spill_regs[i];
 
-         if ((reload_reg_free_p (regnum, reload_opnum[r],
-                                 reload_when_needed[r])
-              || (reload_in[r]
+         if ((reload_reg_free_p (regnum, rld[r].opnum,
+                                 rld[r].when_needed)
+              || (rld[r].in
                   /* We check reload_reg_used to make sure we
                      don't clobber the return register.  */
                   && ! TEST_HARD_REG_BIT (reload_reg_used, regnum)
                   && reload_reg_free_for_value_p (regnum,
-                                                  reload_opnum[r],
-                                                  reload_when_needed[r],
-                                                  reload_in[r],
-                                                  reload_out[r], r, 1)))
+                                                  rld[r].opnum,
+                                                  rld[r].when_needed,
+                                                  rld[r].in,
+                                                  rld[r].out, r, 1)))
              && TEST_HARD_REG_BIT (reg_class_contents[class], regnum)
-             && HARD_REGNO_MODE_OK (regnum, reload_mode[r])
+             && HARD_REGNO_MODE_OK (regnum, rld[r].mode)
              /* Look first for regs to share, then for unshared.  But
                 don't share regs used for inherited reloads; they are
                 the ones we want to preserve.  */
@@ -5488,12 +4967,12 @@ allocate_reload_reg (chain, r, last_reload, noerror)
                      && ! TEST_HARD_REG_BIT (reload_reg_used_for_inherit,
                                              regnum))))
            {
-             int nr = HARD_REGNO_NREGS (regnum, reload_mode[r]);
+             int nr = HARD_REGNO_NREGS (regnum, rld[r].mode);
              /* Avoid the problem where spilling a GENERAL_OR_FP_REG
                 (on 68000) got us two FP regs.  If NR is 1,
                 we would reject both of them.  */
              if (force_group)
-               nr = CLASS_MAX_NREGS (reload_reg_class[r], reload_mode[r]);
+               nr = rld[r].nregs;
              /* If we need only one reg, we have already won.  */
              if (nr == 1)
                {
@@ -5503,22 +4982,17 @@ allocate_reload_reg (chain, r, last_reload, noerror)
                  break;
                }
              /* Otherwise check that as many consecutive regs as we need
-                are available here.
-                Also, don't use for a group registers that are
-                needed for nongroups.  */
-             if (! TEST_HARD_REG_BIT (chain->counted_for_nongroups, regnum))
-               while (nr > 1)
-                 {
-                   regno = regnum + nr - 1;
-                   if (!(TEST_HARD_REG_BIT (reg_class_contents[class], regno)
-                         && spill_reg_order[regno] >= 0
-                         && reload_reg_free_p (regno, reload_opnum[r],
-                                               reload_when_needed[r])
-                         && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups,
-                                                 regno)))
-                     break;
-                   nr--;
-                 }
+                are available here.  */
+             while (nr > 1)
+               {
+                 int regno = regnum + nr - 1;
+                 if (!(TEST_HARD_REG_BIT (reg_class_contents[class], regno)
+                       && spill_reg_order[regno] >= 0
+                       && reload_reg_free_p (regno, rld[r].opnum,
+                                             rld[r].when_needed)))
+                   break;
+                 nr--;
+               }
              if (nr == 1)
                break;
            }
@@ -5528,115 +5002,29 @@ allocate_reload_reg (chain, r, last_reload, noerror)
       if (count < n_spills)
        break;
     }
-
+    
   /* We should have found a spill register by now.  */
-  if (count == n_spills)
-    {
-      if (noerror)
-       return 0;
-      goto failure;
-    }
+  if (count >= n_spills)
+    return 0;
 
   /* I is the index in SPILL_REG_RTX of the reload register we are to
      allocate.  Get an rtx for it and find its register number.  */
 
-  new = spill_reg_rtx[i];
-
-  if (new == 0 || GET_MODE (new) != reload_mode[r])
-    spill_reg_rtx[i] = new
-      = gen_rtx_REG (reload_mode[r], spill_regs[i]);
-
-  regno = true_regnum (new);
-
-  /* Detect when the reload reg can't hold the reload mode.
-     This used to be one `if', but Sequent compiler can't handle that.  */
-  if (HARD_REGNO_MODE_OK (regno, reload_mode[r]))
-    {
-      enum machine_mode test_mode = VOIDmode;
-      if (reload_in[r])
-       test_mode = GET_MODE (reload_in[r]);
-      /* If reload_in[r] has VOIDmode, it means we will load it
-        in whatever mode the reload reg has: to wit, reload_mode[r].
-        We have already tested that for validity.  */
-      /* Aside from that, we need to test that the expressions
-        to reload from or into have modes which are valid for this
-        reload register.  Otherwise the reload insns would be invalid.  */
-      if (! (reload_in[r] != 0 && test_mode != VOIDmode
-            && ! HARD_REGNO_MODE_OK (regno, test_mode)))
-       if (! (reload_out[r] != 0
-              && ! HARD_REGNO_MODE_OK (regno, GET_MODE (reload_out[r]))))
-         {
-           /* The reg is OK.  */
-           last_spill_reg = i;
-
-           /* Mark as in use for this insn the reload regs we use
-              for this.  */
-           mark_reload_reg_in_use (spill_regs[i], reload_opnum[r],
-                                   reload_when_needed[r], reload_mode[r]);
-
-           reload_reg_rtx[r] = new;
-           reload_spill_index[r] = spill_regs[i];
-           return 1;
-         }
-    }
-
-  /* The reg is not OK.  */
-  if (noerror)
-    return 0;
-
- failure:
-  if (asm_noperands (PATTERN (insn)) < 0)
-    /* It's the compiler's fault.  */
-    fatal_insn ("Could not find a spill register", insn);
-
-  /* It's the user's fault; the operand's mode and constraint
-     don't match.  Disable this reload so we don't crash in final.  */
-  error_for_asm (insn,
-                "`asm' operand constraint incompatible with operand size");
-  reload_in[r] = 0;
-  reload_out[r] = 0;
-  reload_reg_rtx[r] = 0;
-  reload_optional[r] = 1;
-  reload_secondary_p[r] = 1;
-
-  return 1;
+  return set_reload_reg (i, r);
 }
 \f
-/* Assign hard reg targets for the pseudo-registers we must reload
-   into hard regs for this insn.
-   Also output the instructions to copy them in and out of the hard regs.
-
-   For machines with register classes, we are responsible for
-   finding a reload reg in the proper class.  */
-
+/* Initialize all the tables needed to allocate reload registers.
+   CHAIN is the insn currently being processed; SAVE_RELOAD_REG_RTX
+   is the array we use to restore the reg_rtx field for every reload.  */
 static void
-choose_reload_regs (chain)
+choose_reload_regs_init (chain, save_reload_reg_rtx)
      struct insn_chain *chain;
+     rtx *save_reload_reg_rtx;
 {
-  rtx insn = chain->insn;
-  register int i, j;
-  int max_group_size = 1;
-  enum reg_class group_class = NO_REGS;
-  int inheritance;
-  int pass;
+  int i;
 
-  rtx save_reload_reg_rtx[MAX_RELOADS];
-  char save_reload_inherited[MAX_RELOADS];
-  rtx save_reload_inheritance_insn[MAX_RELOADS];
-  rtx save_reload_override_in[MAX_RELOADS];
-  int save_reload_spill_index[MAX_RELOADS];
-  HARD_REG_SET save_reload_reg_used;
-  HARD_REG_SET save_reload_reg_used_in_input_addr[MAX_RECOG_OPERANDS];
-  HARD_REG_SET save_reload_reg_used_in_inpaddr_addr[MAX_RECOG_OPERANDS];
-  HARD_REG_SET save_reload_reg_used_in_output_addr[MAX_RECOG_OPERANDS];
-  HARD_REG_SET save_reload_reg_used_in_outaddr_addr[MAX_RECOG_OPERANDS];
-  HARD_REG_SET save_reload_reg_used_in_input[MAX_RECOG_OPERANDS];
-  HARD_REG_SET save_reload_reg_used_in_output[MAX_RECOG_OPERANDS];
-  HARD_REG_SET save_reload_reg_used_in_op_addr;
-  HARD_REG_SET save_reload_reg_used_in_op_addr_reload;
-  HARD_REG_SET save_reload_reg_used_in_insn;
-  HARD_REG_SET save_reload_reg_used_in_other_addr;
-  HARD_REG_SET save_reload_reg_used_at_all;
+  for (i = 0; i < n_reloads; i++)
+    rld[i].reg_rtx = save_reload_reg_rtx[i];
 
   bzero (reload_inherited, MAX_RELOADS);
   bzero ((char *) reload_inheritance_insn, MAX_RELOADS * sizeof (rtx));
@@ -5652,12 +5040,12 @@ choose_reload_regs (chain)
   CLEAR_HARD_REG_SET (reg_used_in_insn);
   {
     HARD_REG_SET tmp;
-    REG_SET_TO_HARD_REG_SET (tmp, chain->live_before);
+    REG_SET_TO_HARD_REG_SET (tmp, chain->live_throughout);
     IOR_HARD_REG_SET (reg_used_in_insn, tmp);
-    REG_SET_TO_HARD_REG_SET (tmp, chain->live_after);
+    REG_SET_TO_HARD_REG_SET (tmp, chain->dead_or_set);
     IOR_HARD_REG_SET (reg_used_in_insn, tmp);
-    compute_use_by_pseudos (&reg_used_in_insn, chain->live_before);
-    compute_use_by_pseudos (&reg_used_in_insn, chain->live_after);
+    compute_use_by_pseudos (&reg_used_in_insn, chain->live_throughout);
+    compute_use_by_pseudos (&reg_used_in_insn, chain->dead_or_set);
   }
   for (i = 0; i < reload_n_operands; i++)
     {
@@ -5671,27 +5059,34 @@ choose_reload_regs (chain)
 
   IOR_COMPL_HARD_REG_SET (reload_reg_used, chain->used_spill_regs);
 
-#if 0  /* Not needed, now that we can always retry without inheritance.  */
-  /* See if we have more mandatory reloads than spill regs.
-     If so, then we cannot risk optimizations that could prevent
-     reloads from sharing one spill register.
+  CLEAR_HARD_REG_SET (reload_reg_used_for_inherit);
 
-     Since we will try finding a better register than reload_reg_rtx
-     unless it is equal to reload_in or reload_out, count such reloads.  */
+  for (i = 0; i < n_reloads; i++)
+    /* If we have already decided to use a certain register,
+       don't use it in another way.  */
+    if (rld[i].reg_rtx)
+      mark_reload_reg_in_use (REGNO (rld[i].reg_rtx), rld[i].opnum,
+                             rld[i].when_needed, rld[i].mode);
+}
 
-  {
-    int tem = 0;
-    for (j = 0; j < n_reloads; j++)
-      if (! reload_optional[j]
-         && (reload_in[j] != 0 || reload_out[j] != 0 || reload_secondary_p[j])
-         && (reload_reg_rtx[j] == 0
-             || (! rtx_equal_p (reload_reg_rtx[j], reload_in[j])
-                 && ! rtx_equal_p (reload_reg_rtx[j], reload_out[j]))))
-       tem++;
-    if (tem > n_spills)
-      must_reuse = 1;
-  }
-#endif
+/* Assign hard reg targets for the pseudo-registers we must reload
+   into hard regs for this insn.
+   Also output the instructions to copy them in and out of the hard regs.
+
+   For machines with register classes, we are responsible for
+   finding a reload reg in the proper class.  */
+
+static void
+choose_reload_regs (chain)
+     struct insn_chain *chain;
+{
+  rtx insn = chain->insn;
+  register int i, j;
+  int max_group_size = 1;
+  enum reg_class group_class = NO_REGS;
+  int pass, win, inheritance;
+
+  rtx save_reload_reg_rtx[MAX_RELOADS];
 
   /* In order to be certain of getting the registers we need,
      we must sort the reloads into order of increasing register class.
@@ -5707,77 +5102,28 @@ choose_reload_regs (chain)
       reload_order[j] = j;
       reload_spill_index[j] = -1;
 
-      reload_mode[j]
-       = ((reload_inmode[j] == VOIDmode
-          || (GET_MODE_SIZE (reload_outmode[j])
-              > GET_MODE_SIZE (reload_inmode[j])))
-          ? reload_outmode[j] : reload_inmode[j]);
-
-      reload_nregs[j] = CLASS_MAX_NREGS (reload_reg_class[j], reload_mode[j]);
-
-      if (reload_nregs[j] > 1)
+      if (rld[j].nregs > 1)
        {
-         max_group_size = MAX (reload_nregs[j], max_group_size);
-         group_class = reg_class_superunion[(int)reload_reg_class[j]][(int)group_class];
+         max_group_size = MAX (rld[j].nregs, max_group_size);
+         group_class = reg_class_superunion[(int)rld[j].class][(int)group_class];
        }
 
-      /* If we have already decided to use a certain register,
-        don't use it in another way.  */
-      if (reload_reg_rtx[j])
-       mark_reload_reg_in_use (REGNO (reload_reg_rtx[j]), reload_opnum[j],
-                               reload_when_needed[j], reload_mode[j]);
+      save_reload_reg_rtx[j] = rld[j].reg_rtx;
     }
 
   if (n_reloads > 1)
     qsort (reload_order, n_reloads, sizeof (short), reload_reg_class_lower);
 
-  bcopy ((char *) reload_reg_rtx, (char *) save_reload_reg_rtx,
-        sizeof reload_reg_rtx);
-  bcopy (reload_inherited, save_reload_inherited, sizeof reload_inherited);
-  bcopy ((char *) reload_inheritance_insn,
-        (char *) save_reload_inheritance_insn,
-        sizeof reload_inheritance_insn);
-  bcopy ((char *) reload_override_in, (char *) save_reload_override_in,
-        sizeof reload_override_in);
-  bcopy ((char *) reload_spill_index, (char *) save_reload_spill_index,
-        sizeof reload_spill_index);
-  COPY_HARD_REG_SET (save_reload_reg_used, reload_reg_used);
-  COPY_HARD_REG_SET (save_reload_reg_used_at_all, reload_reg_used_at_all);
-  COPY_HARD_REG_SET (save_reload_reg_used_in_op_addr,
-                    reload_reg_used_in_op_addr);
-
-  COPY_HARD_REG_SET (save_reload_reg_used_in_op_addr_reload,
-                    reload_reg_used_in_op_addr_reload);
-
-  COPY_HARD_REG_SET (save_reload_reg_used_in_insn,
-                    reload_reg_used_in_insn);
-  COPY_HARD_REG_SET (save_reload_reg_used_in_other_addr,
-                    reload_reg_used_in_other_addr);
-
-  for (i = 0; i < reload_n_operands; i++)
-    {
-      COPY_HARD_REG_SET (save_reload_reg_used_in_output[i],
-                        reload_reg_used_in_output[i]);
-      COPY_HARD_REG_SET (save_reload_reg_used_in_input[i],
-                        reload_reg_used_in_input[i]);
-      COPY_HARD_REG_SET (save_reload_reg_used_in_input_addr[i],
-                        reload_reg_used_in_input_addr[i]);
-      COPY_HARD_REG_SET (save_reload_reg_used_in_inpaddr_addr[i],
-                        reload_reg_used_in_inpaddr_addr[i]);
-      COPY_HARD_REG_SET (save_reload_reg_used_in_output_addr[i],
-                        reload_reg_used_in_output_addr[i]);
-      COPY_HARD_REG_SET (save_reload_reg_used_in_outaddr_addr[i],
-                        reload_reg_used_in_outaddr_addr[i]);
-    }
-
   /* If -O, try first with inheritance, then turning it off.
      If not -O, don't do inheritance.
      Using inheritance when not optimizing leads to paradoxes
      with fp on the 68k: fp numbers (not NaNs) fail to be equal to themselves
      because one side of the comparison might be inherited.  */
-
+  win = 0;
   for (inheritance = optimize > 0; inheritance >= 0; inheritance--)
     {
+      choose_reload_regs_init (chain, save_reload_reg_rtx);
+
       /* Process the reloads in order of preference just found.
         Beyond this point, subregs can be found in reload_reg_rtx.
 
@@ -5796,16 +5142,14 @@ choose_reload_regs (chain)
         Then make a second pass over the reloads to allocate any reloads
         that haven't been given registers yet.  */
 
-      CLEAR_HARD_REG_SET (reload_reg_used_for_inherit);
-
       for (j = 0; j < n_reloads; j++)
        {
          register int r = reload_order[j];
          rtx search_equiv = NULL_RTX;
 
          /* Ignore reloads that got marked inoperative.  */
-         if (reload_out[r] == 0 && reload_in[r] == 0
-             && ! reload_secondary_p[r])
+         if (rld[r].out == 0 && rld[r].in == 0
+             && ! rld[r].secondary_p)
            continue;
 
          /* If find_reloads chose to use reload_in or reload_out as a reload
@@ -5813,11 +5157,11 @@ choose_reload_regs (chain)
             found one since we might save an insn if we find the value lying
             around.
             Try also when reload_in is a pseudo without a hard reg.  */
-         if (reload_in[r] != 0 && reload_reg_rtx[r] != 0
-             && (rtx_equal_p (reload_in[r], reload_reg_rtx[r])
-                 || (rtx_equal_p (reload_out[r], reload_reg_rtx[r])
-                     && GET_CODE (reload_in[r]) != MEM
-                     && true_regnum (reload_in[r]) < FIRST_PSEUDO_REGISTER)))
+         if (rld[r].in != 0 && rld[r].reg_rtx != 0
+             && (rtx_equal_p (rld[r].in, rld[r].reg_rtx)
+                 || (rtx_equal_p (rld[r].out, rld[r].reg_rtx)
+                     && GET_CODE (rld[r].in) != MEM
+                     && true_regnum (rld[r].in) < FIRST_PSEUDO_REGISTER)))
            continue;
 
 #if 0 /* No longer needed for correct operation.
@@ -5826,14 +5170,14 @@ choose_reload_regs (chain)
             until we are sure that any non-optional reloads have been allocated.
             The following code takes advantage of the fact that optional reloads
             are at the end of reload_order.  */
-         if (reload_optional[r] != 0)
+         if (rld[r].optional != 0)
            for (i = 0; i < j; i++)
-             if ((reload_out[reload_order[i]] != 0
-                  || reload_in[reload_order[i]] != 0
-                  || reload_secondary_p[reload_order[i]])
-                 && ! reload_optional[reload_order[i]]
-                 && reload_reg_rtx[reload_order[i]] == 0)
-               allocate_reload_reg (chain, reload_order[i], 0, inheritance);
+             if ((rld[reload_order[i]].out != 0
+                  || rld[reload_order[i]].in != 0
+                  || rld[reload_order[i]].secondary_p)
+                 && ! rld[reload_order[i]].optional
+                 && rld[reload_order[i]].reg_rtx == 0)
+               allocate_reload_reg (chain, reload_order[i], 0);
 #endif
 
          /* First see if this pseudo is already available as reloaded
@@ -5856,51 +5200,51 @@ choose_reload_regs (chain)
              register int regno = -1;
              enum machine_mode mode = VOIDmode;
 
-             if (reload_in[r] == 0)
+             if (rld[r].in == 0)
                ;
-             else if (GET_CODE (reload_in[r]) == REG)
+             else if (GET_CODE (rld[r].in) == REG)
                {
-                 regno = REGNO (reload_in[r]);
-                 mode = GET_MODE (reload_in[r]);
+                 regno = REGNO (rld[r].in);
+                 mode = GET_MODE (rld[r].in);
                }
-             else if (GET_CODE (reload_in_reg[r]) == REG)
+             else if (GET_CODE (rld[r].in_reg) == REG)
                {
-                 regno = REGNO (reload_in_reg[r]);
-                 mode = GET_MODE (reload_in_reg[r]);
+                 regno = REGNO (rld[r].in_reg);
+                 mode = GET_MODE (rld[r].in_reg);
                }
-             else if (GET_CODE (reload_in_reg[r]) == SUBREG
-                      && GET_CODE (SUBREG_REG (reload_in_reg[r])) == REG)
+             else if (GET_CODE (rld[r].in_reg) == SUBREG
+                      && GET_CODE (SUBREG_REG (rld[r].in_reg)) == REG)
                {
-                 word = SUBREG_WORD (reload_in_reg[r]);
-                 regno = REGNO (SUBREG_REG (reload_in_reg[r]));
+                 word = SUBREG_WORD (rld[r].in_reg);
+                 regno = REGNO (SUBREG_REG (rld[r].in_reg));
                  if (regno < FIRST_PSEUDO_REGISTER)
                    regno += word;
-                 mode = GET_MODE (reload_in_reg[r]);
+                 mode = GET_MODE (rld[r].in_reg);
                }
 #ifdef AUTO_INC_DEC
-             else if ((GET_CODE (reload_in_reg[r]) == PRE_INC
-                       || GET_CODE (reload_in_reg[r]) == PRE_DEC
-                       || GET_CODE (reload_in_reg[r]) == POST_INC
-                       || GET_CODE (reload_in_reg[r]) == POST_DEC)
-                      && GET_CODE (XEXP (reload_in_reg[r], 0)) == REG)
+             else if ((GET_CODE (rld[r].in_reg) == PRE_INC
+                       || GET_CODE (rld[r].in_reg) == PRE_DEC
+                       || GET_CODE (rld[r].in_reg) == POST_INC
+                       || GET_CODE (rld[r].in_reg) == POST_DEC)
+                      && GET_CODE (XEXP (rld[r].in_reg, 0)) == REG)
                {
-                 regno = REGNO (XEXP (reload_in_reg[r], 0));
-                 mode = GET_MODE (XEXP (reload_in_reg[r], 0));
-                 reload_out[r] = reload_in[r];
+                 regno = REGNO (XEXP (rld[r].in_reg, 0));
+                 mode = GET_MODE (XEXP (rld[r].in_reg, 0));
+                 rld[r].out = rld[r].in;
                }
 #endif
 #if 0
              /* This won't work, since REGNO can be a pseudo reg number.
                 Also, it takes much more hair to keep track of all the things
                 that can invalidate an inherited reload of part of a pseudoreg.  */
-             else if (GET_CODE (reload_in[r]) == SUBREG
-                      && GET_CODE (SUBREG_REG (reload_in[r])) == REG)
-               regno = REGNO (SUBREG_REG (reload_in[r])) + SUBREG_WORD (reload_in[r]);
+             else if (GET_CODE (rld[r].in) == SUBREG
+                      && GET_CODE (SUBREG_REG (rld[r].in)) == REG)
+               regno = REGNO (SUBREG_REG (rld[r].in)) + SUBREG_WORD (rld[r].in);
 #endif
 
              if (regno >= 0 && reg_last_reload_reg[regno] != 0)
                {
-                 enum reg_class class = reload_reg_class[r], last_class;
+                 enum reg_class class = rld[r].class, last_class;
                  rtx last_reg = reg_last_reload_reg[regno];
 
                  i = REGNO (last_reg) + word;
@@ -5909,7 +5253,7 @@ choose_reload_regs (chain)
                       >= GET_MODE_SIZE (mode) + word * UNITS_PER_WORD)
                      && reg_reloaded_contents[i] == regno
                      && TEST_HARD_REG_BIT (reg_reloaded_valid, i)
-                     && HARD_REGNO_MODE_OK (i, reload_mode[r])
+                     && HARD_REGNO_MODE_OK (i, rld[r].mode)
                      && (TEST_HARD_REG_BIT (reg_class_contents[(int) class], i)
                          /* Even if we can't use this register as a reload
                             register, we might use it for reload_override_in,
@@ -5928,18 +5272,18 @@ choose_reload_regs (chain)
 #endif
                              ))
 
-                     && (reload_nregs[r] == max_group_size
+                     && (rld[r].nregs == max_group_size
                          || ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class],
                                                  i))
-                     && reload_reg_free_for_value_p (i, reload_opnum[r],
-                                                     reload_when_needed[r],
-                                                     reload_in[r],
+                     && reload_reg_free_for_value_p (i, rld[r].opnum,
+                                                     rld[r].when_needed,
+                                                     rld[r].in,
                                                      const0_rtx, r, 1))
                    {
                      /* If a group is needed, verify that all the subsequent
                         registers still have their values intact.  */
                      int nr
-                       = HARD_REGNO_NREGS (i, reload_mode[r]);
+                       = HARD_REGNO_NREGS (i, rld[r].mode);
                      int k;
 
                      for (k = 1; k < nr; k++)
@@ -5969,28 +5313,26 @@ choose_reload_regs (chain)
 
                          if (i1 != n_earlyclobbers
                              || ! (reload_reg_free_for_value_p
-                                   (i, reload_opnum[r], reload_when_needed[r],
-                                    reload_in[r], reload_out[r], r, 1))
+                                   (i, rld[r].opnum, rld[r].when_needed,
+                                    rld[r].in, rld[r].out, r, 1))
                              /* Don't use it if we'd clobber a pseudo reg.  */
                              || (TEST_HARD_REG_BIT (reg_used_in_insn, i)
-                                 && reload_out[r]
+                                 && rld[r].out
                                  && ! TEST_HARD_REG_BIT (reg_reloaded_dead, i))
                              /* Don't clobber the frame pointer.  */
-                             || (i == HARD_FRAME_POINTER_REGNUM
-                                 && reload_out[r])
+                             || (i == HARD_FRAME_POINTER_REGNUM && rld[r].out)
                              /* Don't really use the inherited spill reg
                                 if we need it wider than we've got it.  */
-                             || (GET_MODE_SIZE (reload_mode[r])
+                             || (GET_MODE_SIZE (rld[r].mode)
                                  > GET_MODE_SIZE (mode))
-                             || ! TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
+                             || ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
                                                      i)
 
                              /* If find_reloads chose reload_out as reload
                                 register, stay with it - that leaves the
                                 inherited register for subsequent reloads.  */
-                             || (reload_out[r] && reload_reg_rtx[r]
-                                 && rtx_equal_p (reload_out[r],
-                                                 reload_reg_rtx[r])))
+                             || (rld[r].out && rld[r].reg_rtx
+                                 && rtx_equal_p (rld[r].out, rld[r].reg_rtx)))
                            {
                              reload_override_in[r] = last_reg;
                              reload_inheritance_insn[r]
@@ -6003,10 +5345,10 @@ choose_reload_regs (chain)
                              /* Mark the register as in use for this part of
                                 the insn.  */
                              mark_reload_reg_in_use (i,
-                                                     reload_opnum[r],
-                                                     reload_when_needed[r],
-                                                     reload_mode[r]);
-                             reload_reg_rtx[r] = last_reg;
+                                                     rld[r].opnum,
+                                                     rld[r].when_needed,
+                                                     rld[r].mode);
+                             rld[r].reg_rtx = last_reg;
                              reload_inherited[r] = 1;
                              reload_inheritance_insn[r]
                                = reg_reloaded_insn[i];
@@ -6022,24 +5364,24 @@ choose_reload_regs (chain)
 
          /* Here's another way to see if the value is already lying around.  */
          if (inheritance
-             && reload_in[r] != 0
+             && rld[r].in != 0
              && ! reload_inherited[r]
-             && reload_out[r] == 0
-             && (CONSTANT_P (reload_in[r])
-                 || GET_CODE (reload_in[r]) == PLUS
-                 || GET_CODE (reload_in[r]) == REG
-                 || GET_CODE (reload_in[r]) == MEM)
-             && (reload_nregs[r] == max_group_size
-                 || ! reg_classes_intersect_p (reload_reg_class[r], group_class)))
-           search_equiv = reload_in[r];
+             && rld[r].out == 0
+             && (CONSTANT_P (rld[r].in)
+                 || GET_CODE (rld[r].in) == PLUS
+                 || GET_CODE (rld[r].in) == REG
+                 || GET_CODE (rld[r].in) == MEM)
+             && (rld[r].nregs == max_group_size
+                 || ! reg_classes_intersect_p (rld[r].class, group_class)))
+           search_equiv = rld[r].in;
          /* If this is an output reload from a simple move insn, look
             if an equivalence for the input is available.  */
-         else if (inheritance && reload_in[r] == 0 && reload_out[r] != 0)
+         else if (inheritance && rld[r].in == 0 && rld[r].out != 0)
            {
              rtx set = single_set (insn);
 
              if (set
-                 && rtx_equal_p (reload_out[r], SET_DEST (set))
+                 && rtx_equal_p (rld[r].out, SET_DEST (set))
                  && CONSTANT_P (SET_SRC (set)))
                search_equiv = SET_SRC (set);
            }
@@ -6047,9 +5389,9 @@ choose_reload_regs (chain)
          if (search_equiv)
            {
              register rtx equiv
-               = find_equiv_reg (search_equiv, insn, reload_reg_class[r],
-                                 -1, NULL_PTR, 0, reload_mode[r]);
-             int regno;
+               = find_equiv_reg (search_equiv, insn, rld[r].class,
+                                 -1, NULL_PTR, 0, rld[r].mode);
+             int regno = 0;
 
              if (equiv != 0)
                {
@@ -6062,7 +5404,7 @@ choose_reload_regs (chain)
                         address and not all machines support SUBREGs
                         there.  */
                      regno = REGNO (SUBREG_REG (equiv)) + SUBREG_WORD (equiv);
-                     equiv = gen_rtx_REG (reload_mode[r], regno);
+                     equiv = gen_rtx_REG (rld[r].mode, regno);
                    }
                  else
                    abort ();
@@ -6072,15 +5414,15 @@ choose_reload_regs (chain)
                 and of the desired class.  */
              if (equiv != 0
                  && ((TEST_HARD_REG_BIT (reload_reg_used_at_all, regno)
-                      && ! reload_reg_free_for_value_p (regno, reload_opnum[r],
-                                                        reload_when_needed[r],
-                                                        reload_in[r],
-                                                        reload_out[r], r, 1))
-                     || ! TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
+                      && ! reload_reg_free_for_value_p (regno, rld[r].opnum,
+                                                        rld[r].when_needed,
+                                                        rld[r].in,
+                                                        rld[r].out, r, 1))
+                     || ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
                                              regno)))
                equiv = 0;
 
-             if (equiv != 0 && ! HARD_REGNO_MODE_OK (regno, reload_mode[r]))
+             if (equiv != 0 && ! HARD_REGNO_MODE_OK (regno, rld[r].mode))
                equiv = 0;
 
              /* We found a register that contains the value we need.
@@ -6106,7 +5448,7 @@ choose_reload_regs (chain)
 
              if (equiv != 0 && regno_clobbered_p (regno, insn))
                {
-                 switch (reload_when_needed[r])
+                 switch (rld[r].when_needed)
                    {
                    case RELOAD_FOR_OTHER_ADDRESS:
                    case RELOAD_FOR_INPADDR_ADDRESS:
@@ -6128,9 +5470,9 @@ choose_reload_regs (chain)
                 to load it, and use it as our reload reg.  */
              if (equiv != 0 && regno != HARD_FRAME_POINTER_REGNUM)
                {
-                 int nr = HARD_REGNO_NREGS (regno, reload_mode[r]);
+                 int nr = HARD_REGNO_NREGS (regno, rld[r].mode);
                  int k;
-                 reload_reg_rtx[r] = equiv;
+                 rld[r].reg_rtx = equiv;
                  reload_inherited[r] = 1;
 
                  /* If reg_reloaded_valid is not set for this register,
@@ -6146,9 +5488,9 @@ choose_reload_regs (chain)
                      i = spill_reg_order[regno + k];
                      if (i >= 0)
                        {
-                         mark_reload_reg_in_use (regno, reload_opnum[r],
-                                                 reload_when_needed[r],
-                                                 reload_mode[r]);
+                         mark_reload_reg_in_use (regno, rld[r].opnum,
+                                                 rld[r].when_needed,
+                                                 rld[r].mode);
                          SET_HARD_REG_BIT (reload_reg_used_for_inherit,
                                            regno + k);
                        }
@@ -6158,7 +5500,7 @@ choose_reload_regs (chain)
 
          /* If we found a register to use already, or if this is an optional
             reload, we are done.  */
-         if (reload_reg_rtx[r] != 0 || reload_optional[r] != 0)
+         if (rld[r].reg_rtx != 0 || rld[r].optional != 0)
            continue;
 
 #if 0 /* No longer needed for correct operation.  Might or might not
@@ -6177,22 +5519,22 @@ choose_reload_regs (chain)
            {
              int s = reload_order[i];
 
-             if ((reload_in[s] == 0 && reload_out[s] == 0
-                  && ! reload_secondary_p[s])
-                 || reload_optional[s])
+             if ((rld[s].in == 0 && rld[s].out == 0
+                  && ! rld[s].secondary_p)
+                 || rld[s].optional)
                continue;
 
-             if ((reload_reg_class[s] != reload_reg_class[r]
-                  && reg_classes_intersect_p (reload_reg_class[r],
-                                              reload_reg_class[s]))
-                 || reload_nregs[s] < reload_nregs[r])
+             if ((rld[s].class != rld[r].class
+                  && reg_classes_intersect_p (rld[r].class,
+                                              rld[s].class))
+                 || rld[s].nregs < rld[r].nregs)
                break;
            }
 
          if (i == n_reloads)
            continue;
 
-         allocate_reload_reg (chain, r, j == n_reloads - 1, inheritance);
+         allocate_reload_reg (chain, r, j == n_reloads - 1);
 #endif
        }
 
@@ -6203,61 +5545,49 @@ choose_reload_regs (chain)
          register int r = reload_order[j];
 
          /* Ignore reloads that got marked inoperative.  */
-         if (reload_out[r] == 0 && reload_in[r] == 0 && ! reload_secondary_p[r])
+         if (rld[r].out == 0 && rld[r].in == 0 && ! rld[r].secondary_p)
            continue;
 
          /* Skip reloads that already have a register allocated or are
             optional.  */
-         if (reload_reg_rtx[r] != 0 || reload_optional[r])
+         if (rld[r].reg_rtx != 0 || rld[r].optional)
            continue;
 
-         if (! allocate_reload_reg (chain, r, j == n_reloads - 1, inheritance))
+         if (! allocate_reload_reg (chain, r, j == n_reloads - 1))
            break;
        }
 
       /* If that loop got all the way, we have won.  */
       if (j == n_reloads)
-       break;
+       {
+         win = 1;
+         break;
+       }
 
       /* Loop around and try without any inheritance.  */
+    }
+
+  if (! win)
+    {
       /* First undo everything done by the failed attempt
         to allocate with inheritance.  */
-      bcopy ((char *) save_reload_reg_rtx, (char *) reload_reg_rtx,
-            sizeof reload_reg_rtx);
-      bcopy ((char *) save_reload_inherited, (char *) reload_inherited,
-            sizeof reload_inherited);
-      bcopy ((char *) save_reload_inheritance_insn,
-            (char *) reload_inheritance_insn,
-            sizeof reload_inheritance_insn);
-      bcopy ((char *) save_reload_override_in, (char *) reload_override_in,
-            sizeof reload_override_in);
-      bcopy ((char *) save_reload_spill_index, (char *) reload_spill_index,
-            sizeof reload_spill_index);
-      COPY_HARD_REG_SET (reload_reg_used, save_reload_reg_used);
-      COPY_HARD_REG_SET (reload_reg_used_at_all, save_reload_reg_used_at_all);
-      COPY_HARD_REG_SET (reload_reg_used_in_op_addr,
-                        save_reload_reg_used_in_op_addr);
-      COPY_HARD_REG_SET (reload_reg_used_in_op_addr_reload,
-                        save_reload_reg_used_in_op_addr_reload);
-      COPY_HARD_REG_SET (reload_reg_used_in_insn,
-                        save_reload_reg_used_in_insn);
-      COPY_HARD_REG_SET (reload_reg_used_in_other_addr,
-                        save_reload_reg_used_in_other_addr);
+      choose_reload_regs_init (chain, save_reload_reg_rtx);
 
-      for (i = 0; i < reload_n_operands; i++)
+      /* Some sanity tests to verify that the reloads found in the first
+        pass are identical to the ones we have now.  */
+      if (chain->n_reloads != n_reloads)
+       abort ();
+
+      for (i = 0; i < n_reloads; i++)
        {
-         COPY_HARD_REG_SET (reload_reg_used_in_input[i],
-                            save_reload_reg_used_in_input[i]);
-         COPY_HARD_REG_SET (reload_reg_used_in_output[i],
-                            save_reload_reg_used_in_output[i]);
-         COPY_HARD_REG_SET (reload_reg_used_in_input_addr[i],
-                            save_reload_reg_used_in_input_addr[i]);
-         COPY_HARD_REG_SET (reload_reg_used_in_inpaddr_addr[i],
-                            save_reload_reg_used_in_inpaddr_addr[i]);
-         COPY_HARD_REG_SET (reload_reg_used_in_output_addr[i],
-                            save_reload_reg_used_in_output_addr[i]);
-         COPY_HARD_REG_SET (reload_reg_used_in_outaddr_addr[i],
-                            save_reload_reg_used_in_outaddr_addr[i]);
+         if (chain->rld[i].regno < 0 || chain->rld[i].reg_rtx != 0)
+           continue;
+         if (chain->rld[i].when_needed != rld[i].when_needed)
+           abort ();
+         for (j = 0; j < n_spills; j++)
+           if (spill_regs[j] == chain->rld[i].regno)
+             if (! set_reload_reg (j, i))
+               failed_reload (chain->insn, i);
        }
     }
 
@@ -6275,8 +5605,8 @@ choose_reload_regs (chain)
        {
          register int r = reload_order[j];
          rtx check_reg;
-         if (reload_inherited[r] && reload_reg_rtx[r])
-           check_reg = reload_reg_rtx[r];
+         if (reload_inherited[r] && rld[r].reg_rtx)
+           check_reg = rld[r].reg_rtx;
          else if (reload_override_in[r]
                   && (GET_CODE (reload_override_in[r]) == REG
                       || GET_CODE (reload_override_in[r]) == SUBREG))
@@ -6284,11 +5614,11 @@ choose_reload_regs (chain)
          else
            continue;
          if (! reload_reg_free_for_value_p (true_regnum (check_reg),
-                                            reload_opnum[r],
-                                            reload_when_needed[r],
-                                            reload_in[r],
+                                            rld[r].opnum,
+                                            rld[r].when_needed,
+                                            rld[r].in,
                                             (reload_inherited[r]
-                                             ? reload_out[r] : const0_rtx),
+                                             ? rld[r].out : const0_rtx),
                                             r, 1))
            {
              if (pass)
@@ -6308,9 +5638,9 @@ choose_reload_regs (chain)
             If we suceeded removing some reload and we are doing a preliminary
             pass just to remove such reloads, make another pass, since the
             removal of one reload might allow us to inherit another one.  */
-         else if (reload_in[r]
-                  && reload_out[r] != reload_in[r]
-                  && remove_address_replacements (reload_in[r]) && pass)
+         else if (rld[r].in
+                  && rld[r].out != rld[r].in
+                  && remove_address_replacements (rld[r].in) && pass)
            pass = 2;
        }
     }
@@ -6319,23 +5649,23 @@ choose_reload_regs (chain)
      actually override reload_in.  */
   for (j = 0; j < n_reloads; j++)
     if (reload_override_in[j])
-      reload_in[j] = reload_override_in[j];
+      rld[j].in = reload_override_in[j];
 
   /* If this reload won't be done because it has been cancelled or is
      optional and not inherited, clear reload_reg_rtx so other
      routines (such as subst_reloads) don't get confused.  */
   for (j = 0; j < n_reloads; j++)
-    if (reload_reg_rtx[j] != 0
-       && ((reload_optional[j] && ! reload_inherited[j])
-           || (reload_in[j] == 0 && reload_out[j] == 0
-               && ! reload_secondary_p[j])))
+    if (rld[j].reg_rtx != 0
+       && ((rld[j].optional && ! reload_inherited[j])
+           || (rld[j].in == 0 && rld[j].out == 0
+               && ! rld[j].secondary_p)))
       {
-       int regno = true_regnum (reload_reg_rtx[j]);
+       int regno = true_regnum (rld[j].reg_rtx);
 
        if (spill_reg_order[regno] >= 0)
-         clear_reload_reg_in_use (regno, reload_opnum[j],
-                                  reload_when_needed[j], reload_mode[j]);
-       reload_reg_rtx[j] = 0;
+         clear_reload_reg_in_use (regno, rld[j].opnum,
+                                  rld[j].when_needed, rld[j].mode);
+       rld[j].reg_rtx = 0;
       }
 
   /* Record which pseudos and which spill regs have output reloads.  */
@@ -6346,30 +5676,30 @@ choose_reload_regs (chain)
       i = reload_spill_index[r];
 
       /* I is nonneg if this reload uses a register.
-        If reload_reg_rtx[r] is 0, this is an optional reload
+        If rld[r].reg_rtx is 0, this is an optional reload
         that we opted to ignore.  */
-      if (reload_out_reg[r] != 0 && GET_CODE (reload_out_reg[r]) == REG
-         && reload_reg_rtx[r] != 0)
+      if (rld[r].out_reg != 0 && GET_CODE (rld[r].out_reg) == REG
+         && rld[r].reg_rtx != 0)
        {
-         register int nregno = REGNO (reload_out_reg[r]);
+         register int nregno = REGNO (rld[r].out_reg);
          int nr = 1;
 
          if (nregno < FIRST_PSEUDO_REGISTER)
-           nr = HARD_REGNO_NREGS (nregno, reload_mode[r]);
+           nr = HARD_REGNO_NREGS (nregno, rld[r].mode);
 
          while (--nr >= 0)
            reg_has_output_reload[nregno + nr] = 1;
 
          if (i >= 0)
            {
-             nr = HARD_REGNO_NREGS (i, reload_mode[r]);
+             nr = HARD_REGNO_NREGS (i, rld[r].mode);
              while (--nr >= 0)
                SET_HARD_REG_BIT (reg_is_output_reload, i + nr);
            }
 
-         if (reload_when_needed[r] != RELOAD_OTHER
-             && reload_when_needed[r] != RELOAD_FOR_OUTPUT
-             && reload_when_needed[r] != RELOAD_FOR_INSN)
+         if (rld[r].when_needed != RELOAD_OTHER
+             && rld[r].when_needed != RELOAD_FOR_OUTPUT
+             && rld[r].when_needed != RELOAD_FOR_INSN)
            abort ();
        }
     }
@@ -6383,13 +5713,13 @@ deallocate_reload_reg (r)
 {
   int regno;
 
-  if (! reload_reg_rtx[r])
+  if (! rld[r].reg_rtx)
     return;
-  regno = true_regnum (reload_reg_rtx[r]);
-  reload_reg_rtx[r] = 0;
+  regno = true_regnum (rld[r].reg_rtx);
+  rld[r].reg_rtx = 0;
   if (spill_reg_order[regno] >= 0)
-    clear_reload_reg_in_use (regno, reload_opnum[r], reload_when_needed[r],
-                            reload_mode[r]);
+    clear_reload_reg_in_use (regno, rld[r].opnum, rld[r].when_needed,
+                            rld[r].mode);
   reload_spill_index[r] = -1;
 }
 \f
@@ -6422,9 +5752,9 @@ merge_assigned_reloads (insn)
       int max_input_address_opnum = -1;
       int min_conflicting_input_opnum = MAX_RECOG_OPERANDS;
 
-      if (reload_in[i] == 0 || reload_when_needed[i] == RELOAD_OTHER
-         || reload_out[i] != 0 || reload_reg_rtx[i] == 0
-         || reg_set_p (reload_reg_rtx[i], insn))
+      if (rld[i].in == 0 || rld[i].when_needed == RELOAD_OTHER
+         || rld[i].out != 0 || rld[i].reg_rtx == 0
+         || reg_set_p (rld[i].reg_rtx, insn))
        continue;
 
       /* Look at all other reloads.  Ensure that the only use of this
@@ -6435,32 +5765,32 @@ merge_assigned_reloads (insn)
 
       for (j = 0; j < n_reloads; j++)
        {
-         if (i == j || reload_reg_rtx[j] == 0
-             || ! reg_overlap_mentioned_p (reload_reg_rtx[j],
-                                           reload_reg_rtx[i]))
+         if (i == j || rld[j].reg_rtx == 0
+             || ! reg_overlap_mentioned_p (rld[j].reg_rtx,
+                                           rld[i].reg_rtx))
            continue;
 
-         if (reload_when_needed[j] == RELOAD_FOR_INPUT_ADDRESS
-             && reload_opnum[j] > max_input_address_opnum)
-           max_input_address_opnum = reload_opnum[j];
+         if (rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS
+             && rld[j].opnum > max_input_address_opnum)
+           max_input_address_opnum = rld[j].opnum;
 
          /* If the reload regs aren't exactly the same (e.g, different modes)
             or if the values are different, we can't merge this reload.
             But if it is an input reload, we might still merge
             RELOAD_FOR_INPUT_ADDRESS and RELOAD_FOR_OTHER_ADDRESS reloads.  */
 
-         if (! rtx_equal_p (reload_reg_rtx[i], reload_reg_rtx[j])
-             || reload_out[j] != 0 || reload_in[j] == 0
-             || ! rtx_equal_p (reload_in[i], reload_in[j]))
+         if (! rtx_equal_p (rld[i].reg_rtx, rld[j].reg_rtx)
+             || rld[j].out != 0 || rld[j].in == 0
+             || ! rtx_equal_p (rld[i].in, rld[j].in))
            {
-             if (reload_when_needed[j] != RELOAD_FOR_INPUT
-                 || ((reload_when_needed[i] != RELOAD_FOR_INPUT_ADDRESS
-                      || reload_opnum[i] > reload_opnum[j])
-                     && reload_when_needed[i] != RELOAD_FOR_OTHER_ADDRESS))
+             if (rld[j].when_needed != RELOAD_FOR_INPUT
+                 || ((rld[i].when_needed != RELOAD_FOR_INPUT_ADDRESS
+                      || rld[i].opnum > rld[j].opnum)
+                     && rld[i].when_needed != RELOAD_FOR_OTHER_ADDRESS))
                break;
              conflicting_input = 1;
-             if (min_conflicting_input_opnum > reload_opnum[j])
-               min_conflicting_input_opnum = reload_opnum[j];
+             if (min_conflicting_input_opnum > rld[j].opnum)
+               min_conflicting_input_opnum = rld[j].opnum;
            }
        }
 
@@ -6471,14 +5801,14 @@ merge_assigned_reloads (insn)
          && max_input_address_opnum <= min_conflicting_input_opnum)
        {
          for (j = 0; j < n_reloads; j++)
-           if (i != j && reload_reg_rtx[j] != 0
-               && rtx_equal_p (reload_reg_rtx[i], reload_reg_rtx[j])
+           if (i != j && rld[j].reg_rtx != 0
+               && rtx_equal_p (rld[i].reg_rtx, rld[j].reg_rtx)
                && (! conflicting_input
-                   || reload_when_needed[j] == RELOAD_FOR_INPUT_ADDRESS
-                   || reload_when_needed[j] == RELOAD_FOR_OTHER_ADDRESS))
+                   || rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS
+                   || rld[j].when_needed == RELOAD_FOR_OTHER_ADDRESS))
              {
-               reload_when_needed[i] = RELOAD_OTHER;
-               reload_in[j] = 0;
+               rld[i].when_needed = RELOAD_OTHER;
+               rld[j].in = 0;
                reload_spill_index[j] = -1;
                transfer_replacements (i, j);
              }
@@ -6489,15 +5819,15 @@ merge_assigned_reloads (insn)
             this test is equivalent to looking for reloads for this operand
             number.  */
 
-         if (reload_when_needed[i] == RELOAD_OTHER)
+         if (rld[i].when_needed == RELOAD_OTHER)
            for (j = 0; j < n_reloads; j++)
-             if (reload_in[j] != 0
-                 && reload_when_needed[i] != RELOAD_OTHER
-                 && reg_overlap_mentioned_for_reload_p (reload_in[j],
-                                                        reload_in[i]))
-               reload_when_needed[j]
-                 = ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
-                     || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS)
+             if (rld[j].in != 0
+                 && rld[i].when_needed != RELOAD_OTHER
+                 && reg_overlap_mentioned_for_reload_p (rld[j].in,
+                                                        rld[i].in))
+               rld[j].when_needed
+                 = ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
+                     || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS)
                     ? RELOAD_FOR_OTHER_ADDRESS : RELOAD_OTHER);
        }
     }
@@ -6552,28 +5882,28 @@ emit_reload_insns (chain)
       rtx this_reload_insn = 0;
       int expect_occurrences = 1;
 
-      if (reload_reg_rtx[j]
-         && REGNO (reload_reg_rtx[j]) < FIRST_PSEUDO_REGISTER)
-       new_spill_reg_store[REGNO (reload_reg_rtx[j])] = 0;
+      if (rld[j].reg_rtx
+         && REGNO (rld[j].reg_rtx) < FIRST_PSEUDO_REGISTER)
+       new_spill_reg_store[REGNO (rld[j].reg_rtx)] = 0;
 
-      old = (reload_in[j] && GET_CODE (reload_in[j]) == MEM
-            ? reload_in_reg[j] : reload_in[j]);
+      old = (rld[j].in && GET_CODE (rld[j].in) == MEM
+            ? rld[j].in_reg : rld[j].in);
 
       if (old != 0
          /* AUTO_INC reloads need to be handled even if inherited.  We got an
             AUTO_INC reload if reload_out is set but reload_out_reg isn't.  */
-         && (! reload_inherited[j] || (reload_out[j] && ! reload_out_reg[j]))
-         && ! rtx_equal_p (reload_reg_rtx[j], old)
-         && reload_reg_rtx[j] != 0)
+         && (! reload_inherited[j] || (rld[j].out && ! rld[j].out_reg))
+         && ! rtx_equal_p (rld[j].reg_rtx, old)
+         && rld[j].reg_rtx != 0)
        {
-         register rtx reloadreg = reload_reg_rtx[j];
+         register rtx reloadreg = rld[j].reg_rtx;
          rtx oldequiv = 0;
          enum machine_mode mode;
          rtx *where;
 
          /* Determine the mode to reload in.
             This is very tricky because we have three to choose from.
-            There is the mode the insn operand wants (reload_inmode[J]).
+            There is the mode the insn operand wants (rld[J].inmode).
             There is the mode of the reload register RELOADREG.
             There is the intrinsic mode of the operand, which we could find
             by stripping some SUBREGs.
@@ -6605,7 +5935,7 @@ emit_reload_insns (chain)
 
          mode = GET_MODE (old);
          if (mode == VOIDmode)
-           mode = reload_inmode[j];
+           mode = rld[j].inmode;
 
 #ifdef SECONDARY_INPUT_RELOAD_CLASS
          /* If we need a secondary register for this operation, see if
@@ -6613,12 +5943,12 @@ emit_reload_insns (chain)
             do this if the secondary register will be used as a scratch
             register.  */
 
-         if (reload_secondary_in_reload[j] >= 0
-             && reload_secondary_in_icode[j] == CODE_FOR_nothing
+         if (rld[j].secondary_in_reload >= 0
+             && rld[j].secondary_in_icode == CODE_FOR_nothing
              && optimize)
            oldequiv
              = find_equiv_reg (old, insn,
-                               reload_reg_class[reload_secondary_in_reload[j]],
+                               rld[rld[j].secondary_in_reload].class,
                                -1, NULL_PTR, 0, mode);
 #endif
 
@@ -6644,9 +5974,9 @@ emit_reload_insns (chain)
 
              /* Don't use OLDEQUIV if any other reload changes it at an
                 earlier stage of this insn or at this stage.  */
-             if (! reload_reg_free_for_value_p (regno, reload_opnum[j],
-                                                reload_when_needed[j],
-                                                reload_in[j], const0_rtx, j,
+             if (! reload_reg_free_for_value_p (regno, rld[j].opnum,
+                                                rld[j].when_needed,
+                                                rld[j].in, const0_rtx, j,
                                                 0))
                oldequiv = 0;
 
@@ -6656,18 +5986,18 @@ emit_reload_insns (chain)
                 or memory.   */
 
              if (oldequiv != 0
-                 && ((REGNO_REG_CLASS (regno) != reload_reg_class[j]
+                 && ((REGNO_REG_CLASS (regno) != rld[j].class
                       && (REGISTER_MOVE_COST (REGNO_REG_CLASS (regno),
-                                              reload_reg_class[j])
-                          >= MEMORY_MOVE_COST (mode, reload_reg_class[j], 1)))
+                                              rld[j].class)
+                          >= MEMORY_MOVE_COST (mode, rld[j].class, 1)))
 #ifdef SECONDARY_INPUT_RELOAD_CLASS
-                     || (SECONDARY_INPUT_RELOAD_CLASS (reload_reg_class[j],
+                     || (SECONDARY_INPUT_RELOAD_CLASS (rld[j].class,
                                                        mode, oldequiv)
                          != NO_REGS)
 #endif
 #ifdef SECONDARY_MEMORY_NEEDED
                      || SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (regno),
-                                                 reload_reg_class[j],
+                                                 rld[j].class,
                                                  mode)
 #endif
                      ))
@@ -6680,10 +6010,10 @@ emit_reload_insns (chain)
             find the pseudo in RELOAD_IN_REG.  */
          if (oldequiv == 0
              && reload_override_in[j]
-             && GET_CODE (reload_in_reg[j]) == REG)
+             && GET_CODE (rld[j].in_reg) == REG)
            {
              oldequiv = old;
-             old = reload_in_reg[j];
+             old = rld[j].in_reg;
            }
          if (oldequiv == 0)
            oldequiv = old;
@@ -6702,7 +6032,7 @@ emit_reload_insns (chain)
              && GET_CODE (old) == REG
              && (dead_or_set_p (insn, spill_reg_stored_to[REGNO (oldequiv)])
                  || rtx_equal_p (spill_reg_stored_to[REGNO (oldequiv)],
-                                 reload_out_reg[j])))
+                                 rld[j].out_reg)))
            delete_output_reload (insn, j, REGNO (oldequiv));
 
          /* Encapsulate both RELOADREG and OLDEQUIV into that mode,
@@ -6720,25 +6050,25 @@ emit_reload_insns (chain)
            oldequiv = gen_rtx_SUBREG (mode, oldequiv, 0);
 
          /* Switch to the right place to emit the reload insns.  */
-         switch (reload_when_needed[j])
+         switch (rld[j].when_needed)
            {
            case RELOAD_OTHER:
              where = &other_input_reload_insns;
              break;
            case RELOAD_FOR_INPUT:
-             where = &input_reload_insns[reload_opnum[j]];
+             where = &input_reload_insns[rld[j].opnum];
              break;
            case RELOAD_FOR_INPUT_ADDRESS:
-             where = &input_address_reload_insns[reload_opnum[j]];
+             where = &input_address_reload_insns[rld[j].opnum];
              break;
            case RELOAD_FOR_INPADDR_ADDRESS:
-             where = &inpaddr_address_reload_insns[reload_opnum[j]];
+             where = &inpaddr_address_reload_insns[rld[j].opnum];
              break;
            case RELOAD_FOR_OUTPUT_ADDRESS:
-             where = &output_address_reload_insns[reload_opnum[j]];
+             where = &output_address_reload_insns[rld[j].opnum];
              break;
            case RELOAD_FOR_OUTADDR_ADDRESS:
-             where = &outaddr_address_reload_insns[reload_opnum[j]];
+             where = &outaddr_address_reload_insns[rld[j].opnum];
              break;
            case RELOAD_FOR_OPERAND_ADDRESS:
              where = &operand_reload_insns;
@@ -6757,18 +6087,18 @@ emit_reload_insns (chain)
          special = 0;
 
          /* Auto-increment addresses must be reloaded in a special way.  */
-         if (reload_out[j] && ! reload_out_reg[j])
+         if (rld[j].out && ! rld[j].out_reg)
            {
              /* We are not going to bother supporting the case where a
                 incremented register can't be copied directly from
                 OLDEQUIV since this seems highly unlikely.  */
-             if (reload_secondary_in_reload[j] >= 0)
+             if (rld[j].secondary_in_reload >= 0)
                abort ();
 
              if (reload_inherited[j])
                oldequiv = reloadreg;
 
-             old = XEXP (reload_in_reg[j], 0);
+             old = XEXP (rld[j].in_reg, 0);
 
              if (optimize && GET_CODE (oldequiv) == REG
                  && REGNO (oldequiv) < FIRST_PSEUDO_REGISTER
@@ -6784,8 +6114,8 @@ emit_reload_insns (chain)
              special = 1;
              /* Output a special code sequence for this case.  */
              new_spill_reg_store[REGNO (reloadreg)]
-               = inc_for_reload (reloadreg, oldequiv, reload_out[j],
-                                 reload_inc[j]);
+               = inc_for_reload (reloadreg, oldequiv, rld[j].out,
+                                 rld[j].inc);
            }
 
          /* If we are reloading a pseudo-register that was set by the previous
@@ -6798,9 +6128,9 @@ emit_reload_insns (chain)
                   /* This is unsafe if some other reload
                      uses the same reg first.  */
                   && reload_reg_free_for_value_p (REGNO (reloadreg),
-                                                  reload_opnum[j],
-                                                  reload_when_needed[j],
-                                                  old, reload_out[j],
+                                                  rld[j].opnum,
+                                                  rld[j].when_needed,
+                                                  old, rld[j].out,
                                                   j, 0))
            {
              rtx temp = PREV_INSN (insn);
@@ -6813,7 +6143,7 @@ emit_reload_insns (chain)
                  /* Make sure we can access insn_operand_constraint.  */
                  && asm_noperands (PATTERN (temp)) < 0
                  /* This is unsafe if prev insn rejects our reload reg.  */
-                 && constraint_accepts_reg_p (insn_operand_constraint[recog_memoized (temp)][0],
+                 && constraint_accepts_reg_p (insn_data[recog_memoized (temp)].operand[0].constraint,
                                               reloadreg)
                  /* This is unsafe if operand occurs more than once in current
                     insn.  Perhaps some occurrences aren't reloaded.  */
@@ -6840,7 +6170,7 @@ emit_reload_insns (chain)
                  if (REG_N_DEATHS (REGNO (old)) == 1
                      && REG_N_SETS (REGNO (old)) == 1)
                    {
-                     reg_renumber[REGNO (old)] = REGNO (reload_reg_rtx[j]);
+                     reg_renumber[REGNO (old)] = REGNO (rld[j].reg_rtx);
                      alter_reg (REGNO (old), -1);
                    }
                  special = 1;
@@ -6866,9 +6196,9 @@ emit_reload_insns (chain)
                 because we don't make such reloads when both the input and
                 output need secondary reload registers.  */
 
-             if (reload_secondary_in_reload[j] >= 0)
+             if (rld[j].secondary_in_reload >= 0)
                {
-                 int secondary_reload = reload_secondary_in_reload[j];
+                 int secondary_reload = rld[j].secondary_in_reload;
                  rtx real_oldequiv = oldequiv;
                  rtx real_old = old;
                  rtx tmp;
@@ -6897,7 +6227,7 @@ emit_reload_insns (chain)
                      if (! reg_equiv_mem[REGNO (tmp)]
                          || num_not_at_initial_offset
                          || GET_CODE (oldequiv) == SUBREG)
-                       real_oldequiv = reload_in[j];
+                       real_oldequiv = rld[j].in;
                      else
                        real_oldequiv = reg_equiv_mem[REGNO (tmp)];
                    }
@@ -6913,19 +6243,19 @@ emit_reload_insns (chain)
                      if (! reg_equiv_mem[REGNO (tmp)]
                          || num_not_at_initial_offset
                          || GET_CODE (old) == SUBREG)
-                       real_old = reload_in[j];
+                       real_old = rld[j].in;
                      else
                        real_old = reg_equiv_mem[REGNO (tmp)];
                    }
 
-                 second_reload_reg = reload_reg_rtx[secondary_reload];
-                 icode = reload_secondary_in_icode[j];
+                 second_reload_reg = rld[secondary_reload].reg_rtx;
+                 icode = rld[j].secondary_in_icode;
 
                  if ((old != oldequiv && ! rtx_equal_p (old, oldequiv))
-                     || (reload_in[j] != 0 && reload_out[j] != 0))
+                     || (rld[j].in != 0 && rld[j].out != 0))
                    {
                      enum reg_class new_class
-                       = SECONDARY_INPUT_RELOAD_CLASS (reload_reg_class[j],
+                       = SECONDARY_INPUT_RELOAD_CLASS (rld[j].class,
                                                        mode, real_oldequiv);
 
                      if (new_class == NO_REGS)
@@ -6942,18 +6272,18 @@ emit_reload_insns (chain)
                            {
                              new_icode = reload_in_optab[(int) mode];
                              if (new_icode != CODE_FOR_nothing
-                                 && ((insn_operand_predicate[(int) new_icode][0]
-                                      && ! ((*insn_operand_predicate[(int) new_icode][0])
+                                 && ((insn_data[(int) new_icode].operand[0].predicate
+                                      && ! ((*insn_data[(int) new_icode].operand[0].predicate)
                                             (reloadreg, mode)))
-                                     || (insn_operand_predicate[(int) new_icode][1]
-                                         && ! ((*insn_operand_predicate[(int) new_icode][1])
+                                     || (insn_data[(int) new_icode].operand[1].predicate
+                                         && ! ((*insn_data[(int) new_icode].operand[1].predicate)
                                                (real_oldequiv, mode)))))
                                new_icode = CODE_FOR_nothing;
 
                              if (new_icode == CODE_FOR_nothing)
                                new_mode = mode;
                              else
-                               new_mode = insn_operand_mode[(int) new_icode][2];
+                               new_mode = insn_data[(int) new_icode].operand[2].mode;
 
                              if (GET_MODE (second_reload_reg) != new_mode)
                                {
@@ -6989,12 +6319,12 @@ emit_reload_insns (chain)
                          /* See if we need a scratch register to load the
                             intermediate register (a tertiary reload).  */
                          enum insn_code tertiary_icode
-                           = reload_secondary_in_icode[secondary_reload];
+                           = rld[secondary_reload].secondary_in_icode;
 
                          if (tertiary_icode != CODE_FOR_nothing)
                            {
                              rtx third_reload_reg
-                               = reload_reg_rtx[reload_secondary_in_reload[secondary_reload]];
+                               = rld[rld[secondary_reload].secondary_in_reload].reg_rtx;
 
                              emit_insn ((GEN_FCN (tertiary_icode)
                                          (second_reload_reg, real_oldequiv,
@@ -7002,8 +6332,8 @@ emit_reload_insns (chain)
                            }
                          else
                            gen_reload (second_reload_reg, real_oldequiv,
-                                       reload_opnum[j],
-                                       reload_when_needed[j]);
+                                       rld[j].opnum,
+                                       rld[j].when_needed);
 
                          oldequiv = second_reload_reg;
                        }
@@ -7027,9 +6357,9 @@ emit_reload_insns (chain)
                               [REGNO (SUBREG_REG (oldequiv))] != 0)
                              || (reg_equiv_constant
                                  [REGNO (SUBREG_REG (oldequiv))] != 0))))
-                   real_oldequiv = reload_in[j];
-                 gen_reload (reloadreg, real_oldequiv, reload_opnum[j],
-                             reload_when_needed[j]);
+                   real_oldequiv = rld[j].in;
+                 gen_reload (reloadreg, real_oldequiv, rld[j].opnum,
+                             rld[j].when_needed);
                }
 
            }
@@ -7045,18 +6375,18 @@ emit_reload_insns (chain)
            reload_override_in[j] = oldequiv;
        }
 
-      /* When inheriting a wider reload, we have a MEM in reload_in[j],
+      /* When inheriting a wider reload, we have a MEM in rld[j].in,
         e.g. inheriting a SImode output reload for
         (mem:HI (plus:SI (reg:SI 14 fp) (const_int 10)))  */
-      if (optimize && reload_inherited[j] && reload_in[j]
-         && GET_CODE (reload_in[j]) == MEM
-         && GET_CODE (reload_in_reg[j]) == MEM
+      if (optimize && reload_inherited[j] && rld[j].in
+         && GET_CODE (rld[j].in) == MEM
+         && GET_CODE (rld[j].in_reg) == MEM
          && reload_spill_index[j] >= 0
          && TEST_HARD_REG_BIT (reg_reloaded_valid, reload_spill_index[j]))
        {
          expect_occurrences
-           = count_occurrences (PATTERN (insn), reload_in[j]) == 1 ? 0 : -1;
-         reload_in[j]
+           = count_occurrences (PATTERN (insn), rld[j].in) == 1 ? 0 : -1;
+         rld[j].in
            = regno_reg_rtx[reg_reloaded_contents[reload_spill_index[j]]];
        }
 
@@ -7066,28 +6396,28 @@ emit_reload_insns (chain)
 
       if (optimize
          && (reload_inherited[j] || reload_override_in[j])
-         && reload_reg_rtx[j]
-         && GET_CODE (reload_reg_rtx[j]) == REG
-         && spill_reg_store[REGNO (reload_reg_rtx[j])] != 0
+         && rld[j].reg_rtx
+         && GET_CODE (rld[j].reg_rtx) == REG
+         && spill_reg_store[REGNO (rld[j].reg_rtx)] != 0
 #if 0
          /* There doesn't seem to be any reason to restrict this to pseudos
             and doing so loses in the case where we are copying from a
             register of the wrong class.  */
-         && (REGNO (spill_reg_stored_to[REGNO (reload_reg_rtx[j])])
+         && (REGNO (spill_reg_stored_to[REGNO (rld[j].reg_rtx)])
              >= FIRST_PSEUDO_REGISTER)
 #endif
          /* The insn might have already some references to stackslots
             replaced by MEMs, while reload_out_reg still names the
             original pseudo.  */
          && (dead_or_set_p (insn,
-                            spill_reg_stored_to[REGNO (reload_reg_rtx[j])])
-             || rtx_equal_p (spill_reg_stored_to[REGNO (reload_reg_rtx[j])],
-                             reload_out_reg[j])))
-       delete_output_reload (insn, j, REGNO (reload_reg_rtx[j]));
+                            spill_reg_stored_to[REGNO (rld[j].reg_rtx)])
+             || rtx_equal_p (spill_reg_stored_to[REGNO (rld[j].reg_rtx)],
+                             rld[j].out_reg)))
+       delete_output_reload (insn, j, REGNO (rld[j].reg_rtx));
 
       /* Input-reloading is done.  Now do output-reloading,
         storing the value from the reload-register after the main insn
-        if reload_out[j] is nonzero.
+        if rld[j].out is nonzero.
 
         ??? At some point we need to support handling output reloads of
         JUMP_INSNs or insns that set cc0.  */
@@ -7096,11 +6426,11 @@ emit_reload_insns (chain)
         not loaded in this same reload, see if we can eliminate a previous
         store.  */
       {
-       rtx pseudo = reload_out_reg[j];
+       rtx pseudo = rld[j].out_reg;
 
        if (pseudo
            && GET_CODE (pseudo) == REG
-           && ! rtx_equal_p (reload_in_reg[j], pseudo)
+           && ! rtx_equal_p (rld[j].in_reg, pseudo)
            && REGNO (pseudo) >= FIRST_PSEUDO_REGISTER
            && reg_last_reload_reg[REGNO (pseudo)])
          {
@@ -7117,12 +6447,12 @@ emit_reload_insns (chain)
          }
       }
 
-      old = reload_out_reg[j];
+      old = rld[j].out_reg;
       if (old != 0
-         && reload_reg_rtx[j] != old
-         && reload_reg_rtx[j] != 0)
+         && rld[j].reg_rtx != old
+         && rld[j].reg_rtx != 0)
        {
-         register rtx reloadreg = reload_reg_rtx[j];
+         register rtx reloadreg = rld[j].reg_rtx;
 #ifdef SECONDARY_OUTPUT_RELOAD_CLASS
          register rtx second_reloadreg = 0;
 #endif
@@ -7136,7 +6466,7 @@ emit_reload_insns (chain)
          if ((GET_CODE (old) == REG || GET_CODE (old) == SCRATCH)
              && (note = find_reg_note (insn, REG_UNUSED, old)) != 0)
            {
-             XEXP (note, 0) = reload_reg_rtx[j];
+             XEXP (note, 0) = rld[j].reg_rtx;
              continue;
            }
          /* Likewise for a SUBREG of an operand that dies.  */
@@ -7146,7 +6476,7 @@ emit_reload_insns (chain)
                                                  SUBREG_REG (old))))
            {
              XEXP (note, 0) = gen_lowpart_common (GET_MODE (old),
-                                                  reload_reg_rtx[j]);
+                                                  rld[j].reg_rtx);
              continue;
            }
          else if (GET_CODE (old) == SCRATCH)
@@ -7168,12 +6498,12 @@ emit_reload_insns (chain)
          if (GET_CODE (insn) == JUMP_INSN)
            abort ();
 
-         if (reload_when_needed[j] == RELOAD_OTHER)
+         if (rld[j].when_needed == RELOAD_OTHER)
            start_sequence ();
          else
-           push_to_sequence (output_reload_insns[reload_opnum[j]]);
+           push_to_sequence (output_reload_insns[rld[j].opnum]);
 
-         old = reload_out[j];
+         old = rld[j].out;
 
          /* Determine the mode to reload in.
             See comments above (for input reloading).  */
@@ -7200,7 +6530,7 @@ emit_reload_insns (chain)
             one, since it will be stored into OLD.  We might need a secondary
             register only for an input reload, so check again here.  */
 
-         if (reload_secondary_out_reload[j] >= 0)
+         if (rld[j].secondary_out_reload >= 0)
            {
              rtx real_old = old;
 
@@ -7208,18 +6538,18 @@ emit_reload_insns (chain)
                  && reg_equiv_mem[REGNO (old)] != 0)
                real_old = reg_equiv_mem[REGNO (old)];
 
-             if((SECONDARY_OUTPUT_RELOAD_CLASS (reload_reg_class[j],
+             if((SECONDARY_OUTPUT_RELOAD_CLASS (rld[j].class,
                                                 mode, real_old)
                  != NO_REGS))
                {
                  second_reloadreg = reloadreg;
-                 reloadreg = reload_reg_rtx[reload_secondary_out_reload[j]];
+                 reloadreg = rld[rld[j].secondary_out_reload].reg_rtx;
 
                  /* See if RELOADREG is to be used as a scratch register
                     or as an intermediate register.  */
-                 if (reload_secondary_out_icode[j] != CODE_FOR_nothing)
+                 if (rld[j].secondary_out_icode != CODE_FOR_nothing)
                    {
-                     emit_insn ((GEN_FCN (reload_secondary_out_icode[j])
+                     emit_insn ((GEN_FCN (rld[j].secondary_out_icode)
                                  (real_old, second_reloadreg, reloadreg)));
                      special = 1;
                    }
@@ -7228,9 +6558,9 @@ emit_reload_insns (chain)
                      /* See if we need both a scratch and intermediate reload
                         register.  */
 
-                     int secondary_reload = reload_secondary_out_reload[j];
+                     int secondary_reload = rld[j].secondary_out_reload;
                      enum insn_code tertiary_icode
-                       = reload_secondary_out_icode[secondary_reload];
+                       = rld[secondary_reload].secondary_out_icode;
 
                      if (GET_MODE (reloadreg) != mode)
                        reloadreg = gen_rtx_REG (mode, REGNO (reloadreg));
@@ -7238,7 +6568,7 @@ emit_reload_insns (chain)
                      if (tertiary_icode != CODE_FOR_nothing)
                        {
                          rtx third_reloadreg
-                           = reload_reg_rtx[reload_secondary_out_reload[secondary_reload]];
+                           = rld[rld[secondary_reload].secondary_out_reload].reg_rtx;
                          rtx tem;
 
                          /* Copy primary reload reg to secondary reload reg.
@@ -7257,7 +6587,7 @@ emit_reload_insns (chain)
                            real_old = SUBREG_REG (real_old), reloadreg = tem;
 
                          gen_reload (reloadreg, second_reloadreg,
-                                     reload_opnum[j], reload_when_needed[j]);
+                                     rld[j].opnum, rld[j].when_needed);
                          emit_insn ((GEN_FCN (tertiary_icode)
                                      (real_old, reloadreg, third_reloadreg)));
                          special = 1;
@@ -7268,7 +6598,7 @@ emit_reload_insns (chain)
                           OUT later.  */
 
                        gen_reload (reloadreg, second_reloadreg,
-                                   reload_opnum[j], reload_when_needed[j]);
+                                   rld[j].opnum, rld[j].when_needed);
                    }
                }
            }
@@ -7287,8 +6617,8 @@ emit_reload_insns (chain)
                  || rtx_equal_p (old, SET_DEST (set))
                  || !reg_mentioned_p (old, SET_SRC (set))
                  || !regno_clobbered_p (REGNO (old), insn))
-               gen_reload (old, reloadreg, reload_opnum[j],
-                           reload_when_needed[j]);
+               gen_reload (old, reloadreg, rld[j].opnum,
+                           rld[j].when_needed);
            }
 
          /* Look at all insns we emitted, just to be safe.  */
@@ -7301,14 +6631,14 @@ emit_reload_insns (chain)
                   clear any memory of reloaded copies of the pseudo reg.
                   If this output reload comes from a spill reg,
                   reg_has_output_reload will make this do nothing.  */
-               note_stores (pat, forget_old_reloads_1);
+               note_stores (pat, forget_old_reloads_1, NULL);
 
-               if (reg_mentioned_p (reload_reg_rtx[j], pat))
+               if (reg_mentioned_p (rld[j].reg_rtx, pat))
                  {
                    rtx set = single_set (insn);
                    if (reload_spill_index[j] < 0
                        && set
-                       && SET_SRC (set) == reload_reg_rtx[j])
+                       && SET_SRC (set) == rld[j].reg_rtx)
                      {
                        int src = REGNO (SET_SRC (set));
 
@@ -7317,9 +6647,9 @@ emit_reload_insns (chain)
                        if (find_regno_note (insn, REG_DEAD, src))
                          SET_HARD_REG_BIT (reg_reloaded_died, src);
                      }
-                   if (REGNO (reload_reg_rtx[j]) < FIRST_PSEUDO_REGISTER)
+                   if (REGNO (rld[j].reg_rtx) < FIRST_PSEUDO_REGISTER)
                      {
-                       int s = reload_secondary_out_reload[j];
+                       int s = rld[j].secondary_out_reload;
                        set = single_set (p);
                        /* If this reload copies only to the secondary reload
                           register, the secondary reload does the actual
@@ -7329,17 +6659,17 @@ emit_reload_insns (chain)
                               has and where the actual store to the pseudo is
                               made; leave new_spill_reg_store alone.  */
                        else if (s >= 0
-                                && SET_SRC (set) == reload_reg_rtx[j]
-                                && SET_DEST (set) == reload_reg_rtx[s])
+                                && SET_SRC (set) == rld[j].reg_rtx
+                                && SET_DEST (set) == rld[s].reg_rtx)
                          {
                            /* Usually the next instruction will be the
                               secondary reload insn;  if we can confirm
                               that it is, setting new_spill_reg_store to
                               that insn will allow an extra optimization.  */
-                           rtx s_reg = reload_reg_rtx[s];
+                           rtx s_reg = rld[s].reg_rtx;
                            rtx next = NEXT_INSN (p);
-                           reload_out[s] = reload_out[j];
-                           reload_out_reg[s] = reload_out_reg[j];
+                           rld[s].out = rld[j].out;
+                           rld[s].out_reg = rld[j].out_reg;
                            set = single_set (next);
                            if (set && SET_SRC (set) == s_reg
                                && ! new_spill_reg_store[REGNO (s_reg)])
@@ -7350,18 +6680,18 @@ emit_reload_insns (chain)
                              }
                          }
                        else
-                         new_spill_reg_store[REGNO (reload_reg_rtx[j])] = p;
+                         new_spill_reg_store[REGNO (rld[j].reg_rtx)] = p;
                      }
                  }
              }
 
-         if (reload_when_needed[j] == RELOAD_OTHER)
+         if (rld[j].when_needed == RELOAD_OTHER)
            {
-             emit_insns (other_output_reload_insns[reload_opnum[j]]);
-             other_output_reload_insns[reload_opnum[j]] = get_insns ();
+             emit_insns (other_output_reload_insns[rld[j].opnum]);
+             other_output_reload_insns[rld[j].opnum] = get_insns ();
            }
          else
-           output_reload_insns[reload_opnum[j]] = get_insns ();
+           output_reload_insns[rld[j].opnum] = get_insns ();
 
          end_sequence ();
        }
@@ -7437,10 +6767,10 @@ emit_reload_insns (chain)
         clear any memory of a previous store to the same pseudo.  Only do
         something if there will not be an output reload for the pseudo
         being reloaded.  */
-      if (reload_in_reg[r] != 0
+      if (rld[r].in_reg != 0
          && ! (reload_inherited[r] || reload_override_in[r]))
        {
-         rtx reg = reload_in_reg[r];
+         rtx reg = rld[r].in_reg;
 
          if (GET_CODE (reg) == SUBREG)
            reg = SUBREG_REG (reg);
@@ -7462,13 +6792,13 @@ emit_reload_insns (chain)
        }
 
       /* I is nonneg if this reload used a register.
-        If reload_reg_rtx[r] is 0, this is an optional reload
+        If rld[r].reg_rtx is 0, this is an optional reload
         that we opted to ignore.  */
 
-      if (i >= 0 && reload_reg_rtx[r] != 0)
+      if (i >= 0 && rld[r].reg_rtx != 0)
        {
          int nr
-           = HARD_REGNO_NREGS (i, GET_MODE (reload_reg_rtx[r]));
+           = HARD_REGNO_NREGS (i, GET_MODE (rld[r].reg_rtx));
          int k;
          int part_reaches_end = 0;
          int all_reaches_end = 1;
@@ -7477,8 +6807,8 @@ emit_reload_insns (chain)
             of the value lives to the end.  */
          for (k = 0; k < nr; k++)
            {
-             if (reload_reg_reaches_end_p (i + k, reload_opnum[r],
-                                           reload_when_needed[r]))
+             if (reload_reg_reaches_end_p (i + k, rld[r].opnum,
+                                           rld[r].when_needed))
                part_reaches_end = 1;
              else
                all_reaches_end = 0;
@@ -7495,26 +6825,26 @@ emit_reload_insns (chain)
                CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k);
 
              /* Maybe the spill reg contains a copy of reload_out.  */
-             if (reload_out[r] != 0
-                 && (GET_CODE (reload_out[r]) == REG
+             if (rld[r].out != 0
+                 && (GET_CODE (rld[r].out) == REG
 #ifdef AUTO_INC_DEC
-                     || ! reload_out_reg[r]
+                     || ! rld[r].out_reg
 #endif
-                     || GET_CODE (reload_out_reg[r]) == REG))
+                     || GET_CODE (rld[r].out_reg) == REG))
                {
-                 rtx out = (GET_CODE (reload_out[r]) == REG
-                            ? reload_out[r]
-                            : reload_out_reg[r]
-                            ? reload_out_reg[r]
-/* AUTO_INC */              : XEXP (reload_in_reg[r], 0));
+                 rtx out = (GET_CODE (rld[r].out) == REG
+                            ? rld[r].out
+                            : rld[r].out_reg
+                            ? rld[r].out_reg
+/* AUTO_INC */              : XEXP (rld[r].in_reg, 0));
                  register int nregno = REGNO (out);
                  int nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
                             : HARD_REGNO_NREGS (nregno,
-                                                GET_MODE (reload_reg_rtx[r])));
+                                                GET_MODE (rld[r].reg_rtx)));
 
                  spill_reg_store[i] = new_spill_reg_store[i];
                  spill_reg_stored_to[i] = out;
-                 reg_last_reload_reg[nregno] = reload_reg_rtx[r];
+                 reg_last_reload_reg[nregno] = rld[r].reg_rtx;
 
                  /* If NREGNO is a hard register, it may occupy more than
                     one register.  If it does, say what is in the
@@ -7526,8 +6856,8 @@ emit_reload_insns (chain)
                    for (k = 1; k < nnr; k++)
                      reg_last_reload_reg[nregno + k]
                        = (nr == nnr
-                          ? gen_rtx_REG (reg_raw_mode[REGNO (reload_reg_rtx[r]) + k],
-                                         REGNO (reload_reg_rtx[r]) + k)
+                          ? gen_rtx_REG (reg_raw_mode[REGNO (rld[r].reg_rtx) + k],
+                                         REGNO (rld[r].reg_rtx) + k)
                           : 0);
 
                  /* Now do the inverse operation.  */
@@ -7546,38 +6876,38 @@ emit_reload_insns (chain)
              /* Maybe the spill reg contains a copy of reload_in.  Only do
                 something if there will not be an output reload for
                 the register being reloaded.  */
-             else if (reload_out_reg[r] == 0
-                      && reload_in[r] != 0
-                      && ((GET_CODE (reload_in[r]) == REG
-                           && REGNO (reload_in[r]) >= FIRST_PSEUDO_REGISTER
-                           && ! reg_has_output_reload[REGNO (reload_in[r])])
-                          || (GET_CODE (reload_in_reg[r]) == REG
-                              && ! reg_has_output_reload[REGNO (reload_in_reg[r])]))
-                      && ! reg_set_p (reload_reg_rtx[r], PATTERN (insn)))
+             else if (rld[r].out_reg == 0
+                      && rld[r].in != 0
+                      && ((GET_CODE (rld[r].in) == REG
+                           && REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER
+                           && ! reg_has_output_reload[REGNO (rld[r].in)])
+                          || (GET_CODE (rld[r].in_reg) == REG
+                              && ! reg_has_output_reload[REGNO (rld[r].in_reg)]))
+                      && ! reg_set_p (rld[r].reg_rtx, PATTERN (insn)))
                {
                  register int nregno;
                  int nnr;
 
-                 if (GET_CODE (reload_in[r]) == REG
-                     && REGNO (reload_in[r]) >= FIRST_PSEUDO_REGISTER)
-                   nregno = REGNO (reload_in[r]);
-                 else if (GET_CODE (reload_in_reg[r]) == REG)
-                   nregno = REGNO (reload_in_reg[r]);
+                 if (GET_CODE (rld[r].in) == REG
+                     && REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER)
+                   nregno = REGNO (rld[r].in);
+                 else if (GET_CODE (rld[r].in_reg) == REG)
+                   nregno = REGNO (rld[r].in_reg);
                  else
-                   nregno = REGNO (XEXP (reload_in_reg[r], 0));
+                   nregno = REGNO (XEXP (rld[r].in_reg, 0));
 
                  nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
                         : HARD_REGNO_NREGS (nregno,
-                                            GET_MODE (reload_reg_rtx[r])));
+                                            GET_MODE (rld[r].reg_rtx)));
 
-                 reg_last_reload_reg[nregno] = reload_reg_rtx[r];
+                 reg_last_reload_reg[nregno] = rld[r].reg_rtx;
 
                  if (nregno < FIRST_PSEUDO_REGISTER)
                    for (k = 1; k < nnr; k++)
                      reg_last_reload_reg[nregno + k]
                        = (nr == nnr
-                          ? gen_rtx_REG (reg_raw_mode[REGNO (reload_reg_rtx[r]) + k],
-                                         REGNO (reload_reg_rtx[r]) + k)
+                          ? gen_rtx_REG (reg_raw_mode[REGNO (rld[r].reg_rtx) + k],
+                                         REGNO (rld[r].reg_rtx) + k)
                           : 0);
 
                  /* Unless we inherited this reload, show we haven't
@@ -7585,7 +6915,7 @@ emit_reload_insns (chain)
                     Previous stores of inherited auto_inc expressions
                     also have to be discarded.  */
                  if (! reload_inherited[r]
-                     || (reload_out[r] && ! reload_out_reg[r]))
+                     || (rld[r].out && ! rld[r].out_reg))
                    spill_reg_store[i] = 0;
 
                  for (k = 0; k < nr; k++)
@@ -7607,8 +6937,8 @@ emit_reload_insns (chain)
            {
              for (k = 0; k < nr; k++)
                if (reload_reg_reaches_end_p (i + k,
-                                             reload_opnum[r],
-                                             reload_when_needed[r]))
+                                             rld[r].opnum,
+                                             rld[r].when_needed))
                  CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k);
            }
        }
@@ -7621,13 +6951,13 @@ emit_reload_insns (chain)
         that invalidates any previous reloaded copy of it.
         But forget_old_reloads_1 won't get to see it, because
         it thinks only about the original insn.  So invalidate it here.  */
-      if (i < 0 && reload_out[r] != 0
-         && (GET_CODE (reload_out[r]) == REG
-             || (GET_CODE (reload_out[r]) == MEM
-                 && GET_CODE (reload_out_reg[r]) == REG)))
+      if (i < 0 && rld[r].out != 0
+         && (GET_CODE (rld[r].out) == REG
+             || (GET_CODE (rld[r].out) == MEM
+                 && GET_CODE (rld[r].out_reg) == REG)))
        {
-         rtx out = (GET_CODE (reload_out[r]) == REG
-                    ? reload_out[r] : reload_out_reg[r]);
+         rtx out = (GET_CODE (rld[r].out) == REG
+                    ? rld[r].out : rld[r].out_reg);
          register int nregno = REGNO (out);
          if (nregno >= FIRST_PSEUDO_REGISTER)
            {
@@ -7638,14 +6968,14 @@ emit_reload_insns (chain)
              /* If we can find a hard register that is stored, record
                 the storing insn so that we may delete this insn with
                 delete_output_reload.  */
-             src_reg = reload_reg_rtx[r];
+             src_reg = rld[r].reg_rtx;
 
              /* If this is an optional reload, try to find the source reg
                 from an input reload.  */
              if (! src_reg)
                {
                  rtx set = single_set (insn);
-                 if (set && SET_DEST (set) == reload_out[r])
+                 if (set && SET_DEST (set) == rld[r].out)
                    {
                      int k;
 
@@ -7653,9 +6983,9 @@ emit_reload_insns (chain)
                      store_insn = insn;
                      for (k = 0; k < n_reloads; k++)
                        {
-                         if (reload_in[k] == src_reg)
+                         if (rld[k].in == src_reg)
                            {
-                             src_reg = reload_reg_rtx[k];
+                             src_reg = rld[k].reg_rtx;
                              break;
                            }
                        }
@@ -7667,7 +6997,7 @@ emit_reload_insns (chain)
                  && REGNO (src_reg) < FIRST_PSEUDO_REGISTER)
                {
                  int src_regno = REGNO (src_reg);
-                 int nr = HARD_REGNO_NREGS (src_regno, reload_mode[r]);
+                 int nr = HARD_REGNO_NREGS (src_regno, rld[r].mode);
                  /* The place where to find a death note varies with
                     PRESERVE_DEATH_INFO_REGNO_P .  The condition is not
                     necessarily checked exactly in the code that moves
@@ -7694,7 +7024,7 @@ emit_reload_insns (chain)
            }
          else
            {
-             int num_regs = HARD_REGNO_NREGS (nregno,GET_MODE (reload_out[r]));
+             int num_regs = HARD_REGNO_NREGS (nregno,GET_MODE (rld[r].out));
 
              while (num_regs-- > 0)
                reg_last_reload_reg[nregno + num_regs] = 0;
@@ -7728,9 +7058,9 @@ gen_reload (out, in, opnum, type)
       && (tem = gen_lowpart_common (GET_MODE (SUBREG_REG (in)), out)) != 0)
     in = SUBREG_REG (in), out = tem;
   else if (GET_CODE (out) == SUBREG
-      && (GET_MODE_SIZE (GET_MODE (out))
-         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
-      && (tem = gen_lowpart_common (GET_MODE (SUBREG_REG (out)), in)) != 0)
+          && (GET_MODE_SIZE (GET_MODE (out))
+              > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
+          && (tem = gen_lowpart_common (GET_MODE (SUBREG_REG (out)), in)) != 0)
     out = SUBREG_REG (out), in = tem;
 
   /* How to do this reload can get quite tricky.  Normally, we are being
@@ -7837,7 +7167,8 @@ gen_reload (out, in, opnum, type)
          || (GET_CODE (op1) == REG
              && REGNO (op1) >= FIRST_PSEUDO_REGISTER)
          || (code != CODE_FOR_nothing
-             && ! (*insn_operand_predicate[code][2]) (op1, insn_operand_mode[code][2])))
+             && ! ((*insn_data[code].operand[2].predicate)
+                   (op1, insn_data[code].operand[2].mode))))
        tem = op0, op0 = op1, op1 = tem;
 
       gen_reload (out, op0, opnum, type);
@@ -7956,14 +7287,14 @@ delete_output_reload (insn, j, last_reload_reg)
      insn than it is inherited.  */
   for (k = n_reloads - 1; k >= 0; k--)
     {
-      rtx reg2 = reload_in[k];
+      rtx reg2 = rld[k].in;
       if (! reg2)
        continue;
       if (GET_CODE (reg2) == MEM || reload_override_in[k])
-       reg2 = reload_in_reg[k];
+       reg2 = rld[k].in_reg;
 #ifdef AUTO_INC_DEC
-      if (reload_out[k] && ! reload_out_reg[k])
-       reg2 = XEXP (reload_in_reg[k], 0);
+      if (rld[k].out && ! rld[k].out_reg)
+       reg2 = XEXP (rld[k].in_reg, 0);
 #endif
       while (GET_CODE (reg2) == SUBREG)
        reg2 = SUBREG_REG (reg2);
@@ -7972,7 +7303,7 @@ delete_output_reload (insn, j, last_reload_reg)
          if (reload_inherited[k] || reload_override_in[k] || k == j)
            {
              n_inherited++;
-             reg2 = reload_out_reg[k];
+             reg2 = rld[k].out_reg;
              if (! reg2)
                continue;
              while (GET_CODE (reg2) == SUBREG)
@@ -8025,7 +7356,7 @@ delete_output_reload (insn, j, last_reload_reg)
      See if the pseudo reg has been completely replaced
      with reload regs.  If so, delete the store insn
      and forget we had a stack slot for the pseudo.  */
-  if (reload_out[j] != reload_in[j]
+  if (rld[j].out != rld[j].in
       && REG_N_DEATHS (REGNO (reg)) == 1
       && REG_N_SETS (REGNO (reg)) == 1
       && REG_BASIC_BLOCK (REGNO (reg)) >= 0
@@ -8083,7 +7414,7 @@ delete_output_reload (insn, j, last_reload_reg)
 
       /* For the debugging info,
         say the pseudo lives in this reload reg.  */
-      reg_renumber[REGNO (reg)] = REGNO (reload_reg_rtx[j]);
+      reg_renumber[REGNO (reg)] = REGNO (rld[j].reg_rtx);
       alter_reg (REGNO (reg), -1);
     }
   delete_address_reloads (output_reload_insn, insn);
@@ -8204,11 +7535,11 @@ delete_address_reloads_1 (dead_insn, x, current_insn)
              if (i2 == current_insn)
                {
                  for (j = n_reloads - 1; j >= 0; j--)
-                   if ((reload_reg_rtx[j] == dst && reload_inherited[j])
+                   if ((rld[j].reg_rtx == dst && reload_inherited[j])
                        || reload_override_in[j] == dst)
                      return;
                  for (j = n_reloads - 1; j >= 0; j--)
-                   if (reload_in[j] && reload_reg_rtx[j] == dst)
+                   if (rld[j].in && rld[j].reg_rtx == dst)
                      break;
                  if (j >= 0)
                    break;
@@ -8223,7 +7554,7 @@ delete_address_reloads_1 (dead_insn, x, current_insn)
          if (i2 == current_insn)
            {
              for (j = n_reloads - 1; j >= 0; j--)
-               if ((reload_reg_rtx[j] == dst && reload_inherited[j])
+               if ((rld[j].reg_rtx == dst && reload_inherited[j])
                    || reload_override_in[j] == dst)
                  return;
              /* ??? We can't finish the loop here, because dst might be
@@ -8668,9 +7999,10 @@ reload_cse_invalidate_mem (mem_rtx)
    note_stores; it is ignored.  */
 
 static void
-reload_cse_invalidate_rtx (dest, ignore)
+reload_cse_invalidate_rtx (dest, ignore, data)
      rtx dest;
      rtx ignore ATTRIBUTE_UNUSED;
+     void *data ATTRIBUTE_UNUSED;
 {
   while (GET_CODE (dest) == STRICT_LOW_PART
         || GET_CODE (dest) == SIGN_EXTRACT
@@ -8883,11 +8215,11 @@ reload_cse_regs_1 (first)
              if (GET_CODE (x) == SET)
                reload_cse_record_set (x, body);
              else
-               note_stores (x, reload_cse_invalidate_rtx);
+               note_stores (x, reload_cse_invalidate_rtx, NULL);
            }
        }
       else
-       note_stores (body, reload_cse_invalidate_rtx);
+       note_stores (body, reload_cse_invalidate_rtx, NULL);
 
 #ifdef AUTO_INC_DEC
       /* Clobber any registers which appear in REG_INC notes.  We
@@ -8898,7 +8230,7 @@ reload_cse_regs_1 (first)
 
        for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
          if (REG_NOTE_KIND (x) == REG_INC)
-           reload_cse_invalidate_rtx (XEXP (x, 0), NULL_RTX);
+           reload_cse_invalidate_rtx (XEXP (x, 0), NULL_RTX, NULL);
       }
 #endif
 
@@ -8910,10 +8242,14 @@ reload_cse_regs_1 (first)
 
          for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1))
            if (GET_CODE (XEXP (x, 0)) == CLOBBER)
-             reload_cse_invalidate_rtx (XEXP (XEXP (x, 0), 0), NULL_RTX);
+             reload_cse_invalidate_rtx (XEXP (XEXP (x, 0), 0), NULL_RTX,
+                                        NULL);
        }
     }
 
+  /* Clean up.  */
+  end_alias_analysis ();
+
   /* Free all the temporary structures we created, and go back to the
      regular obstacks.  */
   obstack_free (&reload_obstack, firstobj);
@@ -9132,7 +8468,6 @@ static int
 reload_cse_simplify_operands (insn)
      rtx insn;
 {
-#ifdef REGISTER_CONSTRAINTS
   int i,j;
 
   const char *constraints[MAX_RECOG_OPERANDS];
@@ -9152,31 +8487,31 @@ reload_cse_simplify_operands (insn)
 
   extract_insn (insn);
 
-  if (recog_n_alternatives == 0 || recog_n_operands == 0)
+  if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0)
     return 0;
 
   /* Figure out which alternative currently matches.  */
   if (! constrain_operands (1))
     fatal_insn_not_found (insn);
 
-  alternative_reject = (int *) alloca (recog_n_alternatives * sizeof (int));
-  alternative_nregs = (int *) alloca (recog_n_alternatives * sizeof (int));
-  alternative_order = (int *) alloca (recog_n_alternatives * sizeof (int));
-  bzero ((char *)alternative_reject, recog_n_alternatives * sizeof (int));
-  bzero ((char *)alternative_nregs, recog_n_alternatives * sizeof (int));
+  alternative_reject = (int *) alloca (recog_data.n_alternatives * sizeof (int));
+  alternative_nregs = (int *) alloca (recog_data.n_alternatives * sizeof (int));
+  alternative_order = (int *) alloca (recog_data.n_alternatives * sizeof (int));
+  bzero ((char *)alternative_reject, recog_data.n_alternatives * sizeof (int));
+  bzero ((char *)alternative_nregs, recog_data.n_alternatives * sizeof (int));
 
-  for (i = 0; i < recog_n_operands; i++)
+  for (i = 0; i < recog_data.n_operands; i++)
     {
       enum machine_mode mode;
       int regno;
       const char *p;
 
-      op_alt_regno[i] = (int *) alloca (recog_n_alternatives * sizeof (int));
-      for (j = 0; j < recog_n_alternatives; j++)
+      op_alt_regno[i] = (int *) alloca (recog_data.n_alternatives * sizeof (int));
+      for (j = 0; j < recog_data.n_alternatives; j++)
        op_alt_regno[i][j] = -1;
 
-      p = constraints[i] = recog_constraints[i];
-      mode = recog_operand_mode[i];
+      p = constraints[i] = recog_data.constraints[i];
+      mode = recog_data.operand_mode[i];
 
       /* Add the reject values for each alternative given by the constraints
         for this operand.  */
@@ -9194,7 +8529,7 @@ reload_cse_simplify_operands (insn)
 
       /* We won't change operands which are already registers.  We
         also don't want to modify output operands.  */
-      regno = true_regnum (recog_operand[i]);
+      regno = true_regnum (recog_data.operand[i]);
       if (regno >= 0
          || constraints[i][0] == '='
          || constraints[i][0] == '+')
@@ -9204,7 +8539,7 @@ reload_cse_simplify_operands (insn)
        {
          int class = (int) NO_REGS;
 
-         if (! reload_cse_regno_equal_p (regno, recog_operand[i], mode))
+         if (! reload_cse_regno_equal_p (regno, recog_data.operand[i], mode))
            continue;
 
          REGNO (reg) = regno;
@@ -9254,8 +8589,9 @@ reload_cse_simplify_operands (insn)
                     a cheap CONST_INT. */
                  if (op_alt_regno[i][j] == -1
                      && reg_fits_class_p (reg, class, 0, mode)
-                     && (GET_CODE (recog_operand[i]) != CONST_INT
-                         || rtx_cost (recog_operand[i], SET) > rtx_cost (reg, SET)))
+                     && (GET_CODE (recog_data.operand[i]) != CONST_INT
+                         || (rtx_cost (recog_data.operand[i], SET)
+                             > rtx_cost (reg, SET))))
                    {
                      alternative_nregs[j]++;
                      op_alt_regno[i][j] = regno;
@@ -9272,21 +8608,21 @@ reload_cse_simplify_operands (insn)
 
   /* Record all alternatives which are better or equal to the currently
      matching one in the alternative_order array.  */
-  for (i = j = 0; i < recog_n_alternatives; i++)
+  for (i = j = 0; i < recog_data.n_alternatives; i++)
     if (alternative_reject[i] <= alternative_reject[which_alternative])
       alternative_order[j++] = i;
-  recog_n_alternatives = j;
+  recog_data.n_alternatives = j;
 
   /* Sort it.  Given a small number of alternatives, a dumb algorithm
      won't hurt too much.  */
-  for (i = 0; i < recog_n_alternatives - 1; i++)
+  for (i = 0; i < recog_data.n_alternatives - 1; i++)
     {
       int best = i;
       int best_reject = alternative_reject[alternative_order[i]];
       int best_nregs = alternative_nregs[alternative_order[i]];
       int tmp;
 
-      for (j = i + 1; j < recog_n_alternatives; j++)
+      for (j = i + 1; j < recog_data.n_alternatives; j++)
        {
          int this_reject = alternative_reject[alternative_order[j]];
          int this_nregs = alternative_nregs[alternative_order[j]];
@@ -9312,25 +8648,25 @@ reload_cse_simplify_operands (insn)
   /* Pop back to the real obstacks while changing the insn.  */
   pop_obstacks ();
 
-  for (i = 0; i < recog_n_operands; i++)
+  for (i = 0; i < recog_data.n_operands; i++)
     {
-      enum machine_mode mode = recog_operand_mode[i];
+      enum machine_mode mode = recog_data.operand_mode[i];
       if (op_alt_regno[i][j] == -1)
        continue;
 
-      validate_change (insn, recog_operand_loc[i],
+      validate_change (insn, recog_data.operand_loc[i],
                       gen_rtx_REG (mode, op_alt_regno[i][j]), 1);
     }
 
-  for (i = recog_n_dups - 1; i >= 0; i--)
+  for (i = recog_data.n_dups - 1; i >= 0; i--)
     {
-      int op = recog_dup_num[i];
-      enum machine_mode mode = recog_operand_mode[op];
+      int op = recog_data.dup_num[i];
+      enum machine_mode mode = recog_data.operand_mode[op];
 
       if (op_alt_regno[op][j] == -1)
        continue;
 
-      validate_change (insn, recog_dup_loc[i],
+      validate_change (insn, recog_data.dup_loc[i],
                       gen_rtx_REG (mode, op_alt_regno[op][j]), 1);
     }
 
@@ -9339,9 +8675,6 @@ reload_cse_simplify_operands (insn)
   push_obstacks (&reload_obstack, &reload_obstack);
 
   return apply_change_group ();
-#else
-  return 0;
-#endif
 }
 
 /* These two variables are used to pass information from
@@ -9355,9 +8688,10 @@ static rtx reload_cse_check_src;
    second argument, which is passed by note_stores, is ignored.  */
 
 static void
-reload_cse_check_clobber (dest, ignore)
+reload_cse_check_clobber (dest, ignore, data)
      rtx dest;
      rtx ignore ATTRIBUTE_UNUSED;
+     void *data ATTRIBUTE_UNUSED;
 {
   if (reg_overlap_mentioned_p (dest, reload_cse_check_src))
     reload_cse_check_clobbered = 1;
@@ -9393,8 +8727,8 @@ reload_cse_record_set (set, body)
     x = XEXP (x, 0);
   if (push_operand (x, GET_MODE (x)))
     {
-      reload_cse_invalidate_rtx (stack_pointer_rtx, NULL_RTX);
-      reload_cse_invalidate_rtx (dest, NULL_RTX);
+      reload_cse_invalidate_rtx (stack_pointer_rtx, NULL_RTX, NULL);
+      reload_cse_invalidate_rtx (dest, NULL_RTX, NULL);
       return;
     }
 
@@ -9406,7 +8740,7 @@ reload_cse_record_set (set, body)
       || side_effects_p (src)
       || side_effects_p (dest))
     {
-      reload_cse_invalidate_rtx (dest, NULL_RTX);
+      reload_cse_invalidate_rtx (dest, NULL_RTX, NULL);
       return;
     }
 
@@ -9416,7 +8750,7 @@ reload_cse_record_set (set, body)
   if (reg_mentioned_p (cc0_rtx, src)
       || reg_mentioned_p (cc0_rtx, dest))
     {
-      reload_cse_invalidate_rtx (dest, NULL_RTX);
+      reload_cse_invalidate_rtx (dest, NULL_RTX, NULL);
       return;
     }
 #endif
@@ -9437,10 +8771,10 @@ reload_cse_record_set (set, body)
 
          reload_cse_check_clobbered = 0;
          reload_cse_check_src = src;
-         note_stores (x, reload_cse_check_clobber);
+         note_stores (x, reload_cse_check_clobber, NULL);
          if (reload_cse_check_clobbered)
            {
-             reload_cse_invalidate_rtx (dest, NULL_RTX);
+             reload_cse_invalidate_rtx (dest, NULL_RTX, NULL);
              return;
            }
        }
@@ -9633,13 +8967,13 @@ reload_combine ()
       reload_combine_ruid++;
 
       /* Look for (set (REGX) (CONST_INT))
-                 (set (REGX) (PLUS (REGX) (REGY)))
-                 ...
-                 ... (MEM (REGX)) ...
+        (set (REGX) (PLUS (REGX) (REGY)))
+        ...
+        ... (MEM (REGX)) ...
         and convert it to
-                 (set (REGZ) (CONST_INT))
-                 ...
-                 ... (MEM (PLUS (REGZ) (REGY)))... .
+        (set (REGZ) (CONST_INT))
+        ...
+        ... (MEM (PLUS (REGZ) (REGY)))... .
 
         First, check that we have (set (REGX) (PLUS (REGX) (REGY)))
         and that we know all uses of REGX before it dies.  */
@@ -9755,7 +9089,7 @@ reload_combine ()
                }
            }
        }
-      note_stores (PATTERN (insn), reload_combine_note_store);
+      note_stores (PATTERN (insn), reload_combine_note_store, NULL);
       if (GET_CODE (insn) == CALL_INSN)
        {
          rtx link;
@@ -9818,8 +9152,9 @@ reload_combine ()
    update reg_state[regno].store_ruid and reg_state[regno].use_index
    accordingly.  Called via note_stores from reload_combine.  */
 static void
-reload_combine_note_store (dst, set)
+reload_combine_note_store (dst, set, data)
      rtx dst, set;
+     void *data ATTRIBUTE_UNUSED;
 {
   int regno = 0;
   int i;
@@ -10145,7 +9480,7 @@ reload_cse_move2add (first)
                }
            }
        }
-      note_stores (PATTERN (insn), move2add_note_store);
+      note_stores (PATTERN (insn), move2add_note_store, NULL);
       /* If this is a CALL_INSN, all call used registers are stored with
         unknown values.  */
       if (GET_CODE (insn) == CALL_INSN)
@@ -10166,8 +9501,9 @@ reload_cse_move2add (first)
    Update reg_set_luid, reg_offset and reg_base_reg accordingly.
    Called from reload_cse_move2add via note_stores.  */
 static void
-move2add_note_store (dst, set)
+move2add_note_store (dst, set, data)
      rtx dst, set;
+     void *data ATTRIBUTE_UNUSED;
 {
   int regno = 0;
   int i;
This page took 0.204221 seconds and 5 git commands to generate.