/* Reload pseudo regs into hard regs for insns that require hard regs.
   Copyright (C) 1987-2019 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "predict.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "optabs.h"
#include "regs.h"
#include "ira.h"
#include "recog.h"

#include "rtl-error.h"
#include "expr.h"
#include "addresses.h"
#include "cfgrtl.h"
#include "cfgbuild.h"
#include "reload.h"
#include "except.h"
#include "dumpfile.h"
#include "rtl-iter.h"

/* This file contains the reload pass of the compiler, which is
   run after register allocation has been done.  It checks that
   each insn is valid (operands required to be in registers really
   are in registers of the proper class) and fixes up invalid ones
   by copying values temporarily into registers for the insns
   that need them.

   The results of register allocation are described by the vector
   reg_renumber; the insns still contain pseudo regs, but reg_renumber
   can be used to find which hard reg, if any, a pseudo reg is in.

   The technique we always use is to free up a few hard regs that are
   called ``reload regs'', and for each place where a pseudo reg
   must be in a hard reg, copy it temporarily into one of the reload regs.

   Reload regs are allocated locally for every instruction that needs
   reloads.  When there are pseudos which are allocated to a register that
   has been chosen as a reload reg, such pseudos must be ``spilled''.
   This means that they go to other hard regs, or to stack slots if no other
   available hard regs can be found.  Spilling can invalidate more
   insns, requiring additional need for reloads, so we must keep checking
   until the process stabilizes.

   For machines with different classes of registers, we must keep track
   of the register class needed for each reload, and make sure that
   we allocate enough reload registers of each class.

   The file reload.c contains the code that checks one insn for
   validity and reports the reloads that it needs.  This file
   is in charge of scanning the entire rtl code, accumulating the
   reload needs, spilling, assigning reload registers to use for
   fixing up each insn, and generating the new insns to copy values
   into the reload registers.  */

struct target_reload default_target_reload;
#if SWITCHABLE_TARGET
struct target_reload *this_target_reload = &default_target_reload;
#endif

#define spill_indirect_levels			\
  (this_target_reload->x_spill_indirect_levels)

/* During reload_as_needed, element N contains a REG rtx for the hard reg
   into which reg N has been reloaded (perhaps for a previous insn).  */
static rtx *reg_last_reload_reg;

/* Elt N nonzero if reg_last_reload_reg[N] has been set in this insn
   for an output reload that stores into reg N.  */
static regset_head reg_has_output_reload;

/* Indicates which hard regs are reload-registers for an output reload
   in the current insn.  */
static HARD_REG_SET reg_is_output_reload;

/* Widest mode in which each pseudo reg is referred to (via subreg).  */
static machine_mode *reg_max_ref_mode;

/* Vector to remember old contents of reg_renumber before spilling.  */
static short *reg_old_renumber;

/* During reload_as_needed, element N contains the last pseudo regno reloaded
   into hard register N.  If that pseudo reg occupied more than one register,
   reg_reloaded_contents points to that pseudo for each spill register in
   use; all of these must remain set for an inheritance to occur.  */
static int reg_reloaded_contents[FIRST_PSEUDO_REGISTER];

/* During reload_as_needed, element N contains the insn for which
   hard register N was last used.   Its contents are significant only
   when reg_reloaded_valid is set for this register.  */
static rtx_insn *reg_reloaded_insn[FIRST_PSEUDO_REGISTER];

/* Indicate if reg_reloaded_insn / reg_reloaded_contents is valid.  */
static HARD_REG_SET reg_reloaded_valid;
/* Indicate if the register was dead at the end of the reload.
   This is only valid if reg_reloaded_contents is set and valid.  */
static HARD_REG_SET reg_reloaded_dead;

/* Indicate whether the register's current value is one that is not
   safe to retain across a call, even for registers that are normally
   call-saved.  This is only meaningful for members of reg_reloaded_valid.  */
static HARD_REG_SET reg_reloaded_call_part_clobbered;

/* Number of spill-regs so far; number of valid elements of spill_regs.  */
static int n_spills;

/* In parallel with spill_regs, contains REG rtx's for those regs.
   Holds the last rtx used for any given reg, or 0 if it has never
   been used for spilling yet.  This rtx is reused, provided it has
   the proper mode.  */
static rtx spill_reg_rtx[FIRST_PSEUDO_REGISTER];

/* In parallel with spill_regs, contains nonzero for a spill reg
   that was stored after the last time it was used.
   The precise value is the insn generated to do the store.  */
static rtx_insn *spill_reg_store[FIRST_PSEUDO_REGISTER];

/* This is the register that was stored with spill_reg_store.  This is a
   copy of reload_out / reload_out_reg when the value was stored; if
   reload_out is a MEM, spill_reg_stored_to will be set to reload_out_reg.  */
static rtx spill_reg_stored_to[FIRST_PSEUDO_REGISTER];

/* This table is the inverse mapping of spill_regs:
   indexed by hard reg number,
   it contains the position of that reg in spill_regs,
   or -1 for something that is not in spill_regs.

   ?!?  This is no longer accurate.  */
static short spill_reg_order[FIRST_PSEUDO_REGISTER];

/* This reg set indicates registers that can't be used as spill registers for
   the currently processed insn.  These are the hard registers which are live
   during the insn, but not allocated to pseudos, as well as fixed
   registers.  */
static HARD_REG_SET bad_spill_regs;

/* These are the hard registers that can't be used as spill register for any
   insn.  This includes registers used for user variables and registers that
   we can't eliminate.  A register that appears in this set also can't be used
   to retry register allocation.  */
static HARD_REG_SET bad_spill_regs_global;

/* Describes order of use of registers for reloading
   of spilled pseudo-registers.  `n_spills' is the number of
   elements that are actually valid; new ones are added at the end.

   Both spill_regs and spill_reg_order are used on two occasions:
   once during find_reload_regs, where they keep track of the spill registers
   for a single insn, but also during reload_as_needed where they show all
   the registers ever used by reload.  For the latter case, the information
   is calculated during finish_spills.  */
static short spill_regs[FIRST_PSEUDO_REGISTER];

/* This vector of reg sets indicates, for each pseudo, which hard registers
   may not be used for retrying global allocation because the register was
   formerly spilled from one of them.  If we allowed reallocating a pseudo to
   a register that it was already allocated to, reload might not
   terminate.  */
static HARD_REG_SET *pseudo_previous_regs;

/* This vector of reg sets indicates, for each pseudo, which hard
   registers may not be used for retrying global allocation because they
   are used as spill registers during one of the insns in which the
   pseudo is live.  */
static HARD_REG_SET *pseudo_forbidden_regs;

/* All hard regs that have been used as spill registers for any insn are
   marked in this set.  */
static HARD_REG_SET used_spill_regs;

/* Index of last register assigned as a spill register.  We allocate in
   a round-robin fashion.  */
static int last_spill_reg;

/* Record the stack slot for each spilled hard register.  */
static rtx spill_stack_slot[FIRST_PSEUDO_REGISTER];

/* Width allocated so far for that stack slot.  */
static poly_uint64_pod spill_stack_slot_width[FIRST_PSEUDO_REGISTER];

/* Record which pseudos needed to be spilled.  */
static regset_head spilled_pseudos;

/* Record which pseudos changed their allocation in finish_spills.  */
static regset_head changed_allocation_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.  */
int reload_first_uid;

/* Flag set by local-alloc or global-alloc if anything is live in
   a call-clobbered reg across calls.  */
int caller_save_needed;

/* Set to 1 while reload_as_needed is operating.
   Required by some machines to handle any generated moves differently.  */
int reload_in_progress = 0;

/* This obstack is used for allocation of rtl during register elimination.
   The allocated storage can be freed once find_reloads has processed the
   insn.  */
static struct obstack reload_obstack;

/* Points to the beginning of the reload_obstack.  All insn_chain structures
   are allocated first.  */
static char *reload_startobj;

/* The point after all insn_chain structures.  Used to quickly deallocate
   memory allocated in copy_reloads during calculate_needs_all_insns.  */
static 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;

/* List of insn_chain instructions, one for every insn that reload needs to
   examine.  */
struct insn_chain *reload_insn_chain;

/* TRUE if we potentially left dead insns in the insn stream and want to
   run DCE immediately after reload, FALSE otherwise.  */
static bool need_dce;

/* List of all insns needing reloads.  */
static struct insn_chain *insns_need_reload;

/* This structure is used to record information about register eliminations.
   Each array entry describes one possible way of eliminating a register
   in favor of another.   If there is more than one way of eliminating a
   particular register, the most preferred should be specified first.  */

struct elim_table
{
  int from;			/* Register number to be eliminated.  */
  int to;			/* Register number used as replacement.  */
  poly_int64_pod initial_offset; /* Initial difference between values.  */
  int can_eliminate;		/* Nonzero if this elimination can be done.  */
  int can_eliminate_previous;	/* Value returned by TARGET_CAN_ELIMINATE
				   target hook in previous scan over insns
				   made by reload.  */
  poly_int64_pod offset;	/* Current offset between the two regs.  */
  poly_int64_pod previous_offset; /* Offset at end of previous insn.  */
  int ref_outside_mem;		/* "to" has been referenced outside a MEM.  */
  rtx from_rtx;			/* REG rtx for the register to be eliminated.
				   We cannot simply compare the number since
				   we might then spuriously replace a hard
				   register corresponding to a pseudo
				   assigned to the reg to be eliminated.  */
  rtx to_rtx;			/* REG rtx for the replacement.  */
};

static struct elim_table *reg_eliminate = 0;

/* This is an intermediate structure to initialize the table.  It has
   exactly the members provided by ELIMINABLE_REGS.  */
static const struct elim_table_1
{
  const int from;
  const int to;
} reg_eliminate_1[] =

  ELIMINABLE_REGS;

#define NUM_ELIMINABLE_REGS ARRAY_SIZE (reg_eliminate_1)

/* Record the number of pending eliminations that have an offset not equal
   to their initial offset.  If nonzero, we use a new copy of each
   replacement result in any insns encountered.  */
int num_not_at_initial_offset;

/* Count the number of registers that we may be able to eliminate.  */
static int num_eliminable;
/* And the number of registers that are equivalent to a constant that
   can be eliminated to frame_pointer / arg_pointer + constant.  */
static int num_eliminable_invariants;

/* For each label, we record the offset of each elimination.  If we reach
   a label by more than one path and an offset differs, we cannot do the
   elimination.  This information is indexed by the difference of the
   number of the label and the first label number.  We can't offset the
   pointer itself as this can cause problems on machines with segmented
   memory.  The first table is an array of flags that records whether we
   have yet encountered a label and the second table is an array of arrays,
   one entry in the latter array for each elimination.  */

static int first_label_num;
static char *offsets_known_at;
static poly_int64_pod (*offsets_at)[NUM_ELIMINABLE_REGS];

vec<reg_equivs_t, va_gc> *reg_equivs;

/* Stack of addresses where an rtx has been changed.  We can undo the 
   changes by popping items off the stack and restoring the original
   value at each location. 

   We use this simplistic undo capability rather than copy_rtx as copy_rtx
   will not make a deep copy of a normally sharable rtx, such as
   (const (plus (symbol_ref) (const_int))).  If such an expression appears
   as R1 in gen_reload_chain_without_interm_reg_p, then a shared
   rtx expression would be changed.  See PR 42431.  */

typedef rtx *rtx_p;
static vec<rtx_p> substitute_stack;

/* Number of labels in the current function.  */

static int num_labels;

static void replace_pseudos_in (rtx *, machine_mode, rtx);
static void maybe_fix_stack_asms (void);
static void copy_reloads (struct insn_chain *);
static void calculate_needs_all_insns (int);
static int find_reg (struct insn_chain *, int);
static void find_reload_regs (struct insn_chain *);
static void select_reload_regs (void);
static void delete_caller_save_insns (void);

static void spill_failure (rtx_insn *, enum reg_class);
static void count_spilled_pseudo (int, int, int);
static void delete_dead_insn (rtx_insn *);
static void alter_reg (int, int, bool);
static void set_label_offsets (rtx, rtx_insn *, int);
static void check_eliminable_occurrences (rtx);
static void elimination_effects (rtx, machine_mode);
static rtx eliminate_regs_1 (rtx, machine_mode, rtx, bool, bool);
static int eliminate_regs_in_insn (rtx_insn *, int);
static void update_eliminable_offsets (void);
static void mark_not_eliminable (rtx, const_rtx, void *);
static void set_initial_elim_offsets (void);
static bool verify_initial_elim_offsets (void);
static void set_initial_label_offsets (void);
static void set_offsets_for_label (rtx_insn *);
static void init_eliminable_invariants (rtx_insn *, bool);
static void init_elim_table (void);
static void free_reg_equiv (void);
static void update_eliminables (HARD_REG_SET *);
static bool update_eliminables_and_spill (void);
static void elimination_costs_in_insn (rtx_insn *);
static void spill_hard_reg (unsigned int, int);
static int finish_spills (int);
static void scan_paradoxical_subregs (rtx);
static void count_pseudo (int);
static void order_regs_for_reload (struct insn_chain *);
static void reload_as_needed (int);
static void forget_old_reloads_1 (rtx, const_rtx, void *);
static void forget_marked_reloads (regset);
static int reload_reg_class_lower (const void *, const void *);
static void mark_reload_reg_in_use (unsigned int, int, enum reload_type,
				    machine_mode);
static void clear_reload_reg_in_use (unsigned int, int, enum reload_type,
				     machine_mode);
static int reload_reg_free_p (unsigned int, int, enum reload_type);
static int reload_reg_free_for_value_p (int, int, int, enum reload_type,
					rtx, rtx, int, int);
static int free_for_value_p (int, machine_mode, int, enum reload_type,
			     rtx, rtx, int, int);
static int allocate_reload_reg (struct insn_chain *, int, int);
static int conflicts_with_override (rtx);
static void failed_reload (rtx_insn *, int);
static int set_reload_reg (int, int);
static void choose_reload_regs_init (struct insn_chain *, rtx *);
static void choose_reload_regs (struct insn_chain *);
static void emit_input_reload_insns (struct insn_chain *, struct reload *,
				     rtx, int);
static void emit_output_reload_insns (struct insn_chain *, struct reload *,
				      int);
static void do_input_reload (struct insn_chain *, struct reload *, int);
static void do_output_reload (struct insn_chain *, struct reload *, int);
static void emit_reload_insns (struct insn_chain *);
static void delete_output_reload (rtx_insn *, int, int, rtx);
static void delete_address_reloads (rtx_insn *, rtx_insn *);
static void delete_address_reloads_1 (rtx_insn *, rtx, rtx_insn *);
static void inc_for_reload (rtx, rtx, rtx, poly_int64);
static void add_auto_inc_notes (rtx_insn *, rtx);
static void substitute (rtx *, const_rtx, rtx);
static bool gen_reload_chain_without_interm_reg_p (int, int);
static int reloads_conflict (int, int);
static rtx_insn *gen_reload (rtx, rtx, int, enum reload_type);
static rtx_insn *emit_insn_if_valid_for_reload (rtx);

/* Initialize the reload pass.  This is called at the beginning of compilation
   and may be called again if the target is reinitialized.  */

void
init_reload (void)
{
  int i;

  /* Often (MEM (REG n)) is still valid even if (REG n) is put on the stack.
     Set spill_indirect_levels to the number of levels such addressing is
     permitted, zero if it is not permitted at all.  */

  rtx tem
    = gen_rtx_MEM (Pmode,
		   gen_rtx_PLUS (Pmode,
				 gen_rtx_REG (Pmode,
					      LAST_VIRTUAL_REGISTER + 1),
				 gen_int_mode (4, Pmode)));
  spill_indirect_levels = 0;

  while (memory_address_p (QImode, tem))
    {
      spill_indirect_levels++;
      tem = gen_rtx_MEM (Pmode, tem);
    }

  /* See if indirect addressing is valid for (MEM (SYMBOL_REF ...)).  */

  tem = gen_rtx_MEM (Pmode, gen_rtx_SYMBOL_REF (Pmode, "foo"));
  indirect_symref_ok = memory_address_p (QImode, tem);

  /* See if reg+reg is a valid (and offsettable) address.  */

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      tem = gen_rtx_PLUS (Pmode,
			  gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
			  gen_rtx_REG (Pmode, i));

      /* This way, we make sure that reg+reg is an offsettable address.  */
      tem = plus_constant (Pmode, tem, 4);

      for (int mode = 0; mode < MAX_MACHINE_MODE; mode++)
	if (!double_reg_address_ok[mode]
	    && memory_address_p ((enum machine_mode)mode, tem))
	  double_reg_address_ok[mode] = 1;
    }

  /* Initialize obstack for our rtl allocation.  */
  if (reload_startobj == NULL)
    {
      gcc_obstack_init (&reload_obstack);
      reload_startobj = XOBNEWVAR (&reload_obstack, char, 0);
    }

  INIT_REG_SET (&spilled_pseudos);
  INIT_REG_SET (&changed_allocation_pseudos);
  INIT_REG_SET (&pseudos_counted);
}

/* List of insn chains that are currently unused.  */
static struct insn_chain *unused_insn_chains = 0;

/* Allocate an empty insn_chain structure.  */
struct insn_chain *
new_insn_chain (void)
{
  struct insn_chain *c;

  if (unused_insn_chains == 0)
    {
      c = XOBNEW (&reload_obstack, struct insn_chain);
      INIT_REG_SET (&c->live_throughout);
      INIT_REG_SET (&c->dead_or_set);
    }
  else
    {
      c = unused_insn_chains;
      unused_insn_chains = c->next;
    }
  c->is_caller_save_insn = 0;
  c->need_operand_change = 0;
  c->need_reload = 0;
  c->need_elim = 0;
  return c;
}

/* Small utility function to set all regs in hard reg set TO which are
   allocated to pseudos in regset FROM.  */

void
compute_use_by_pseudos (HARD_REG_SET *to, regset from)
{
  unsigned int regno;
  reg_set_iterator rsi;

  EXECUTE_IF_SET_IN_REG_SET (from, FIRST_PSEUDO_REGISTER, regno, rsi)
    {
      int r = reg_renumber[regno];

      if (r < 0)
	{
	  /* reload_combine uses the information from DF_LIVE_IN,
	     which might still contain registers that have not
	     actually been allocated since they have an
	     equivalence.  */
	  gcc_assert (ira_conflicts_p || reload_completed);
	}
      else
	add_to_hard_reg_set (to, PSEUDO_REGNO_MODE (regno), r);
    }
}

/* Replace all pseudos found in LOC with their corresponding
   equivalences.  */

static void
replace_pseudos_in (rtx *loc, machine_mode mem_mode, rtx usage)
{
  rtx x = *loc;
  enum rtx_code code;
  const char *fmt;
  int i, j;

  if (! x)
    return;

  code = GET_CODE (x);
  if (code == REG)
    {
      unsigned int regno = REGNO (x);

      if (regno < FIRST_PSEUDO_REGISTER)
	return;

      x = eliminate_regs_1 (x, mem_mode, usage, true, false);
      if (x != *loc)
	{
	  *loc = x;
	  replace_pseudos_in (loc, mem_mode, usage);
	  return;
	}

      if (reg_equiv_constant (regno))
	*loc = reg_equiv_constant (regno);
      else if (reg_equiv_invariant (regno))
	*loc = reg_equiv_invariant (regno);
      else if (reg_equiv_mem (regno))
	*loc = reg_equiv_mem (regno);
      else if (reg_equiv_address (regno))
	*loc = gen_rtx_MEM (GET_MODE (x), reg_equiv_address (regno));
      else
	{
	  gcc_assert (!REG_P (regno_reg_rtx[regno])
		      || REGNO (regno_reg_rtx[regno]) != regno);
	  *loc = regno_reg_rtx[regno];
	}

      return;
    }
  else if (code == MEM)
    {
      replace_pseudos_in (& XEXP (x, 0), GET_MODE (x), usage);
      return;
    }

  /* Process each of our operands recursively.  */
  fmt = GET_RTX_FORMAT (code);
  for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
    if (*fmt == 'e')
      replace_pseudos_in (&XEXP (x, i), mem_mode, usage);
    else if (*fmt == 'E')
      for (j = 0; j < XVECLEN (x, i); j++)
	replace_pseudos_in (& XVECEXP (x, i, j), mem_mode, usage);
}

/* Determine if the current function has an exception receiver block
   that reaches the exit block via non-exceptional edges  */

static bool
has_nonexceptional_receiver (void)
{
  edge e;
  edge_iterator ei;
  basic_block *tos, *worklist, bb;

  /* If we're not optimizing, then just err on the safe side.  */
  if (!optimize)
    return true;

  /* First determine which blocks can reach exit via normal paths.  */
  tos = worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) + 1);

  FOR_EACH_BB_FN (bb, cfun)
    bb->flags &= ~BB_REACHABLE;

  /* Place the exit block on our worklist.  */
  EXIT_BLOCK_PTR_FOR_FN (cfun)->flags |= BB_REACHABLE;
  *tos++ = EXIT_BLOCK_PTR_FOR_FN (cfun);

  /* Iterate: find everything reachable from what we've already seen.  */
  while (tos != worklist)
    {
      bb = *--tos;

      FOR_EACH_EDGE (e, ei, bb->preds)
	if (!(e->flags & EDGE_ABNORMAL))
	  {
	    basic_block src = e->src;

	    if (!(src->flags & BB_REACHABLE))
	      {
		src->flags |= BB_REACHABLE;
		*tos++ = src;
	      }
	  }
    }
  free (worklist);

  /* Now see if there's a reachable block with an exceptional incoming
     edge.  */
  FOR_EACH_BB_FN (bb, cfun)
    if (bb->flags & BB_REACHABLE && bb_has_abnormal_pred (bb))
      return true;

  /* No exceptional block reached exit unexceptionally.  */
  return false;
}

/* Grow (or allocate) the REG_EQUIVS array from its current size (which may be
   zero elements) to MAX_REG_NUM elements.

   Initialize all new fields to NULL and update REG_EQUIVS_SIZE.  */
void
grow_reg_equivs (void)
{
  int old_size = vec_safe_length (reg_equivs);
  int max_regno = max_reg_num ();
  int i;
  reg_equivs_t ze;

  memset (&ze, 0, sizeof (reg_equivs_t));
  vec_safe_reserve (reg_equivs, max_regno);
  for (i = old_size; i < max_regno; i++)
    reg_equivs->quick_insert (i, ze);
}


/* Global variables used by reload and its subroutines.  */

/* The current basic block while in calculate_elim_costs_all_insns.  */
static basic_block elim_bb;

/* Set during calculate_needs if an insn needs register elimination.  */
static int something_needs_elimination;
/* Set during calculate_needs if an insn needs an operand changed.  */
static int something_needs_operands_changed;
/* Set by alter_regs if we spilled a register to the stack.  */
static bool something_was_spilled;

/* Nonzero means we couldn't get enough spill regs.  */
static int failure;

/* Temporary array of pseudo-register number.  */
static int *temp_pseudo_reg_arr;

/* If a pseudo has no hard reg, delete the insns that made the equivalence.
   If that insn didn't set the register (i.e., it copied the register to
   memory), just delete that insn instead of the equivalencing insn plus
   anything now dead.  If we call delete_dead_insn on that insn, we may
   delete the insn that actually sets the register if the register dies
   there and that is incorrect.  */
static void
remove_init_insns ()
{
  for (int i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
    {
      if (reg_renumber[i] < 0 && reg_equiv_init (i) != 0)
	{
	  rtx list;
	  for (list = reg_equiv_init (i); list; list = XEXP (list, 1))
	    {
	      rtx_insn *equiv_insn = as_a <rtx_insn *> (XEXP (list, 0));

	      /* If we already deleted the insn or if it may trap, we can't
		 delete it.  The latter case shouldn't happen, but can
		 if an insn has a variable address, gets a REG_EH_REGION
		 note added to it, and then gets converted into a load
		 from a constant address.  */
	      if (NOTE_P (equiv_insn)
		  || can_throw_internal (equiv_insn))
		;
	      else if (reg_set_p (regno_reg_rtx[i], PATTERN (equiv_insn)))
		delete_dead_insn (equiv_insn);
	      else
		SET_INSN_DELETED (equiv_insn);
	    }
	}
    }
}

/* Return true if remove_init_insns will delete INSN.  */
static bool
will_delete_init_insn_p (rtx_insn *insn)
{
  rtx set = single_set (insn);
  if (!set || !REG_P (SET_DEST (set)))
    return false;
  unsigned regno = REGNO (SET_DEST (set));

  if (can_throw_internal (insn))
    return false;

  if (regno < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
    return false;

  for (rtx list = reg_equiv_init (regno); list; list = XEXP (list, 1))
    {
      rtx equiv_insn = XEXP (list, 0);
      if (equiv_insn == insn)
	return true;
    }
  return false;
}

/* Main entry point for the reload pass.

   FIRST is the first insn of the function being compiled.

   GLOBAL nonzero means we were called from global_alloc
   and should attempt to reallocate any pseudoregs that we
   displace from hard regs we will use for reloads.
   If GLOBAL is zero, we do not have enough information to do that,
   so any pseudo reg that is spilled must go to the stack.

   Return value is TRUE if reload likely left dead insns in the
   stream and a DCE pass should be run to elimiante them.  Else the
   return value is FALSE.  */

bool
reload (rtx_insn *first, int global)
{
  int i, n;
  rtx_insn *insn;
  struct elim_table *ep;
  basic_block bb;
  bool inserted;

  /* Make sure even insns with volatile mem refs are recognizable.  */
  init_recog ();

  failure = 0;

  reload_firstobj = XOBNEWVAR (&reload_obstack, char, 0);

  /* Make sure that the last insn in the chain
     is not something that needs reloading.  */
  emit_note (NOTE_INSN_DELETED);

  /* Enable find_equiv_reg to distinguish insns made by reload.  */
  reload_first_uid = get_max_uid ();

  /* Initialize the secondary memory table.  */
  clear_secondary_mem ();

  /* We don't have a stack slot for any spill reg yet.  */
  memset (spill_stack_slot, 0, sizeof spill_stack_slot);
  memset (spill_stack_slot_width, 0, sizeof spill_stack_slot_width);

  /* Initialize the save area information for caller-save, in case some
     are needed.  */
  init_save_areas ();

  /* Compute which hard registers are now in use
     as homes for pseudo registers.
     This is done here rather than (eg) in global_alloc
     because this point is reached even if not optimizing.  */
  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
    mark_home_live (i);

  /* A function that has a nonlocal label that can reach the exit
     block via non-exceptional paths must save all call-saved
     registers.  */
  if (cfun->has_nonlocal_label
      && has_nonexceptional_receiver ())
    crtl->saves_all_registers = 1;

  if (crtl->saves_all_registers)
    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
      if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i))
	df_set_regs_ever_live (i, true);

  /* Find all the pseudo registers that didn't get hard regs
     but do have known equivalent constants or memory slots.
     These include parameters (known equivalent to parameter slots)
     and cse'd or loop-moved constant memory addresses.

     Record constant equivalents in reg_equiv_constant
     so they will be substituted by find_reloads.
     Record memory equivalents in reg_mem_equiv so they can
     be substituted eventually by altering the REG-rtx's.  */

  grow_reg_equivs ();
  reg_old_renumber = XCNEWVEC (short, max_regno);
  memcpy (reg_old_renumber, reg_renumber, max_regno * sizeof (short));
  pseudo_forbidden_regs = XNEWVEC (HARD_REG_SET, max_regno);
  pseudo_previous_regs = XCNEWVEC (HARD_REG_SET, max_regno);

  CLEAR_HARD_REG_SET (bad_spill_regs_global);

  init_eliminable_invariants (first, true);
  init_elim_table ();

  /* Alter each pseudo-reg rtx to contain its hard reg number.  Assign
     stack slots to the pseudos that lack hard regs or equivalents.
     Do not touch virtual registers.  */

  temp_pseudo_reg_arr = XNEWVEC (int, max_regno - LAST_VIRTUAL_REGISTER - 1);
  for (n = 0, i = LAST_VIRTUAL_REGISTER + 1; i < max_regno; i++)
    temp_pseudo_reg_arr[n++] = i;

  if (ira_conflicts_p)
    /* Ask IRA to order pseudo-registers for better stack slot
       sharing.  */
    ira_sort_regnos_for_alter_reg (temp_pseudo_reg_arr, n, reg_max_ref_mode);

  for (i = 0; i < n; i++)
    alter_reg (temp_pseudo_reg_arr[i], -1, false);

  /* If we have some registers we think can be eliminated, scan all insns to
     see if there is an insn that sets one of these registers to something
     other than itself plus a constant.  If so, the register cannot be
     eliminated.  Doing this scan here eliminates an extra pass through the
     main reload loop in the most common case where register elimination
     cannot be done.  */
  for (insn = first; insn && num_eliminable; insn = NEXT_INSN (insn))
    if (INSN_P (insn))
      note_stores (PATTERN (insn), mark_not_eliminable, NULL);

  maybe_fix_stack_asms ();

  insns_need_reload = 0;
  something_needs_elimination = 0;

  /* Initialize to -1, which means take the first spill register.  */
  last_spill_reg = -1;

  /* Spill any hard regs that we know we can't eliminate.  */
  CLEAR_HARD_REG_SET (used_spill_regs);
  /* There can be multiple ways to eliminate a register;
     they should be listed adjacently.
     Elimination for any register fails only if all possible ways fail.  */
  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; )
    {
      int from = ep->from;
      int can_eliminate = 0;
      do
	{
          can_eliminate |= ep->can_eliminate;
          ep++;
	}
      while (ep < &reg_eliminate[NUM_ELIMINABLE_REGS] && ep->from == from);
      if (! can_eliminate)
	spill_hard_reg (from, 1);
    }

  if (!HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed)
    spill_hard_reg (HARD_FRAME_POINTER_REGNUM, 1);

  finish_spills (global);

  /* From now on, we may need to generate moves differently.  We may also
     allow modifications of insns which cause them to not be recognized.
     Any such modifications will be cleaned up during reload itself.  */
  reload_in_progress = 1;

  /* This loop scans the entire function each go-round
     and repeats until one repetition spills no additional hard regs.  */
  for (;;)
    {
      int something_changed;
      poly_int64 starting_frame_size;

      starting_frame_size = get_frame_size ();
      something_was_spilled = false;

      set_initial_elim_offsets ();
      set_initial_label_offsets ();

      /* For each pseudo register that has an equivalent location defined,
	 try to eliminate any eliminable registers (such as the frame pointer)
	 assuming initial offsets for the replacement register, which
	 is the normal case.

	 If the resulting location is directly addressable, substitute
	 the MEM we just got directly for the old REG.

	 If it is not addressable but is a constant or the sum of a hard reg
	 and constant, it is probably not addressable because the constant is
	 out of range, in that case record the address; we will generate
	 hairy code to compute the address in a register each time it is
	 needed.  Similarly if it is a hard register, but one that is not
	 valid as an address register.

	 If the location is not addressable, but does not have one of the
	 above forms, assign a stack slot.  We have to do this to avoid the
	 potential of producing lots of reloads if, e.g., a location involves
	 a pseudo that didn't get a hard register and has an equivalent memory
	 location that also involves a pseudo that didn't get a hard register.

	 Perhaps at some point we will improve reload_when_needed handling
	 so this problem goes away.  But that's very hairy.  */

      for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
	if (reg_renumber[i] < 0 && reg_equiv_memory_loc (i))
	  {
	    rtx x = eliminate_regs (reg_equiv_memory_loc (i), VOIDmode,
				    NULL_RTX);

	    if (strict_memory_address_addr_space_p
		  (GET_MODE (regno_reg_rtx[i]), XEXP (x, 0),
		   MEM_ADDR_SPACE (x)))
	      reg_equiv_mem (i) = x, reg_equiv_address (i) = 0;
	    else if (CONSTANT_P (XEXP (x, 0))
		     || (REG_P (XEXP (x, 0))
			 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
		     || (GET_CODE (XEXP (x, 0)) == PLUS
			 && REG_P (XEXP (XEXP (x, 0), 0))
			 && (REGNO (XEXP (XEXP (x, 0), 0))
			     < FIRST_PSEUDO_REGISTER)
			 && CONSTANT_P (XEXP (XEXP (x, 0), 1))))
	      reg_equiv_address (i) = XEXP (x, 0), reg_equiv_mem (i) = 0;
	    else
	      {
		/* Make a new stack slot.  Then indicate that something
		   changed so we go back and recompute offsets for
		   eliminable registers because the allocation of memory
		   below might change some offset.  reg_equiv_{mem,address}
		   will be set up for this pseudo on the next pass around
		   the loop.  */
		reg_equiv_memory_loc (i) = 0;
		reg_equiv_init (i) = 0;
		alter_reg (i, -1, true);
	      }
	  }

      if (caller_save_needed)
	setup_save_areas ();

      if (maybe_ne (starting_frame_size, 0) && crtl->stack_alignment_needed)
	{
	  /* If we have a stack frame, we must align it now.  The
	     stack size may be a part of the offset computation for
	     register elimination.  So if this changes the stack size,
	     then repeat the elimination bookkeeping.  We don't
	     realign when there is no stack, as that will cause a
	     stack frame when none is needed should
	     TARGET_STARTING_FRAME_OFFSET not be already aligned to
	     STACK_BOUNDARY.  */
	  assign_stack_local (BLKmode, 0, crtl->stack_alignment_needed);
	}
      /* If we allocated another stack slot, redo elimination bookkeeping.  */
      if (something_was_spilled
	  || maybe_ne (starting_frame_size, get_frame_size ()))
	{
	  if (update_eliminables_and_spill ())
	    finish_spills (0);
	  continue;
	}

      if (caller_save_needed)
	{
	  save_call_clobbered_regs ();
	  /* That might have allocated new insn_chain structures.  */
	  reload_firstobj = XOBNEWVAR (&reload_obstack, char, 0);
	}

      calculate_needs_all_insns (global);

      if (! ira_conflicts_p)
	/* Don't do it for IRA.  We need this info because we don't
	   change live_throughout and dead_or_set for chains when IRA
	   is used.  */
	CLEAR_REG_SET (&spilled_pseudos);

      something_changed = 0;

      /* If we allocated any new memory locations, make another pass
	 since it might have changed elimination offsets.  */
      if (something_was_spilled
	  || maybe_ne (starting_frame_size, get_frame_size ()))
	something_changed = 1;

      /* Even if the frame size remained the same, we might still have
	 changed elimination offsets, e.g. if find_reloads called
	 force_const_mem requiring the back end to allocate a constant
	 pool base register that needs to be saved on the stack.  */
      else if (!verify_initial_elim_offsets ())
	something_changed = 1;

      if (update_eliminables_and_spill ())
	{
	  finish_spills (0);
	  something_changed = 1;
	}
      else
	{
	  select_reload_regs ();
	  if (failure)
	    goto failed;
	  if (insns_need_reload)
	    something_changed |= finish_spills (global);
	}

      if (! something_changed)
	break;

      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
     done.  */
  if (global)
    for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
      if (ep->can_eliminate)
	mark_elimination (ep->from, ep->to);

  remove_init_insns ();

  /* Use the reload registers where necessary
     by generating move instructions to move the must-be-register
     values into or out of the reload registers.  */

  if (insns_need_reload != 0 || something_needs_elimination
      || something_needs_operands_changed)
    {
      poly_int64 old_frame_size = get_frame_size ();

      reload_as_needed (global);

      gcc_assert (known_eq (old_frame_size, get_frame_size ()));

      gcc_assert (verify_initial_elim_offsets ());
    }

  /* If we were able to eliminate the frame pointer, show that it is no
     longer live at the start of any basic block.  If it ls live by
     virtue of being in a pseudo, that pseudo will be marked live
     and hence the frame pointer will be known to be live via that
     pseudo.  */

  if (! frame_pointer_needed)
    FOR_EACH_BB_FN (bb, cfun)
      bitmap_clear_bit (df_get_live_in (bb), HARD_FRAME_POINTER_REGNUM);

  /* Come here (with failure set nonzero) if we can't get enough spill
     regs.  */
 failed:

  CLEAR_REG_SET (&changed_allocation_pseudos);
  CLEAR_REG_SET (&spilled_pseudos);
  reload_in_progress = 0;

  /* Now eliminate all pseudo regs by modifying them into
     their equivalent memory references.
     The REG-rtx's for the pseudos are modified in place,
     so all insns that used to refer to them now refer to memory.

     For a reg that has a reg_equiv_address, all those insns
     were changed by reloading so that no insns refer to it any longer;
     but the DECL_RTL of a variable decl may refer to it,
     and if so this causes the debugging info to mention the variable.  */

  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
    {
      rtx addr = 0;

      if (reg_equiv_mem (i))
	addr = XEXP (reg_equiv_mem (i), 0);

      if (reg_equiv_address (i))
	addr = reg_equiv_address (i);

      if (addr)
	{
	  if (reg_renumber[i] < 0)
	    {
	      rtx reg = regno_reg_rtx[i];

	      REG_USERVAR_P (reg) = 0;
	      PUT_CODE (reg, MEM);
	      XEXP (reg, 0) = addr;
	      if (reg_equiv_memory_loc (i))
		MEM_COPY_ATTRIBUTES (reg, reg_equiv_memory_loc (i));
	      else
		MEM_ATTRS (reg) = 0;
	      MEM_NOTRAP_P (reg) = 1;
	    }
	  else if (reg_equiv_mem (i))
	    XEXP (reg_equiv_mem (i), 0) = addr;
	}

      /* We don't want complex addressing modes in debug insns
	 if simpler ones will do, so delegitimize equivalences
	 in debug insns.  */
      if (MAY_HAVE_DEBUG_BIND_INSNS && reg_renumber[i] < 0)
	{
	  rtx reg = regno_reg_rtx[i];
	  rtx equiv = 0;
	  df_ref use, next;

	  if (reg_equiv_constant (i))
	    equiv = reg_equiv_constant (i);
	  else if (reg_equiv_invariant (i))
	    equiv = reg_equiv_invariant (i);
	  else if (reg && MEM_P (reg))
	    equiv = targetm.delegitimize_address (reg);
	  else if (reg && REG_P (reg) && (int)REGNO (reg) != i)
	    equiv = reg;

	  if (equiv == reg)
	    continue;

	  for (use = DF_REG_USE_CHAIN (i); use; use = next)
	    {
	      insn = DF_REF_INSN (use);

	      /* Make sure the next ref is for a different instruction,
		 so that we're not affected by the rescan.  */
	      next = DF_REF_NEXT_REG (use);
	      while (next && DF_REF_INSN (next) == insn)
		next = DF_REF_NEXT_REG (next);

	      if (DEBUG_BIND_INSN_P (insn))
		{
		  if (!equiv)
		    {
		      INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
		      df_insn_rescan_debug_internal (insn);
		    }
		  else
		    INSN_VAR_LOCATION_LOC (insn)
		      = simplify_replace_rtx (INSN_VAR_LOCATION_LOC (insn),
					      reg, equiv);
		}
	    }
	}
    }

  /* We must set reload_completed now since the cleanup_subreg_operands call
     below will re-recognize each insn and reload may have generated insns
     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, except those that refer to the return
     value and the special mem:BLK CLOBBERs added to prevent the scheduler
     from misarranging variable-array code, and simplify (subreg (reg))
     operands.  Strip and regenerate REG_INC notes that may have been moved
     around.  */

  for (insn = first; insn; insn = NEXT_INSN (insn))
    if (INSN_P (insn))
      {
	rtx *pnote;

	if (CALL_P (insn))
	  replace_pseudos_in (& CALL_INSN_FUNCTION_USAGE (insn),
			      VOIDmode, CALL_INSN_FUNCTION_USAGE (insn));

	if ((GET_CODE (PATTERN (insn)) == USE
	     /* We mark with QImode USEs introduced by reload itself.  */
	     && (GET_MODE (insn) == QImode
		 || find_reg_note (insn, REG_EQUAL, NULL_RTX)))
	    || (GET_CODE (PATTERN (insn)) == CLOBBER
		&& (!MEM_P (XEXP (PATTERN (insn), 0))
		    || GET_MODE (XEXP (PATTERN (insn), 0)) != BLKmode
		    || (GET_CODE (XEXP (XEXP (PATTERN (insn), 0), 0)) != SCRATCH
			&& XEXP (XEXP (PATTERN (insn), 0), 0)
				!= stack_pointer_rtx))
		&& (!REG_P (XEXP (PATTERN (insn), 0))
		    || ! REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))))
	  {
	    delete_insn (insn);
	    continue;
	  }

	/* Some CLOBBERs may survive until here and still reference unassigned
	   pseudos with const equivalent, which may in turn cause ICE in later
	   passes if the reference remains in place.  */
	if (GET_CODE (PATTERN (insn)) == CLOBBER)
	  replace_pseudos_in (& XEXP (PATTERN (insn), 0),
			      VOIDmode, PATTERN (insn));

	/* Discard obvious no-ops, even without -O.  This optimization
	   is fast and doesn't interfere with debugging.  */
	if (NONJUMP_INSN_P (insn)
	    && GET_CODE (PATTERN (insn)) == SET
	    && REG_P (SET_SRC (PATTERN (insn)))
	    && REG_P (SET_DEST (PATTERN (insn)))
	    && (REGNO (SET_SRC (PATTERN (insn)))
		== REGNO (SET_DEST (PATTERN (insn)))))
	  {
	    delete_insn (insn);
	    continue;
	  }

	pnote = &REG_NOTES (insn);
	while (*pnote != 0)
	  {
	    if (REG_NOTE_KIND (*pnote) == REG_DEAD
		|| REG_NOTE_KIND (*pnote) == REG_UNUSED
		|| REG_NOTE_KIND (*pnote) == REG_INC)
	      *pnote = XEXP (*pnote, 1);
	    else
	      pnote = &XEXP (*pnote, 1);
	  }

	if (AUTO_INC_DEC)
	  add_auto_inc_notes (insn, PATTERN (insn));

	/* Simplify (subreg (reg)) if it appears as an operand.  */
	cleanup_subreg_operands (insn);

	/* Clean up invalid ASMs so that they don't confuse later passes.
	   See PR 21299.  */
	if (asm_noperands (PATTERN (insn)) >= 0)
	  {
	    extract_insn (insn);
	    if (!constrain_operands (1, get_enabled_alternatives (insn)))
	      {
		error_for_asm (insn,
			       "%<asm%> operand has impossible constraints");
		delete_insn (insn);
		continue;
	      }
	  }
      }

  free (temp_pseudo_reg_arr);

  /* Indicate that we no longer have known memory locations or constants.  */
  free_reg_equiv ();

  free (reg_max_ref_mode);
  free (reg_old_renumber);
  free (pseudo_previous_regs);
  free (pseudo_forbidden_regs);

  CLEAR_HARD_REG_SET (used_spill_regs);
  for (i = 0; i < n_spills; i++)
    SET_HARD_REG_BIT (used_spill_regs, spill_regs[i]);

  /* Free all the insn_chain structures at once.  */
  obstack_free (&reload_obstack, reload_startobj);
  unused_insn_chains = 0;

  inserted = fixup_abnormal_edges ();

  /* We've possibly turned single trapping insn into multiple ones.  */
  if (cfun->can_throw_non_call_exceptions)
    {
      auto_sbitmap blocks (last_basic_block_for_fn (cfun));
      bitmap_ones (blocks);
      find_many_sub_basic_blocks (blocks);
    }

  if (inserted)
    commit_edge_insertions ();

  /* Replacing pseudos with their memory equivalents might have
     created shared rtx.  Subsequent passes would get confused
     by this, so unshare everything here.  */
  unshare_all_rtl_again (first);

#ifdef STACK_BOUNDARY
  /* init_emit has set the alignment of the hard frame pointer
     to STACK_BOUNDARY.  It is very likely no longer valid if
     the hard frame pointer was used for register allocation.  */
  if (!frame_pointer_needed)
    REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT;
#endif

  substitute_stack.release ();

  gcc_assert (bitmap_empty_p (&spilled_pseudos));

  reload_completed = !failure;

  return need_dce;
}

/* Yet another special case.  Unfortunately, reg-stack forces people to
   write incorrect clobbers in asm statements.  These clobbers must not
   cause the register to appear in bad_spill_regs, otherwise we'll call
   fatal_insn later.  We clear the corresponding regnos in the live
   register sets to avoid this.
   The whole thing is rather sick, I'm afraid.  */

static void
maybe_fix_stack_asms (void)
{
#ifdef STACK_REGS
  const char *constraints[MAX_RECOG_OPERANDS];
  machine_mode operand_mode[MAX_RECOG_OPERANDS];
  struct insn_chain *chain;

  for (chain = reload_insn_chain; chain != 0; chain = chain->next)
    {
      int i, noperands;
      HARD_REG_SET clobbered, allowed;
      rtx pat;

      if (! INSN_P (chain->insn)
	  || (noperands = asm_noperands (PATTERN (chain->insn))) < 0)
	continue;
      pat = PATTERN (chain->insn);
      if (GET_CODE (pat) != PARALLEL)
	continue;

      CLEAR_HARD_REG_SET (clobbered);
      CLEAR_HARD_REG_SET (allowed);

      /* First, make a mask of all stack regs that are clobbered.  */
      for (i = 0; i < XVECLEN (pat, 0); i++)
	{
	  rtx t = XVECEXP (pat, 0, i);
	  if (GET_CODE (t) == CLOBBER && STACK_REG_P (XEXP (t, 0)))
	    SET_HARD_REG_BIT (clobbered, REGNO (XEXP (t, 0)));
	  /* CLOBBER_HIGH is only supported for LRA.  */
	  gcc_assert (GET_CODE (t) != CLOBBER_HIGH);
	}

      /* Get the operand values and constraints out of the insn.  */
      decode_asm_operands (pat, recog_data.operand, recog_data.operand_loc,
			   constraints, operand_mode, NULL);

      /* For every operand, see what registers are allowed.  */
      for (i = 0; i < noperands; i++)
	{
	  const char *p = constraints[i];
	  /* For every alternative, we compute the class of registers allowed
	     for reloading in CLS, and merge its contents into the reg set
	     ALLOWED.  */
	  int cls = (int) NO_REGS;

	  for (;;)
	    {
	      char c = *p;

	      if (c == '\0' || c == ',' || c == '#')
		{
		  /* End of one alternative - mark the regs in the current
		     class, and reset the class.  */
		  IOR_HARD_REG_SET (allowed, reg_class_contents[cls]);
		  cls = NO_REGS;
		  p++;
		  if (c == '#')
		    do {
		      c = *p++;
		    } while (c != '\0' && c != ',');
		  if (c == '\0')
		    break;
		  continue;
		}

	      switch (c)
		{
		case 'g':
		  cls = (int) reg_class_subunion[cls][(int) GENERAL_REGS];
		  break;

		default:
		  enum constraint_num cn = lookup_constraint (p);
		  if (insn_extra_address_constraint (cn))
		    cls = (int) reg_class_subunion[cls]
		      [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
					     ADDRESS, SCRATCH)];
		  else
		    cls = (int) reg_class_subunion[cls]
		      [reg_class_for_constraint (cn)];
		  break;
		}
	      p += CONSTRAINT_LEN (c, p);
	    }
	}
      /* Those of the registers which are clobbered, but allowed by the
	 constraints, must be usable as reload registers.  So clear them
	 out of the life information.  */
      AND_HARD_REG_SET (allowed, clobbered);
      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	if (TEST_HARD_REG_BIT (allowed, i))
	  {
	    CLEAR_REGNO_REG_SET (&chain->live_throughout, i);
	    CLEAR_REGNO_REG_SET (&chain->dead_or_set, i);
	  }
    }

#endif
}

/* Copy the global variables n_reloads and rld into the corresponding elts
   of CHAIN.  */
static void
copy_reloads (struct insn_chain *chain)
{
  chain->n_reloads = n_reloads;
  chain->rld = XOBNEWVEC (&reload_obstack, struct reload, n_reloads);
  memcpy (chain->rld, rld, n_reloads * sizeof (struct reload));
  reload_insn_firstobj = XOBNEWVAR (&reload_obstack, char, 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.  */
static void
calculate_needs_all_insns (int global)
{
  struct insn_chain **pprev_reload = &insns_need_reload;
  struct insn_chain *chain, *next = 0;

  something_needs_elimination = 0;

  reload_insn_firstobj = XOBNEWVAR (&reload_obstack, char, 0);
  for (chain = reload_insn_chain; chain != 0; chain = next)
    {
      rtx_insn *insn = chain->insn;

      next = chain->next;

      /* 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_OPERAND and REG_LABEL_TARGET), we need to see
	 what effects this has on the known offsets at labels.  */

      if (LABEL_P (insn) || JUMP_P (insn) || JUMP_TABLE_DATA_P (insn)
	  || (INSN_P (insn) && REG_NOTES (insn) != 0))
	set_label_offsets (insn, insn, 0);

      if (INSN_P (insn))
	{
	  rtx old_body = PATTERN (insn);
	  int old_code = INSN_CODE (insn);
	  rtx old_notes = REG_NOTES (insn);
	  int did_elimination = 0;
	  int operands_changed = 0;

	  /* Skip insns that only set an equivalence.  */
	  if (will_delete_init_insn_p (insn))
	    continue;

	  /* If needed, eliminate any eliminable registers.  */
	  if (num_eliminable || num_eliminable_invariants)
	    did_elimination = eliminate_regs_in_insn (insn, 0);

	  /* Analyze the instruction.  */
	  operands_changed = find_reloads (insn, 0, spill_indirect_levels,
					   global, spill_reg_order);

	  /* If a no-op set needs more than one reload, this is likely
	     to be something that needs input address reloads.  We
	     can't get rid of this cleanly later, and it is of no use
	     anyway, so discard it now.
	     We only do this when expensive_optimizations is enabled,
	     since this complements reload inheritance / output
	     reload deletion, and it can make debugging harder.  */
	  if (flag_expensive_optimizations && n_reloads > 1)
	    {
	      rtx set = single_set (insn);
	      if (set
		  &&
		  ((SET_SRC (set) == SET_DEST (set)
		    && REG_P (SET_SRC (set))
		    && REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER)
		   || (REG_P (SET_SRC (set)) && REG_P (SET_DEST (set))
		       && reg_renumber[REGNO (SET_SRC (set))] < 0
		       && reg_renumber[REGNO (SET_DEST (set))] < 0
		       && reg_equiv_memory_loc (REGNO (SET_SRC (set))) != NULL
		       && reg_equiv_memory_loc (REGNO (SET_DEST (set))) != NULL
		       && rtx_equal_p (reg_equiv_memory_loc (REGNO (SET_SRC (set))),
				       reg_equiv_memory_loc (REGNO (SET_DEST (set)))))))
		{
		  if (ira_conflicts_p)
		    /* Inform IRA about the insn deletion.  */
		    ira_mark_memory_move_deletion (REGNO (SET_DEST (set)),
						   REGNO (SET_SRC (set)));
		  delete_insn (insn);
		  /* Delete it from the reload chain.  */
		  if (chain->prev)
		    chain->prev->next = next;
		  else
		    reload_insn_chain = next;
		  if (next)
		    next->prev = chain->prev;
		  chain->next = unused_insn_chains;
		  unused_insn_chains = chain;
		  continue;
		}
	    }
	  if (num_eliminable)
	    update_eliminable_offsets ();

	  /* Remember for later shortcuts which insns had any reloads or
	     register eliminations.  */
	  chain->need_elim = did_elimination;
	  chain->need_reload = n_reloads > 0;
	  chain->need_operand_change = operands_changed;

	  /* Discard any register replacements done.  */
	  if (did_elimination)
	    {
	      obstack_free (&reload_obstack, reload_insn_firstobj);
	      PATTERN (insn) = old_body;
	      INSN_CODE (insn) = old_code;
	      REG_NOTES (insn) = old_notes;
	      something_needs_elimination = 1;
	    }

	  something_needs_operands_changed |= operands_changed;

	  if (n_reloads != 0)
	    {
	      copy_reloads (chain);
	      *pprev_reload = chain;
	      pprev_reload = &chain->next_need_reload;
	    }
	}
    }
  *pprev_reload = 0;
}

/* This function is called from the register allocator to set up estimates
   for the cost of eliminating pseudos which have REG_EQUIV equivalences to
   an invariant.  The structure is similar to calculate_needs_all_insns.  */

void
calculate_elim_costs_all_insns (void)
{
  int *reg_equiv_init_cost;
  basic_block bb;
  int i;

  reg_equiv_init_cost = XCNEWVEC (int, max_regno);
  init_elim_table ();
  init_eliminable_invariants (get_insns (), false);

  set_initial_elim_offsets ();
  set_initial_label_offsets ();

  FOR_EACH_BB_FN (bb, cfun)
    {
      rtx_insn *insn;
      elim_bb = bb;

      FOR_BB_INSNS (bb, insn)
	{
	  /* If this is a label, a JUMP_INSN, or has REG_NOTES (which might
	     include REG_LABEL_OPERAND and REG_LABEL_TARGET), we need to see
	     what effects this has on the known offsets at labels.  */

	  if (LABEL_P (insn) || JUMP_P (insn) || JUMP_TABLE_DATA_P (insn)
	      || (INSN_P (insn) && REG_NOTES (insn) != 0))
	    set_label_offsets (insn, insn, 0);

	  if (INSN_P (insn))
	    {
	      rtx set = single_set (insn);

	      /* Skip insns that only set an equivalence.  */
	      if (set && REG_P (SET_DEST (set))
		  && reg_renumber[REGNO (SET_DEST (set))] < 0
		  && (reg_equiv_constant (REGNO (SET_DEST (set)))
		      || reg_equiv_invariant (REGNO (SET_DEST (set)))))
		{
		  unsigned regno = REGNO (SET_DEST (set));
		  rtx_insn_list *init = reg_equiv_init (regno);
		  if (init)
		    {
		      rtx t = eliminate_regs_1 (SET_SRC (set), VOIDmode, insn,
						false, true);
		      machine_mode mode = GET_MODE (SET_DEST (set));
		      int cost = set_src_cost (t, mode,
					       optimize_bb_for_speed_p (bb));
		      int freq = REG_FREQ_FROM_BB (bb);

		      reg_equiv_init_cost[regno] = cost * freq;
		      continue;
		    }
		}
	      /* If needed, eliminate any eliminable registers.  */
	      if (num_eliminable || num_eliminable_invariants)
		elimination_costs_in_insn (insn);

	      if (num_eliminable)
		update_eliminable_offsets ();
	    }
	}
    }
  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
    {
      if (reg_equiv_invariant (i))
	{
	  if (reg_equiv_init (i))
	    {
	      int cost = reg_equiv_init_cost[i];
	      if (dump_file)
		fprintf (dump_file,
			 "Reg %d has equivalence, initial gains %d\n", i, cost);
	      if (cost != 0)
		ira_adjust_equiv_reg_cost (i, cost);
	    }
	  else
	    {
	      if (dump_file)
		fprintf (dump_file,
			 "Reg %d had equivalence, but can't be eliminated\n",
			 i);
	      ira_adjust_equiv_reg_cost (i, 0);
	    }
	}
    }

  free (reg_equiv_init_cost);
  free (offsets_known_at);
  free (offsets_at);
  offsets_at = NULL;
  offsets_known_at = NULL;
}

/* 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 (const void *r1p, const void *r2p)
{
  int r1 = *(const short *) r1p, r2 = *(const short *) r2p;
  int t;

  /* Consider required reloads before optional ones.  */
  t = rld[r1].optional - rld[r2].optional;
  if (t != 0)
    return t;

  /* Count all solitary classes before non-solitary ones.  */
  t = ((reg_class_size[(int) rld[r2].rclass] == 1)
       - (reg_class_size[(int) rld[r1].rclass] == 1));
  if (t != 0)
    return t;

  /* Aside from solitaires, consider all multi-reg groups first.  */
  t = rld[r2].nregs - rld[r1].nregs;
  if (t != 0)
    return t;

  /* Consider reloads in order of increasing reg-class number.  */
  t = (int) rld[r1].rclass - (int) rld[r2].rclass;
  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;
}

/* The cost of spilling each hard reg.  */
static int spill_cost[FIRST_PSEUDO_REGISTER];

/* 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];

/* Map of hard regno to pseudo regno currently occupying the hard
   reg.  */
static int hard_regno_to_pseudo_regno[FIRST_PSEUDO_REGISTER];

/* Update the spill cost arrays, considering that pseudo REG is live.  */

static void
count_pseudo (int reg)
{
  int freq = REG_FREQ (reg);
  int r = reg_renumber[reg];
  int nregs;

  /* Ignore spilled pseudo-registers which can be here only if IRA is used.  */
  if (ira_conflicts_p && r < 0)
    return;

  if (REGNO_REG_SET_P (&pseudos_counted, reg)
      || REGNO_REG_SET_P (&spilled_pseudos, reg))
    return;

  SET_REGNO_REG_SET (&pseudos_counted, reg);

  gcc_assert (r >= 0);

  spill_add_cost[r] += freq;
  nregs = hard_regno_nregs (r, PSEUDO_REGNO_MODE (reg));
  while (nregs-- > 0)
    {
      hard_regno_to_pseudo_regno[r + nregs] = reg;
      spill_cost[r + nregs] += freq;
    }
}

/* 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 (struct insn_chain *chain)
{
  unsigned i;
  HARD_REG_SET used_by_pseudos;
  HARD_REG_SET used_by_pseudos2;
  reg_set_iterator rsi;

  COPY_HARD_REG_SET (bad_spill_regs, fixed_reg_set);

  memset (spill_cost, 0, sizeof spill_cost);
  memset (spill_add_cost, 0, sizeof spill_add_cost);
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    hard_regno_to_pseudo_regno[i] = -1;

  /* Count number of uses of each hard reg by pseudo regs allocated to it
     and then order them by decreasing use.  First exclude hard registers
     that are live in or across this insn.  */

  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 (bad_spill_regs, used_by_pseudos);
  IOR_HARD_REG_SET (bad_spill_regs, used_by_pseudos2);

  /* 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_throughout, FIRST_PSEUDO_REGISTER, i, rsi)
    {
      count_pseudo (i);
    }
  EXECUTE_IF_SET_IN_REG_SET
    (&chain->dead_or_set, FIRST_PSEUDO_REGISTER, i, rsi)
    {
      count_pseudo (i);
    }
  CLEAR_REG_SET (&pseudos_counted);
}

/* Vector of reload-numbers showing the order in which the reloads should
   be processed.  */
static short reload_order[MAX_RELOADS];

/* 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
count_spilled_pseudo (int spilled, int spilled_nregs, int reg)
{
  int freq = REG_FREQ (reg);
  int r = reg_renumber[reg];
  int nregs;

  /* Ignore spilled pseudo-registers which can be here only if IRA is used.  */
  if (ira_conflicts_p && r < 0)
    return;

  gcc_assert (r >= 0);

  nregs = hard_regno_nregs (r, PSEUDO_REGNO_MODE (reg));

  if (REGNO_REG_SET_P (&spilled_pseudos, reg)
      || spilled + spilled_nregs <= r || r + nregs <= spilled)
    return;

  SET_REGNO_REG_SET (&spilled_pseudos, reg);

  spill_add_cost[r] -= freq;
  while (nregs-- > 0)
    {
      hard_regno_to_pseudo_regno[r + nregs] = -1;
      spill_cost[r + nregs] -= freq;
    }
}

/* Find reload register to use for reload number ORDER.  */

static int
find_reg (struct insn_chain *chain, int order)
{
  int rnum = reload_order[order];
  struct reload *rl = rld + rnum;
  int best_cost = INT_MAX;
  int best_reg = -1;
  unsigned int i, j, n;
  int k;
  HARD_REG_SET not_usable;
  HARD_REG_SET used_by_other_reload;
  reg_set_iterator rsi;
  static int regno_pseudo_regs[FIRST_PSEUDO_REGISTER];
  static int best_regno_pseudo_regs[FIRST_PSEUDO_REGISTER];

  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->rclass]);

  CLEAR_HARD_REG_SET (used_by_other_reload);
  for (k = 0; k < order; k++)
    {
      int other = reload_order[k];

      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);
    }

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
#ifdef REG_ALLOC_ORDER
      unsigned int regno = reg_alloc_order[i];
#else
      unsigned int regno = i;
#endif

      if (! TEST_HARD_REG_BIT (not_usable, regno)
	  && ! TEST_HARD_REG_BIT (used_by_other_reload, regno)
	  && targetm.hard_regno_mode_ok (regno, rl->mode))
	{
	  int this_cost = spill_cost[regno];
	  int ok = 1;
	  unsigned int this_nregs = hard_regno_nregs (regno, rl->mode);

	  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 (ira_conflicts_p)
	    {
	      /* Ask IRA to find a better pseudo-register for
		 spilling.  */
	      for (n = j = 0; j < this_nregs; j++)
		{
		  int r = hard_regno_to_pseudo_regno[regno + j];

		  if (r < 0)
		    continue;
		  if (n == 0 || regno_pseudo_regs[n - 1] != r)
		    regno_pseudo_regs[n++] = r;
		}
	      regno_pseudo_regs[n++] = -1;
	      if (best_reg < 0
		  || ira_better_spill_reload_regno_p (regno_pseudo_regs,
						      best_regno_pseudo_regs,
						      rl->in, rl->out,
						      chain->insn))
		{
		  best_reg = regno;
		  for (j = 0;; j++)
		    {
		      best_regno_pseudo_regs[j] = regno_pseudo_regs[j];
		      if (regno_pseudo_regs[j] < 0)
			break;
		    }
		}
	      continue;
	    }

	  if (rl->in && REG_P (rl->in) && REGNO (rl->in) == regno)
	    this_cost--;
	  if (rl->out && REG_P (rl->out) && 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;
	    }
	}
    }
  if (best_reg == -1)
    return 0;

  if (dump_file)
    fprintf (dump_file, "Using reg %d for reload %d\n", best_reg, rnum);

  rl->nregs = hard_regno_nregs (best_reg, rl->mode);
  rl->regno = best_reg;

  EXECUTE_IF_SET_IN_REG_SET
    (&chain->live_throughout, FIRST_PSEUDO_REGISTER, j, rsi)
    {
      count_spilled_pseudo (best_reg, rl->nregs, j);
    }

  EXECUTE_IF_SET_IN_REG_SET
    (&chain->dead_or_set, FIRST_PSEUDO_REGISTER, j, rsi)
    {
      count_spilled_pseudo (best_reg, rl->nregs, j);
    }

  for (i = 0; i < rl->nregs; i++)
    {
      gcc_assert (spill_cost[best_reg + i] == 0);
      gcc_assert (spill_add_cost[best_reg + i] == 0);
      gcc_assert (hard_regno_to_pseudo_regno[best_reg + i] == -1);
      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.  */

static void
find_reload_regs (struct insn_chain *chain)
{
  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)
	{
	  chain->rld[i].regno = REGNO (chain->rld[i].reg_rtx);
	  chain->rld[i].nregs = REG_NREGS (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 (dump_file)
    fprintf (dump_file, "Spilling for insn %d.\n", INSN_UID (chain->insn));

  qsort (reload_order, n_reloads, sizeof (short), reload_reg_class_lower);

  /* Compute the order of preference for hard registers to spill.  */

  order_regs_for_reload (chain);

  for (i = 0; i < n_reloads; i++)
    {
      int r = reload_order[i];

      /* 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))
	  {
	    if (dump_file)
	      fprintf (dump_file, "reload failure for reload %d\n", r);
	    spill_failure (chain->insn, rld[r].rclass);
	    failure = 1;
	    return;
	  }
    }

  COPY_HARD_REG_SET (chain->used_spill_regs, used_spill_regs_local);
  IOR_HARD_REG_SET (used_spill_regs, used_spill_regs_local);

  memcpy (chain->rld, rld, n_reloads * sizeof (struct reload));
}

static void
select_reload_regs (void)
{
  struct insn_chain *chain;

  /* Try to satisfy the needs for each insn.  */
  for (chain = insns_need_reload; chain != 0;
       chain = chain->next_need_reload)
    find_reload_regs (chain);
}

/* Delete all insns that were inserted by emit_caller_save_insns during
   this iteration.  */
static void
delete_caller_save_insns (void)
{
  struct insn_chain *c = reload_insn_chain;

  while (c != 0)
    {
      while (c != 0 && c->is_caller_save_insn)
	{
	  struct insn_chain *next = c->next;
	  rtx_insn *insn = c->insn;

	  if (c == reload_insn_chain)
	    reload_insn_chain = next;
	  delete_insn (insn);

	  if (next)
	    next->prev = c->prev;
	  if (c->prev)
	    c->prev->next = next;
	  c->next = unused_insn_chains;
	  unused_insn_chains = c;
	  c = next;
	}
      if (c != 0)
	c = c->next;
    }
}

/* 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 (rtx_insn *insn, enum reg_class rclass)
{
  if (asm_noperands (PATTERN (insn)) >= 0)
    error_for_asm (insn, "can%'t find a register in class %qs while "
		   "reloading %<asm%>",
		   reg_class_names[rclass]);
  else
    {
      error ("unable to find a register to spill in class %qs",
	     reg_class_names[rclass]);

      if (dump_file)
	{
	  fprintf (dump_file, "\nReloads for insn # %d\n", INSN_UID (insn));
	  debug_reload_to_stream (dump_file);
	}
      fatal_insn ("this is the insn:", insn);
    }
}

/* Delete an unneeded INSN and any previous insns who sole purpose is loading
   data that is dead in INSN.  */

static void
delete_dead_insn (rtx_insn *insn)
{
  rtx_insn *prev = prev_active_insn (insn);
  rtx prev_dest;

  /* If the previous insn sets a register that dies in our insn make
     a note that we want to run DCE immediately after reload.

     We used to delete the previous insn & recurse, but that's wrong for
     block local equivalences.  Instead of trying to figure out the exact
     circumstances where we can delete the potentially dead insns, just
     let DCE do the job.  */
  if (prev && BLOCK_FOR_INSN (prev) == BLOCK_FOR_INSN (insn)
      && GET_CODE (PATTERN (prev)) == SET
      && (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest))
      && reg_mentioned_p (prev_dest, PATTERN (insn))
      && find_regno_note (insn, REG_DEAD, REGNO (prev_dest))
      && ! side_effects_p (SET_SRC (PATTERN (prev))))
    need_dce = 1;

  SET_INSN_DELETED (insn);
}

/* Modify the home of pseudo-reg I.
   The new home is present in reg_renumber[I].

   FROM_REG may be the hard reg that the pseudo-reg is being spilled from;
   or it may be -1, meaning there is none or it is not relevant.
   This is used so that all pseudos spilled from a given hard reg
   can share one stack slot.  */

static void
alter_reg (int i, int from_reg, bool dont_share_p)
{
  /* When outputting an inline function, this can happen
     for a reg that isn't actually used.  */
  if (regno_reg_rtx[i] == 0)
    return;

  /* If the reg got changed to a MEM at rtl-generation time,
     ignore it.  */
  if (!REG_P (regno_reg_rtx[i]))
    return;

  /* Modify the reg-rtx to contain the new hard reg
     number or else to contain its pseudo reg number.  */
  SET_REGNO (regno_reg_rtx[i],
	     reg_renumber[i] >= 0 ? reg_renumber[i] : i);

  /* If we have a pseudo that is needed but has no hard reg or equivalent,
     allocate a stack slot for it.  */

  if (reg_renumber[i] < 0
      && REG_N_REFS (i) > 0
      && reg_equiv_constant (i) == 0
      && (reg_equiv_invariant (i) == 0
	  || reg_equiv_init (i) == 0)
      && reg_equiv_memory_loc (i) == 0)
    {
      rtx x = NULL_RTX;
      machine_mode mode = GET_MODE (regno_reg_rtx[i]);
      poly_uint64 inherent_size = GET_MODE_SIZE (mode);
      unsigned int inherent_align = GET_MODE_ALIGNMENT (mode);
      machine_mode wider_mode = wider_subreg_mode (mode, reg_max_ref_mode[i]);
      poly_uint64 total_size = GET_MODE_SIZE (wider_mode);
      /* ??? Seems strange to derive the minimum alignment from the size,
	 but that's the traditional behavior.  For polynomial-size modes,
	 the natural extension is to use the minimum possible size.  */
      unsigned int min_align
	= constant_lower_bound (GET_MODE_BITSIZE (reg_max_ref_mode[i]));
      poly_int64 adjust = 0;

      something_was_spilled = true;

      if (ira_conflicts_p)
	{
	  /* Mark the spill for IRA.  */
	  SET_REGNO_REG_SET (&spilled_pseudos, i);
	  if (!dont_share_p)
	    x = ira_reuse_stack_slot (i, inherent_size, total_size);
	}

      if (x)
	;

      /* Each pseudo reg has an inherent size which comes from its own mode,
	 and a total size which provides room for paradoxical subregs
	 which refer to the pseudo reg in wider modes.

	 We can use a slot already allocated if it provides both
	 enough inherent space and enough total space.
	 Otherwise, we allocate a new slot, making sure that it has no less
	 inherent space, and no less total space, then the previous slot.  */
      else if (from_reg == -1 || (!dont_share_p && ira_conflicts_p))
	{
	  rtx stack_slot;

	  /* The sizes are taken from a subreg operation, which guarantees
	     that they're ordered.  */
	  gcc_checking_assert (ordered_p (total_size, inherent_size));

	  /* No known place to spill from => no slot to reuse.  */
	  x = assign_stack_local (mode, total_size,
				  min_align > inherent_align
				  || maybe_gt (total_size, inherent_size)
				  ? -1 : 0);

	  stack_slot = x;

	  /* Cancel the big-endian correction done in assign_stack_local.
	     Get the address of the beginning of the slot.  This is so we
	     can do a big-endian correction unconditionally below.  */
	  if (BYTES_BIG_ENDIAN)
	    {
	      adjust = inherent_size - total_size;
	      if (maybe_ne (adjust, 0))
		{
		  poly_uint64 total_bits = total_size * BITS_PER_UNIT;
		  machine_mode mem_mode
		    = int_mode_for_size (total_bits, 1).else_blk ();
		  stack_slot = adjust_address_nv (x, mem_mode, adjust);
		}
	    }

	  if (! dont_share_p && ira_conflicts_p)
	    /* Inform IRA about allocation a new stack slot.  */
	    ira_mark_new_stack_slot (stack_slot, i, total_size);
	}

      /* Reuse a stack slot if possible.  */
      else if (spill_stack_slot[from_reg] != 0
	       && known_ge (spill_stack_slot_width[from_reg], total_size)
	       && known_ge (GET_MODE_SIZE
			    (GET_MODE (spill_stack_slot[from_reg])),
			    inherent_size)
	       && MEM_ALIGN (spill_stack_slot[from_reg]) >= min_align)
	x = spill_stack_slot[from_reg];

      /* Allocate a bigger slot.  */
      else
	{
	  /* Compute maximum size needed, both for inherent size
	     and for total size.  */
	  rtx stack_slot;

	  if (spill_stack_slot[from_reg])
	    {
	      if (partial_subreg_p (mode,
				    GET_MODE (spill_stack_slot[from_reg])))
		mode = GET_MODE (spill_stack_slot[from_reg]);
	      total_size = ordered_max (total_size,
					spill_stack_slot_width[from_reg]);
	      if (MEM_ALIGN (spill_stack_slot[from_reg]) > min_align)
		min_align = MEM_ALIGN (spill_stack_slot[from_reg]);
	    }

	  /* The sizes are taken from a subreg operation, which guarantees
	     that they're ordered.  */
	  gcc_checking_assert (ordered_p (total_size, inherent_size));

	  /* Make a slot with that size.  */
	  x = assign_stack_local (mode, total_size,
				  min_align > inherent_align
				  || maybe_gt (total_size, inherent_size)
				  ? -1 : 0);
	  stack_slot = x;

	  /* Cancel the  big-endian correction done in assign_stack_local.
	     Get the address of the beginning of the slot.  This is so we
	     can do a big-endian correction unconditionally below.  */
	  if (BYTES_BIG_ENDIAN)
	    {
	      adjust = GET_MODE_SIZE (mode) - total_size;
	      if (maybe_ne (adjust, 0))
		{
		  poly_uint64 total_bits = total_size * BITS_PER_UNIT;
		  machine_mode mem_mode
		    = int_mode_for_size (total_bits, 1).else_blk ();
		  stack_slot = adjust_address_nv (x, mem_mode, adjust);
		}
	    }

	  spill_stack_slot[from_reg] = stack_slot;
	  spill_stack_slot_width[from_reg] = total_size;
	}

      /* On a big endian machine, the "address" of the slot
	 is the address of the low part that fits its inherent mode.  */
      adjust += subreg_size_lowpart_offset (inherent_size, total_size);

      /* If we have any adjustment to make, or if the stack slot is the
	 wrong mode, make a new stack slot.  */
      x = adjust_address_nv (x, GET_MODE (regno_reg_rtx[i]), adjust);

      /* Set all of the memory attributes as appropriate for a spill.  */
      set_mem_attrs_for_spill (x);

      /* Save the stack slot for later.  */
      reg_equiv_memory_loc (i) = x;
    }
}

/* Mark the slots in regs_ever_live for the hard regs used by
   pseudo-reg number REGNO, accessed in MODE.  */

static void
mark_home_live_1 (int regno, machine_mode mode)
{
  int i, lim;

  i = reg_renumber[regno];
  if (i < 0)
    return;
  lim = end_hard_regno (mode, i);
  while (i < lim)
    df_set_regs_ever_live (i++, true);
}

/* Mark the slots in regs_ever_live for the hard regs
   used by pseudo-reg number REGNO.  */

void
mark_home_live (int regno)
{
  if (reg_renumber[regno] >= 0)
    mark_home_live_1 (regno, PSEUDO_REGNO_MODE (regno));
}

/* This function handles the tracking of elimination offsets around branches.

   X is a piece of RTL being scanned.

   INSN is the insn that it came from, if any.

   INITIAL_P is nonzero if we are to set the offset to be the initial
   offset and zero if we are setting the offset of the label to be the
   current offset.  */

static void
set_label_offsets (rtx x, rtx_insn *insn, int initial_p)
{
  enum rtx_code code = GET_CODE (x);
  rtx tem;
  unsigned int i;
  struct elim_table *p;

  switch (code)
    {
    case LABEL_REF:
      if (LABEL_REF_NONLOCAL_P (x))
	return;

      x = label_ref_label (x);

      /* fall through */

    case CODE_LABEL:
      /* If we know nothing about this label, set the desired offsets.  Note
	 that this sets the offset at a label to be the offset before a label
	 if we don't know anything about the label.  This is not correct for
	 the label after a BARRIER, but is the best guess we can make.  If
	 we guessed wrong, we will suppress an elimination that might have
	 been possible had we been able to guess correctly.  */

      if (! offsets_known_at[CODE_LABEL_NUMBER (x) - first_label_num])
	{
	  for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
	    offsets_at[CODE_LABEL_NUMBER (x) - first_label_num][i]
	      = (initial_p ? reg_eliminate[i].initial_offset
		 : reg_eliminate[i].offset);
	  offsets_known_at[CODE_LABEL_NUMBER (x) - first_label_num] = 1;
	}

      /* Otherwise, if this is the definition of a label and it is
	 preceded by a BARRIER, set our offsets to the known offset of
	 that label.  */

      else if (x == insn
	       && (tem = prev_nonnote_insn (insn)) != 0
	       && BARRIER_P (tem))
	set_offsets_for_label (insn);
      else
	/* If neither of the above cases is true, compare each offset
	   with those previously recorded and suppress any eliminations
	   where the offsets disagree.  */

	for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
	  if (maybe_ne (offsets_at[CODE_LABEL_NUMBER (x) - first_label_num][i],
			(initial_p ? reg_eliminate[i].initial_offset
			 : reg_eliminate[i].offset)))
	    reg_eliminate[i].can_eliminate = 0;

      return;

    case JUMP_TABLE_DATA:
      set_label_offsets (PATTERN (insn), insn, initial_p);
      return;

    case JUMP_INSN:
      set_label_offsets (PATTERN (insn), insn, initial_p);

      /* fall through */

    case INSN:
    case CALL_INSN:
      /* Any labels mentioned in REG_LABEL_OPERAND notes can be branched
	 to indirectly and hence must have all eliminations at their
	 initial offsets.  */
      for (tem = REG_NOTES (x); tem; tem = XEXP (tem, 1))
	if (REG_NOTE_KIND (tem) == REG_LABEL_OPERAND)
	  set_label_offsets (XEXP (tem, 0), insn, 1);
      return;

    case PARALLEL:
    case ADDR_VEC:
    case ADDR_DIFF_VEC:
      /* Each of the labels in the parallel or address vector must be
	 at their initial offsets.  We want the first field for PARALLEL
	 and ADDR_VEC and the second field for ADDR_DIFF_VEC.  */

      for (i = 0; i < (unsigned) XVECLEN (x, code == ADDR_DIFF_VEC); i++)
	set_label_offsets (XVECEXP (x, code == ADDR_DIFF_VEC, i),
			   insn, initial_p);
      return;

    case SET:
      /* We only care about setting PC.  If the source is not RETURN,
	 IF_THEN_ELSE, or a label, disable any eliminations not at
	 their initial offsets.  Similarly if any arm of the IF_THEN_ELSE
	 isn't one of those possibilities.  For branches to a label,
	 call ourselves recursively.

	 Note that this can disable elimination unnecessarily when we have
	 a non-local goto since it will look like a non-constant jump to
	 someplace in the current function.  This isn't a significant
	 problem since such jumps will normally be when all elimination
	 pairs are back to their initial offsets.  */

      if (SET_DEST (x) != pc_rtx)
	return;

      switch (GET_CODE (SET_SRC (x)))
	{
	case PC:
	case RETURN:
	  return;

	case LABEL_REF:
	  set_label_offsets (SET_SRC (x), insn, initial_p);
	  return;

	case IF_THEN_ELSE:
	  tem = XEXP (SET_SRC (x), 1);
	  if (GET_CODE (tem) == LABEL_REF)
	    set_label_offsets (label_ref_label (tem), insn, initial_p);
	  else if (GET_CODE (tem) != PC && GET_CODE (tem) != RETURN)
	    break;

	  tem = XEXP (SET_SRC (x), 2);
	  if (GET_CODE (tem) == LABEL_REF)
	    set_label_offsets (label_ref_label (tem), insn, initial_p);
	  else if (GET_CODE (tem) != PC && GET_CODE (tem) != RETURN)
	    break;
	  return;

	default:
	  break;
	}

      /* If we reach here, all eliminations must be at their initial
	 offset because we are doing a jump to a variable address.  */
      for (p = reg_eliminate; p < &reg_eliminate[NUM_ELIMINABLE_REGS]; p++)
	if (maybe_ne (p->offset, p->initial_offset))
	  p->can_eliminate = 0;
      break;

    default:
      break;
    }
}

/* This function examines every reg that occurs in X and adjusts the
   costs for its elimination which are gathered by IRA.  INSN is the
   insn in which X occurs.  We do not recurse into MEM expressions.  */

static void
note_reg_elim_costly (const_rtx x, rtx insn)
{
  subrtx_iterator::array_type array;
  FOR_EACH_SUBRTX (iter, array, x, NONCONST)
    {
      const_rtx x = *iter;
      if (MEM_P (x))
	iter.skip_subrtxes ();
      else if (REG_P (x)
	       && REGNO (x) >= FIRST_PSEUDO_REGISTER
	       && reg_equiv_init (REGNO (x))
	       && reg_equiv_invariant (REGNO (x)))
	{
	  rtx t = reg_equiv_invariant (REGNO (x));
	  rtx new_rtx = eliminate_regs_1 (t, Pmode, insn, true, true);
	  int cost = set_src_cost (new_rtx, Pmode,
				   optimize_bb_for_speed_p (elim_bb));
	  int freq = REG_FREQ_FROM_BB (elim_bb);

	  if (cost != 0)
	    ira_adjust_equiv_reg_cost (REGNO (x), -cost * freq);
	}
    }
}

/* Scan X and replace any eliminable registers (such as fp) with a
   replacement (such as sp), plus an offset.

   MEM_MODE is the mode of an enclosing MEM.  We need this to know how
   much to adjust a register for, e.g., PRE_DEC.  Also, if we are inside a
   MEM, we are allowed to replace a sum of a register and the constant zero
   with the register, which we cannot do outside a MEM.  In addition, we need
   to record the fact that a register is referenced outside a MEM.

   If INSN is an insn, it is the insn containing X.  If we replace a REG
   in a SET_DEST with an equivalent MEM and INSN is nonzero, write a
   CLOBBER of the pseudo after INSN so find_equiv_regs will know that
   the REG is being modified.

   Alternatively, INSN may be a note (an EXPR_LIST or INSN_LIST).
   That's used when we eliminate in expressions stored in notes.
   This means, do not set ref_outside_mem even if the reference
   is outside of MEMs.

   If FOR_COSTS is true, we are being called before reload in order to
   estimate the costs of keeping registers with an equivalence unallocated.

   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
   encounter, return the actual location so that find_reloads will do
   the proper thing.  */

static rtx
eliminate_regs_1 (rtx x, machine_mode mem_mode, rtx insn,
		  bool may_use_invariant, bool for_costs)
{
  enum rtx_code code = GET_CODE (x);
  struct elim_table *ep;
  int regno;
  rtx new_rtx;
  int i, j;
  const char *fmt;
  int copied = 0;

  if (! current_function_decl)
    return x;

  switch (code)
    {
    CASE_CONST_ANY:
    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 x;

    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)
	      return plus_constant (Pmode, ep->to_rtx, ep->previous_offset);

	}
      else if (reg_renumber && reg_renumber[regno] < 0
	       && reg_equivs
	       && reg_equiv_invariant (regno))
	{
	  if (may_use_invariant || (insn && DEBUG_INSN_P (insn)))
	    return eliminate_regs_1 (copy_rtx (reg_equiv_invariant (regno)),
			             mem_mode, insn, true, for_costs);
	  /* There exists at least one use of REGNO that cannot be
	     eliminated.  Prevent the defining insn from being deleted.  */
	  reg_equiv_init (regno) = NULL;
	  if (!for_costs)
	    alter_reg (regno, -1, true);
	}
      return x;

    /* You might think handling MINUS in a manner similar to PLUS is a
       good idea.  It is not.  It has been tried multiple times and every
       time the change has had to have been reverted.

       Other parts of reload know a PLUS is special (gen_reload for example)
       and require special code to handle code a reloaded PLUS operand.

       Also consider backends where the flags register is clobbered by a
       MINUS, but we can emit a PLUS that does not clobber flags (IA-32,
       lea instruction comes to mind).  If we try to reload a MINUS, we
       may kill the flags register that was holding a useful value.

       So, please before trying to handle MINUS, consider reload as a
       whole instead of this little section as well as the backend issues.  */
    case PLUS:
      /* If this is the sum of an eliminable register and a constant, rework
	 the sum.  */
      if (REG_P (XEXP (x, 0))
	  && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
	  && CONSTANT_P (XEXP (x, 1)))
	{
	  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
	       ep++)
	    if (ep->from_rtx == XEXP (x, 0) && ep->can_eliminate)
	      {
		/* 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
		   to do so at other times because that would change the
		   structure of the insn in a way that reload can't handle.
		   We special-case the commonest situation in
		   eliminate_regs_in_insn, so just replace a PLUS with a
		   PLUS here, unless inside a MEM.  */
		if (mem_mode != 0
		    && CONST_INT_P (XEXP (x, 1))
		    && known_eq (INTVAL (XEXP (x, 1)), -ep->previous_offset))
		  return ep->to_rtx;
		else
		  return gen_rtx_PLUS (Pmode, ep->to_rtx,
				       plus_constant (Pmode, XEXP (x, 1),
						      ep->previous_offset));
	      }

	  /* If the register is not eliminable, we are done since the other
	     operand is a constant.  */
	  return x;
	}

      /* If this is part of an address, we want to bring any constant to the
	 outermost PLUS.  We will do this by doing register replacement in
	 our operands and seeing if a constant shows up in one of them.

	 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_1 (XEXP (x, 0), mem_mode, insn, true,
				     for_costs);
	rtx new1 = eliminate_regs_1 (XEXP (x, 1), mem_mode, insn, true,
				     for_costs);

	if (reg_renumber && (new0 != XEXP (x, 0) || new1 != XEXP (x, 1)))
	  {
	    /* If one side is a PLUS and the other side is a pseudo that
	       didn't get a hard register but has a reg_equiv_constant,
	       we must replace the constant here since it may no longer
	       be in the position of any operand.  */
	    if (GET_CODE (new0) == PLUS && REG_P (new1)
		&& REGNO (new1) >= FIRST_PSEUDO_REGISTER
		&& reg_renumber[REGNO (new1)] < 0
		&& reg_equivs
		&& reg_equiv_constant (REGNO (new1)) != 0)
	      new1 = reg_equiv_constant (REGNO (new1));
	    else if (GET_CODE (new1) == PLUS && REG_P (new0)
		     && REGNO (new0) >= FIRST_PSEUDO_REGISTER
		     && reg_renumber[REGNO (new0)] < 0
		     && reg_equiv_constant (REGNO (new0)) != 0)
	      new0 = reg_equiv_constant (REGNO (new0));

	    new_rtx = form_sum (GET_MODE (x), new0, new1);

	    /* As above, if we are not inside a MEM we do not want to
	       turn a PLUS into something else.  We might try to do so here
	       for an addition of 0 if we aren't optimizing.  */
	    if (! mem_mode && GET_CODE (new_rtx) != PLUS)
	      return gen_rtx_PLUS (GET_MODE (x), new_rtx, const0_rtx);
	    else
	      return new_rtx;
	  }
      }
      return x;

    case MULT:
      /* If this is the product of an eliminable register and a
	 constant, apply the distribute law and move the constant out
	 so that we have (plus (mult ..) ..).  This is needed in order
	 to keep load-address insns valid.   This case is pathological.
	 We ignore the possibility of overflow here.  */
      if (REG_P (XEXP (x, 0))
	  && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
	  && CONST_INT_P (XEXP (x, 1)))
	for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
	     ep++)
	  if (ep->from_rtx == XEXP (x, 0) && ep->can_eliminate)
	    {
	      if (! mem_mode
		  /* Refs inside notes or in DEBUG_INSNs don't count for
		     this purpose.  */
		  && ! (insn != 0 && (GET_CODE (insn) == EXPR_LIST
				      || GET_CODE (insn) == INSN_LIST
				      || DEBUG_INSN_P (insn))))
		ep->ref_outside_mem = 1;

	      return
		plus_constant (Pmode,
			       gen_rtx_MULT (Pmode, ep->to_rtx, XEXP (x, 1)),
			       ep->previous_offset * INTVAL (XEXP (x, 1)));
	    }

      /* fall through */

    case CALL:
    case COMPARE:
    /* See comments before PLUS about handling MINUS.  */
    case MINUS:
    case DIV:      case UDIV:
    case MOD:      case UMOD:
    case AND:      case IOR:      case XOR:
    case ROTATERT: case ROTATE:
    case ASHIFTRT: case LSHIFTRT: case ASHIFT:
    case NE:       case EQ:
    case GE:       case GT:       case GEU:    case GTU:
    case LE:       case LT:       case LEU:    case LTU:
      {
	rtx new0 = eliminate_regs_1 (XEXP (x, 0), mem_mode, insn, false,
				     for_costs);
	rtx new1 = XEXP (x, 1)
	  ? eliminate_regs_1 (XEXP (x, 1), mem_mode, insn, false,
			      for_costs) : 0;

	if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
	  return gen_rtx_fmt_ee (code, GET_MODE (x), new0, new1);
      }
      return x;

    case EXPR_LIST:
      /* If we have something in XEXP (x, 0), the usual case, eliminate it.  */
      if (XEXP (x, 0))
	{
	  new_rtx = eliminate_regs_1 (XEXP (x, 0), mem_mode, insn, true,
				      for_costs);
	  if (new_rtx != XEXP (x, 0))
	    {
	      /* If this is a REG_DEAD note, it is not valid anymore.
		 Using the eliminated version could result in creating a
		 REG_DEAD note for the stack or frame pointer.  */
	      if (REG_NOTE_KIND (x) == REG_DEAD)
		return (XEXP (x, 1)
			? eliminate_regs_1 (XEXP (x, 1), mem_mode, insn, true,
					    for_costs)
			: NULL_RTX);

	      x = alloc_reg_note (REG_NOTE_KIND (x), new_rtx, XEXP (x, 1));
	    }
	}

      /* fall through */

    case INSN_LIST:
    case INT_LIST:
      /* Now do eliminations in the rest of the chain.  If this was
	 an EXPR_LIST, this might result in allocating more memory than is
	 strictly needed, but it simplifies the code.  */
      if (XEXP (x, 1))
	{
	  new_rtx = eliminate_regs_1 (XEXP (x, 1), mem_mode, insn, true,
				      for_costs);
	  if (new_rtx != XEXP (x, 1))
	    return
	      gen_rtx_fmt_ee (GET_CODE (x), GET_MODE (x), XEXP (x, 0), new_rtx);
	}
      return x;

    case PRE_INC:
    case POST_INC:
    case PRE_DEC:
    case POST_DEC:
      /* We do not support elimination of a register that is modified.
	 elimination_effects has already make sure that this does not
	 happen.  */
      return x;

    case PRE_MODIFY:
    case POST_MODIFY:
      /* We do not support elimination of a register that is modified.
	 elimination_effects has already make sure that this does not
	 happen.  The only remaining case we need to consider here is
	 that the increment value may be an eliminable register.  */
      if (GET_CODE (XEXP (x, 1)) == PLUS
	  && XEXP (XEXP (x, 1), 0) == XEXP (x, 0))
	{
	  rtx new_rtx = eliminate_regs_1 (XEXP (XEXP (x, 1), 1), mem_mode,
					  insn, true, for_costs);

	  if (new_rtx != XEXP (XEXP (x, 1), 1))
	    return gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (x, 0),
				   gen_rtx_PLUS (GET_MODE (x),
						 XEXP (x, 0), new_rtx));
	}
      return x;

    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:
    case CLZ:
    case CTZ:
    case POPCOUNT:
    case PARITY:
    case BSWAP:
      new_rtx = eliminate_regs_1 (XEXP (x, 0), mem_mode, insn, false,
				  for_costs);
      if (new_rtx != XEXP (x, 0))
	return gen_rtx_fmt_e (code, GET_MODE (x), new_rtx);
      return x;

    case SUBREG:
      /* Similar to above processing, but preserve SUBREG_BYTE.
	 Convert (subreg (mem)) to (mem) if not paradoxical.
	 Also, if we have a non-paradoxical (subreg (pseudo)) and the
	 pseudo didn't get a hard reg, we must replace this with the
	 eliminated version of the memory location because push_reload
	 may do the replacement in certain circumstances.  */
      if (REG_P (SUBREG_REG (x))
	  && !paradoxical_subreg_p (x)
	  && reg_equivs
	  && reg_equiv_memory_loc (REGNO (SUBREG_REG (x))) != 0)
	{
	  new_rtx = SUBREG_REG (x);
	}
      else
	new_rtx = eliminate_regs_1 (SUBREG_REG (x), mem_mode, insn, false, for_costs);

      if (new_rtx != SUBREG_REG (x))
	{
	  poly_int64 x_size = GET_MODE_SIZE (GET_MODE (x));
	  poly_int64 new_size = GET_MODE_SIZE (GET_MODE (new_rtx));

	  if (MEM_P (new_rtx)
	      && ((partial_subreg_p (GET_MODE (x), GET_MODE (new_rtx))
		   /* On RISC machines, combine can create rtl of the form
		      (set (subreg:m1 (reg:m2 R) 0) ...)
		      where m1 < m2, and expects something interesting to
		      happen to the entire word.  Moreover, it will use the
		      (reg:m2 R) later, expecting all bits to be preserved.
		      So if the number of words is the same, preserve the
		      subreg so that push_reload can see it.  */
		   && !(WORD_REGISTER_OPERATIONS
			&& known_equal_after_align_down (x_size - 1,
							 new_size - 1,
							 UNITS_PER_WORD)))
		  || known_eq (x_size, new_size))
	      )
	    return adjust_address_nv (new_rtx, GET_MODE (x), SUBREG_BYTE (x));
	  else if (insn && GET_CODE (insn) == DEBUG_INSN)
	    return gen_rtx_raw_SUBREG (GET_MODE (x), new_rtx, SUBREG_BYTE (x));
	  else
	    return gen_rtx_SUBREG (GET_MODE (x), new_rtx, SUBREG_BYTE (x));
	}

      return x;

    case MEM:
      /* Our only special processing is to pass the mode of the MEM to our
	 recursive call and copy the flags.  While we are here, handle this
	 case more efficiently.  */

      new_rtx = eliminate_regs_1 (XEXP (x, 0), GET_MODE (x), insn, true,
				  for_costs);
      if (for_costs
	  && memory_address_p (GET_MODE (x), XEXP (x, 0))
	  && !memory_address_p (GET_MODE (x), new_rtx))
	note_reg_elim_costly (XEXP (x, 0), insn);

      return replace_equiv_address_nv (x, new_rtx);

    case USE:
      /* Handle insn_list USE that a call to a pure function may generate.  */
      new_rtx = eliminate_regs_1 (XEXP (x, 0), VOIDmode, insn, false,
				  for_costs);
      if (new_rtx != XEXP (x, 0))
	return gen_rtx_USE (GET_MODE (x), new_rtx);
      return x;

    case CLOBBER:
    case CLOBBER_HIGH:
    case ASM_OPERANDS:
      gcc_assert (insn && DEBUG_INSN_P (insn));
      break;

    case SET:
      gcc_unreachable ();

    default:
      break;
    }

  /* Process each of our operands recursively.  If any have changed, make a
     copy of the rtx.  */
  fmt = GET_RTX_FORMAT (code);
  for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
    {
      if (*fmt == 'e')
	{
	  new_rtx = eliminate_regs_1 (XEXP (x, i), mem_mode, insn, false,
				      for_costs);
	  if (new_rtx != XEXP (x, i) && ! copied)
	    {
	      x = shallow_copy_rtx (x);
	      copied = 1;
	    }
	  XEXP (x, i) = new_rtx;
	}
      else if (*fmt == 'E')
	{
	  int copied_vec = 0;
	  for (j = 0; j < XVECLEN (x, i); j++)
	    {
	      new_rtx = eliminate_regs_1 (XVECEXP (x, i, j), mem_mode, insn, false,
					  for_costs);
	      if (new_rtx != XVECEXP (x, i, j) && ! copied_vec)
		{
		  rtvec new_v = gen_rtvec_v (XVECLEN (x, i),
					     XVEC (x, i)->elem);
		  if (! copied)
		    {
		      x = shallow_copy_rtx (x);
		      copied = 1;
		    }
		  XVEC (x, i) = new_v;
		  copied_vec = 1;
		}
	      XVECEXP (x, i, j) = new_rtx;
	    }
	}
    }

  return x;
}

rtx
eliminate_regs (rtx x, machine_mode mem_mode, rtx insn)
{
  if (reg_eliminate == NULL)
    {
      gcc_assert (targetm.no_register_allocation);
      return x;
    }
  return eliminate_regs_1 (x, mem_mode, insn, false, false);
}

/* 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.  */

static void
elimination_effects (rtx x, machine_mode mem_mode)
{
  enum rtx_code code = GET_CODE (x);
  struct elim_table *ep;
  int regno;
  int i, j;
  const char *fmt;

  switch (code)
    {
    CASE_CONST_ANY:
    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 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_equivs
	       && reg_equiv_constant (regno)
	       && ! function_invariant_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:
    case POST_MODIFY:
    case PRE_MODIFY:
      /* If we modify the source of an elimination rule, disable it.  */
      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
	if (ep->from_rtx == XEXP (x, 0))
	  ep->can_eliminate = 0;

      /* If we modify the target of an elimination rule by adding a constant,
	 update its offset.  If we modify the target in any other way, we'll
	 have to disable the rule as well.  */
      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
	if (ep->to_rtx == XEXP (x, 0))
	  {
	    poly_int64 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 if (code == PRE_INC || code == POST_INC)
	      ep->offset -= size;
	    else if (code == PRE_MODIFY || code == POST_MODIFY)
	      {
		if (GET_CODE (XEXP (x, 1)) == PLUS
		    && XEXP (x, 0) == XEXP (XEXP (x, 1), 0)
		    && CONST_INT_P (XEXP (XEXP (x, 1), 1)))
		  ep->offset -= INTVAL (XEXP (XEXP (x, 1), 1));
		else
		  ep->can_eliminate = 0;
	      }
	  }

      /* These two aren't unary operators.  */
      if (code == POST_MODIFY || code == PRE_MODIFY)
	break;

      /* Fall through to generic unary operation case.  */
      gcc_fallthrough ();
    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:
    case CLZ:
    case CTZ:
    case POPCOUNT:
    case PARITY:
    case BSWAP:
      elimination_effects (XEXP (x, 0), mem_mode);
      return;

    case SUBREG:
      if (REG_P (SUBREG_REG (x))
	  && !paradoxical_subreg_p (x)
	  && reg_equivs
	  && 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 CLOBBER_HIGH:
      /* CLOBBER_HIGH is only supported for LRA.  */
      return;

    case SET:
      /* Check for setting a register that we know about.  */
      if (REG_P (SET_DEST (x)))
	{
	  /* 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)
		    && CONST_INT_P (XEXP (src, 1)))
		  ep->offset -= INTVAL (XEXP (src, 1));
		else
		  ep->can_eliminate = 0;
	      }
	}

      elimination_effects (SET_DEST (x), VOIDmode);
      elimination_effects (SET_SRC (x), VOIDmode);
      return;

    case MEM:
      /* 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 (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 = 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));
	}
    }
}

/* 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
   is returned.  Otherwise, 1 is returned.  */

static int
eliminate_regs_in_insn (rtx_insn *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;
  rtx substed_operand[MAX_RECOG_OPERANDS];
  rtx orig_operand[MAX_RECOG_OPERANDS];
  struct elim_table *ep;
  rtx plus_src, plus_cst_src;

  if (! insn_is_asm && icode < 0)
    {
      gcc_assert (DEBUG_INSN_P (insn)
		  || GET_CODE (PATTERN (insn)) == USE
		  || GET_CODE (PATTERN (insn)) == CLOBBER
		  || GET_CODE (PATTERN (insn)) == ASM_INPUT);
      if (DEBUG_BIND_INSN_P (insn))
	INSN_VAR_LOCATION_LOC (insn)
	  = eliminate_regs (INSN_VAR_LOCATION_LOC (insn), VOIDmode, insn);
      return 0;
    }

  if (old_set != 0 && REG_P (SET_DEST (old_set))
      && REGNO (SET_DEST (old_set)) < FIRST_PSEUDO_REGISTER)
    {
      /* Check for setting an eliminable register.  */
      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
	if (ep->from_rtx == SET_DEST (old_set) && ep->can_eliminate)
	  {
	    /* If this is setting the frame pointer register to the
	       hardware frame pointer register and this is an elimination
	       that will be done (tested above), this insn is really
	       adjusting the frame pointer downward to compensate for
	       the adjustment done before a nonlocal goto.  */
	    if (!HARD_FRAME_POINTER_IS_FRAME_POINTER
		&& ep->from == FRAME_POINTER_REGNUM
		&& ep->to == HARD_FRAME_POINTER_REGNUM)
	      {
		rtx base = SET_SRC (old_set);
		rtx_insn *base_insn = insn;
		HOST_WIDE_INT offset = 0;

		while (base != ep->to_rtx)
		  {
		    rtx_insn *prev_insn;
		    rtx prev_set;

		    if (GET_CODE (base) == PLUS
		        && CONST_INT_P (XEXP (base, 1)))
		      {
		        offset += INTVAL (XEXP (base, 1));
		        base = XEXP (base, 0);
		      }
		    else if ((prev_insn = prev_nonnote_insn (base_insn)) != 0
			     && (prev_set = single_set (prev_insn)) != 0
			     && rtx_equal_p (SET_DEST (prev_set), base))
		      {
		        base = SET_SRC (prev_set);
		        base_insn = prev_insn;
		      }
		    else
		      break;
		  }

		if (base == ep->to_rtx)
		  {
		    rtx src = plus_constant (Pmode, ep->to_rtx,
					     offset - ep->offset);

		    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;
		    old_set = single_set (insn);

		    /* First see if this insn remains valid when we
		       make the change.  If not, keep the INSN_CODE
		       the same and let reload fit it up.  */
		    validate_change (insn, &SET_SRC (old_set), src, 1);
		    validate_change (insn, &SET_DEST (old_set),
				     ep->to_rtx, 1);
		    if (! apply_change_group ())
		      {
			SET_SRC (old_set) = src;
			SET_DEST (old_set) = ep->to_rtx;
		      }

		    val = 1;
		    goto done;
		  }
	      }

	    /* In this case this insn isn't serving a useful purpose.  We
	       will delete it in reload_as_needed once we know that this
	       elimination is, in fact, being done.

	       If REPLACE isn't set, we can't delete this insn, but needn't
	       process it since it won't be used unless something changes.  */
	    if (replace)
	      {
		delete_dead_insn (insn);
		return 1;
	      }
	    val = 1;
	    goto done;
	  }
    }

  /* We allow one special case which happens to work on all machines we
     currently support: a single set with the source or a REG_EQUAL
     note being a PLUS of an eliminable register and a constant.  */
  plus_src = plus_cst_src = 0;
  if (old_set && REG_P (SET_DEST (old_set)))
    {
      if (GET_CODE (SET_SRC (old_set)) == PLUS)
	plus_src = SET_SRC (old_set);
      /* First see if the source is of the form (plus (...) CST).  */
      if (plus_src
	  && CONST_INT_P (XEXP (plus_src, 1)))
	plus_cst_src = plus_src;
      else if (REG_P (SET_SRC (old_set))
	       || plus_src)
	{
	  /* Otherwise, see if we have a REG_EQUAL note of the form
	     (plus (...) CST).  */
	  rtx links;
	  for (links = REG_NOTES (insn); links; links = XEXP (links, 1))
	    {
	      if ((REG_NOTE_KIND (links) == REG_EQUAL
		   || REG_NOTE_KIND (links) == REG_EQUIV)
		  && GET_CODE (XEXP (links, 0)) == PLUS
		  && CONST_INT_P (XEXP (XEXP (links, 0), 1)))
		{
		  plus_cst_src = XEXP (links, 0);
		  break;
		}
	    }
	}

      /* Check that the first operand of the PLUS is a hard reg or
	 the lowpart subreg of one.  */
      if (plus_cst_src)
	{
	  rtx reg = XEXP (plus_cst_src, 0);
	  if (GET_CODE (reg) == SUBREG && subreg_lowpart_p (reg))
	    reg = SUBREG_REG (reg);

	  if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
	    plus_cst_src = 0;
	}
    }
  if (plus_cst_src)
    {
      rtx reg = XEXP (plus_cst_src, 0);
      poly_int64 offset = INTVAL (XEXP (plus_cst_src, 1));

      if (GET_CODE (reg) == SUBREG)
	reg = SUBREG_REG (reg);

      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
	if (ep->from_rtx == reg && ep->can_eliminate)
	  {
	    rtx to_rtx = ep->to_rtx;
	    offset += ep->offset;
	    offset = trunc_int_for_mode (offset, GET_MODE (plus_cst_src));

	    if (GET_CODE (XEXP (plus_cst_src, 0)) == SUBREG)
	      to_rtx = gen_lowpart (GET_MODE (XEXP (plus_cst_src, 0)),
				    to_rtx);
	    /* If we have a nonzero offset, and the source is already
	       a simple REG, the following transformation would
	       increase the cost of the insn by replacing a simple REG
	       with (plus (reg sp) CST).  So try only when we already
	       had a PLUS before.  */
	    if (known_eq (offset, 0) || plus_src)
	      {
		rtx new_src = plus_constant (GET_MODE (to_rtx),
					     to_rtx, offset);

		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;
		old_set = single_set (insn);

		/* First see if this insn remains valid when we make the
		   change.  If not, try to replace the whole pattern with
		   a simple set (this may help if the original insn was a
		   PARALLEL that was only recognized as single_set due to
		   REG_UNUSED notes).  If this isn't valid either, keep
		   the INSN_CODE the same and let reload fix it up.  */
		if (!validate_change (insn, &SET_SRC (old_set), new_src, 0))
		  {
		    rtx new_pat = gen_rtx_SET (SET_DEST (old_set), new_src);

		    if (!validate_change (insn, &PATTERN (insn), new_pat, 0))
		      SET_SRC (old_set) = new_src;
		  }
	      }
	    else
	      break;

	    val = 1;
	    /* This can't have an effect on elimination offsets, so skip right
	       to the end.  */
	    goto done;
	  }
    }

  /* Determine the effects of this insn on elimination offsets.  */
  elimination_effects (old_body, VOIDmode);

  /* Eliminate all eliminable registers occurring in operands that
     can be handled by reload.  */
  extract_insn (insn);
  for (i = 0; i < recog_data.n_operands; i++)
    {
      orig_operand[i] = recog_data.operand[i];
      substed_operand[i] = recog_data.operand[i];

      /* For an asm statement, every operand is eliminable.  */
      if (insn_is_asm || insn_data[icode].operand[i].eliminable)
	{
	  bool is_set_src, in_plus;

	  /* Check for setting a register that we know about.  */
	  if (recog_data.operand_type[i] != OP_IN
	      && REG_P (orig_operand[i]))
	    {
	      /* 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 = 0;
	    }

	  /* Companion to the above plus substitution, we can allow
	     invariants as the source of a plain move.  */
	  is_set_src = false;
	  if (old_set
	      && recog_data.operand_loc[i] == &SET_SRC (old_set))
	    is_set_src = true;
	  in_plus = false;
	  if (plus_src
	      && (recog_data.operand_loc[i] == &XEXP (plus_src, 0)
		  || recog_data.operand_loc[i] == &XEXP (plus_src, 1)))
	    in_plus = true;

	  substed_operand[i]
	    = eliminate_regs_1 (recog_data.operand[i], VOIDmode,
			        replace ? insn : NULL_RTX,
				is_set_src || in_plus, false);
	  if (substed_operand[i] != orig_operand[i])
	    val = 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
	      && REG_P (orig_operand[i])
	      && MEM_P (substed_operand[i])
	      && replace)
	    emit_insn_after (gen_clobber (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.
     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.  */

  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.  */
      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.  */
      /* ??? Why this huge if statement - why don't we just rerecognize the
	 thing always?  */
      if (! insn_is_asm
	  && old_set != 0
	  && ((REG_P (SET_SRC (old_set))
	       && (GET_CODE (new_body) != SET
		   || !REG_P (SET_SRC (new_body))))
	      /* If this was a load from or store to memory, compare
		 the MEM in recog_data.operand to the one in the insn.
		 If they are not equal, then rerecognize the insn.  */
	      || (old_set != 0
		  && ((MEM_P (SET_SRC (old_set))
		       && SET_SRC (old_set) != recog_data.operand[1])
		      || (MEM_P (SET_DEST (old_set))
			  && SET_DEST (old_set) != recog_data.operand[0])))
	      /* If this was an add insn before, rerecognize.  */
	      || GET_CODE (SET_SRC (old_set)) == PLUS))
	{
	  int new_icode = recog (PATTERN (insn), insn, 0);
	  if (new_icode >= 0)
	    INSN_CODE (insn) = new_icode;
	}
    }

  /* 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++)
	/* Restoring a top-level match_parallel would clobber the new_body
	   we installed in the insn.  */
	if (recog_data.operand_loc[i] != &PATTERN (insn))
	  *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]];
    }

  /* 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 cases where register elimination cannot be done,
     namely, if a register would be both changed and referenced outside a MEM
     in the resulting insn since such an insn is often undefined and, even if
     not, we cannot know what meaning will be given to it.  Note that it is
     valid to have a register used in an address in an insn that changes it
     (presumably with a pre- or post-increment or decrement).

     If anything changes, return nonzero.  */

  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
    {
      if (maybe_ne (ep->previous_offset, ep->offset) && ep->ref_outside_mem)
	ep->can_eliminate = 0;

      ep->ref_outside_mem = 0;

      if (maybe_ne (ep->previous_offset, ep->offset))
	val = 1;
    }

 done:
  /* If we changed something, perform elimination in REG_NOTES.  This is
     needed even when REPLACE is zero because a REG_DEAD note might refer
     to a register that we eliminate and could cause a different number
     of spill registers to be needed in the final reload pass than in
     the pre-passes.  */
  if (val && REG_NOTES (insn) != 0)
    REG_NOTES (insn)
      = eliminate_regs_1 (REG_NOTES (insn), VOIDmode, REG_NOTES (insn), true,
			  false);

  return val;
}

/* Like eliminate_regs_in_insn, but only estimate costs for the use of the
   register allocator.  INSN is the instruction we need to examine, we perform
   eliminations in its operands and record cases where eliminating a reg with
   an invariant equivalence would add extra cost.  */

#pragma GCC diagnostic push
#pragma GCC diagnostic warning "-Wmaybe-uninitialized"
static void
elimination_costs_in_insn (rtx_insn *insn)
{
  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);
  int i;
  rtx orig_operand[MAX_RECOG_OPERANDS];
  rtx orig_dup[MAX_RECOG_OPERANDS];
  struct elim_table *ep;
  rtx plus_src, plus_cst_src;
  bool sets_reg_p;

  if (! insn_is_asm && icode < 0)
    {
      gcc_assert (DEBUG_INSN_P (insn)
		  || GET_CODE (PATTERN (insn)) == USE
		  || GET_CODE (PATTERN (insn)) == CLOBBER
		  || GET_CODE (PATTERN (insn)) == ASM_INPUT);
      return;
    }

  if (old_set != 0 && REG_P (SET_DEST (old_set))
      && REGNO (SET_DEST (old_set)) < FIRST_PSEUDO_REGISTER)
    {
      /* Check for setting an eliminable register.  */
      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
	if (ep->from_rtx == SET_DEST (old_set) && ep->can_eliminate)
	  return;
    }

  /* We allow one special case which happens to work on all machines we
     currently support: a single set with the source or a REG_EQUAL
     note being a PLUS of an eliminable register and a constant.  */
  plus_src = plus_cst_src = 0;
  sets_reg_p = false;
  if (old_set && REG_P (SET_DEST (old_set)))
    {
      sets_reg_p = true;
      if (GET_CODE (SET_SRC (old_set)) == PLUS)
	plus_src = SET_SRC (old_set);
      /* First see if the source is of the form (plus (...) CST).  */
      if (plus_src
	  && CONST_INT_P (XEXP (plus_src, 1)))
	plus_cst_src = plus_src;
      else if (REG_P (SET_SRC (old_set))
	       || plus_src)
	{
	  /* Otherwise, see if we have a REG_EQUAL note of the form
	     (plus (...) CST).  */
	  rtx links;
	  for (links = REG_NOTES (insn); links; links = XEXP (links, 1))
	    {
	      if ((REG_NOTE_KIND (links) == REG_EQUAL
		   || REG_NOTE_KIND (links) == REG_EQUIV)
		  && GET_CODE (XEXP (links, 0)) == PLUS
		  && CONST_INT_P (XEXP (XEXP (links, 0), 1)))
		{
		  plus_cst_src = XEXP (links, 0);
		  break;
		}
	    }
	}
    }

  /* Determine the effects of this insn on elimination offsets.  */
  elimination_effects (old_body, VOIDmode);

  /* Eliminate all eliminable registers occurring in operands that
     can be handled by reload.  */
  extract_insn (insn);
  int n_dups = recog_data.n_dups;
  for (i = 0; i < n_dups; i++)
    orig_dup[i] = *recog_data.dup_loc[i];

  int n_operands = recog_data.n_operands;
  for (i = 0; i < n_operands; i++)
    {
      orig_operand[i] = recog_data.operand[i];

      /* For an asm statement, every operand is eliminable.  */
      if (insn_is_asm || insn_data[icode].operand[i].eliminable)
	{
	  bool is_set_src, in_plus;

	  /* Check for setting a register that we know about.  */
	  if (recog_data.operand_type[i] != OP_IN
	      && REG_P (orig_operand[i]))
	    {
	      /* 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 = 0;
	    }

	  /* Companion to the above plus substitution, we can allow
	     invariants as the source of a plain move.  */
	  is_set_src = false;
	  if (old_set && recog_data.operand_loc[i] == &SET_SRC (old_set))
	    is_set_src = true;
	  if (is_set_src && !sets_reg_p)
	    note_reg_elim_costly (SET_SRC (old_set), insn);
	  in_plus = false;
	  if (plus_src && sets_reg_p
	      && (recog_data.operand_loc[i] == &XEXP (plus_src, 0)
		  || recog_data.operand_loc[i] == &XEXP (plus_src, 1)))
	    in_plus = true;

	  eliminate_regs_1 (recog_data.operand[i], VOIDmode,
			    NULL_RTX,
			    is_set_src || in_plus, true);
	  /* Terminate the search in check_eliminable_occurrences at
	     this point.  */
	  *recog_data.operand_loc[i] = 0;
	}
    }

  for (i = 0; i < 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);

  /* Restore the old body.  */
  for (i = 0; i < n_operands; i++)
    *recog_data.operand_loc[i] = orig_operand[i];
  for (i = 0; i < n_dups; i++)
    *recog_data.dup_loc[i] = orig_dup[i];

  /* 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.  */

  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
    {
      if (maybe_ne (ep->previous_offset, ep->offset) && ep->ref_outside_mem)
	ep->can_eliminate = 0;

      ep->ref_outside_mem = 0;
    }

  return;
}
#pragma GCC diagnostic pop

/* Loop through all elimination pairs.
   Recalculate the number not at initial offset.

   Compute the maximum offset (minimum offset if the stack does not
   grow downward) for each elimination pair.  */

static void
update_eliminable_offsets (void)
{
  struct elim_table *ep;

  num_not_at_initial_offset = 0;
  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
    {
      ep->previous_offset = ep->offset;
      if (ep->can_eliminate && maybe_ne (ep->offset, ep->initial_offset))
	num_not_at_initial_offset++;
    }
}

/* Given X, a SET or CLOBBER of DEST, if DEST is the target of a register
   replacement we currently believe is valid, mark it as not eliminable if X
   modifies DEST in any way other than by adding a constant integer to it.

   If DEST is the frame pointer, we do nothing because we assume that
   all assignments to the hard frame pointer are nonlocal 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 with either the
   frame or stack pointer.  Assignments to the hard frame pointer must not
   prevent this elimination.

   Called via note_stores from reload before starting its passes to scan
   the insns of the function.  */

static void
mark_not_eliminable (rtx dest, const_rtx x, void *data ATTRIBUTE_UNUSED)
{
  unsigned int i;

  /* A SUBREG of a hard register here is just changing its mode.  We should
     not see a SUBREG of an eliminable hard register, but check just in
     case.  */
  if (GET_CODE (dest) == SUBREG)
    dest = SUBREG_REG (dest);

  if (dest == hard_frame_pointer_rtx)
    return;

  /* CLOBBER_HIGH is only supported for LRA.  */
  gcc_assert (GET_CODE (x) != CLOBBER_HIGH);

  for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
    if (reg_eliminate[i].can_eliminate && dest == reg_eliminate[i].to_rtx
	&& (GET_CODE (x) != SET
	    || GET_CODE (SET_SRC (x)) != PLUS
	    || XEXP (SET_SRC (x), 0) != dest
	    || !CONST_INT_P (XEXP (SET_SRC (x), 1))))
      {
	reg_eliminate[i].can_eliminate_previous
	  = reg_eliminate[i].can_eliminate = 0;
	num_eliminable--;
      }
}

/* Verify that the initial elimination offsets did not change since the
   last call to set_initial_elim_offsets.  This is used to catch cases
   where something illegal happened during reload_as_needed that could
   cause incorrect code to be generated if we did not check for it.  */

static bool
verify_initial_elim_offsets (void)
{
  poly_int64 t;
  struct elim_table *ep;

  if (!num_eliminable)
    return true;

  targetm.compute_frame_layout ();
  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
    {
      INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, t);
      if (maybe_ne (t, ep->initial_offset))
	return false;
    }

  return true;
}

/* Reset all offsets on eliminable registers to their initial values.  */

static void
set_initial_elim_offsets (void)
{
  struct elim_table *ep = reg_eliminate;

  targetm.compute_frame_layout ();
  for (; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
    {
      INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, ep->initial_offset);
      ep->previous_offset = ep->offset = ep->initial_offset;
    }

  num_not_at_initial_offset = 0;
}

/* Subroutine of set_initial_label_offsets called via for_each_eh_label.  */

static void
set_initial_eh_label_offset (rtx label)
{
  set_label_offsets (label, NULL, 1);
}

/* Initialize the known label offsets.
   Set a known offset for each forced label to be at the initial offset
   of each elimination.  We do this because we assume that all
   computed jumps occur from a location where each elimination is
   at its initial offset.
   For all other labels, show that we don't know the offsets.  */

static void
set_initial_label_offsets (void)
{
  memset (offsets_known_at, 0, num_labels);

  unsigned int i;
  rtx_insn *insn;
  FOR_EACH_VEC_SAFE_ELT (forced_labels, i, insn)
    set_label_offsets (insn, NULL, 1);

  for (rtx_insn_list *x = nonlocal_goto_handler_labels; x; x = x->next ())
    if (x->insn ())
      set_label_offsets (x->insn (), NULL, 1);

  for_each_eh_label (set_initial_eh_label_offset);
}

/* Set all elimination offsets to the known values for the code label given
   by INSN.  */

static void
set_offsets_for_label (rtx_insn *insn)
{
  unsigned int i;
  int label_nr = CODE_LABEL_NUMBER (insn);
  struct elim_table *ep;

  num_not_at_initial_offset = 0;
  for (i = 0, ep = reg_eliminate; i < NUM_ELIMINABLE_REGS; ep++, i++)
    {
      ep->offset = ep->previous_offset
		 = offsets_at[label_nr - first_label_num][i];
      if (ep->can_eliminate && maybe_ne (ep->offset, ep->initial_offset))
	num_not_at_initial_offset++;
    }
}

/* See if anything that happened changes which eliminations are valid.
   For example, on the SPARC, whether or not the frame pointer can
   be eliminated can depend on what registers have been used.  We need
   not check some conditions again (such as flag_omit_frame_pointer)
   since they can't have changed.  */

static void
update_eliminables (HARD_REG_SET *pset)
{
  int previous_frame_pointer_needed = frame_pointer_needed;
  struct elim_table *ep;

  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
    if ((ep->from == HARD_FRAME_POINTER_REGNUM
         && targetm.frame_pointer_required ())
	|| ! targetm.can_eliminate (ep->from, ep->to)
	)
      ep->can_eliminate = 0;

  /* Look for the case where we have discovered that we can't replace
     register A with register B and that means that we will now be
     trying to replace register A with register C.  This means we can
     no longer replace register C with register B and we need to disable
     such an elimination, if it exists.  This occurs often with A == ap,
     B == sp, and C == fp.  */

  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
    {
      struct elim_table *op;
      int new_to = -1;

      if (! ep->can_eliminate && ep->can_eliminate_previous)
	{
	  /* Find the current elimination for ep->from, if there is a
	     new one.  */
	  for (op = reg_eliminate;
	       op < &reg_eliminate[NUM_ELIMINABLE_REGS]; op++)
	    if (op->from == ep->from && op->can_eliminate)
	      {
		new_to = op->to;
		break;
	      }

	  /* See if there is an elimination of NEW_TO -> EP->TO.  If so,
	     disable it.  */
	  for (op = reg_eliminate;
	       op < &reg_eliminate[NUM_ELIMINABLE_REGS]; op++)
	    if (op->from == new_to && op->to == ep->to)
	      op->can_eliminate = 0;
	}
    }

  /* See if any registers that we thought we could eliminate the previous
     time are no longer eliminable.  If so, something has changed and we
     must spill the register.  Also, recompute the number of eliminable
     registers and see if the frame pointer is needed; it is if there is
     no elimination of the frame pointer that we can perform.  */

  frame_pointer_needed = 1;
  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
    {
      if (ep->can_eliminate
	  && ep->from == FRAME_POINTER_REGNUM
	  && ep->to != HARD_FRAME_POINTER_REGNUM
	  && (! SUPPORTS_STACK_ALIGNMENT
	      || ! crtl->stack_realign_needed))
	frame_pointer_needed = 0;

      if (! ep->can_eliminate && ep->can_eliminate_previous)
	{
	  ep->can_eliminate_previous = 0;
	  SET_HARD_REG_BIT (*pset, ep->from);
	  num_eliminable--;
	}
    }

  /* If we didn't need a frame pointer last time, but we do now, spill
     the hard frame pointer.  */
  if (frame_pointer_needed && ! previous_frame_pointer_needed)
    SET_HARD_REG_BIT (*pset, HARD_FRAME_POINTER_REGNUM);
}

/* Call update_eliminables an spill any registers we can't eliminate anymore.
   Return true iff a register was spilled.  */

static bool
update_eliminables_and_spill (void)
{
  int i;
  bool did_spill = false;
  HARD_REG_SET to_spill;
  CLEAR_HARD_REG_SET (to_spill);
  update_eliminables (&to_spill);
  AND_COMPL_HARD_REG_SET (used_spill_regs, to_spill);

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (TEST_HARD_REG_BIT (to_spill, i))
      {
	spill_hard_reg (i, 1);
	did_spill = true;

	/* Regardless of the state of spills, if we previously had
	   a register that we thought we could eliminate, but now
	   cannot eliminate, we must run another pass.

	   Consider pseudos which have an entry in reg_equiv_* which
	   reference an eliminable register.  We must make another pass
	   to update reg_equiv_* so that we do not substitute in the
	   old value from when we thought the elimination could be
	   performed.  */
      }
  return did_spill;
}

/* Return true if X is used as the target register of an elimination.  */

bool
elimination_target_reg_p (rtx x)
{
  struct elim_table *ep;

  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
    if (ep->to_rtx == x && ep->can_eliminate)
      return true;

  return false;
}

/* Initialize the table of registers to eliminate.
   Pre-condition: global flag frame_pointer_needed has been set before
   calling this function.  */

static void
init_elim_table (void)
{
  struct elim_table *ep;
  const struct elim_table_1 *ep1;

  if (!reg_eliminate)
    reg_eliminate = XCNEWVEC (struct elim_table, NUM_ELIMINABLE_REGS);

  num_eliminable = 0;

  for (ep = reg_eliminate, ep1 = reg_eliminate_1;
       ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++, ep1++)
    {
      ep->from = ep1->from;
      ep->to = ep1->to;
      ep->can_eliminate = ep->can_eliminate_previous
	= (targetm.can_eliminate (ep->from, ep->to)
	   && ! (ep->to == STACK_POINTER_REGNUM
		 && frame_pointer_needed
		 && (! SUPPORTS_STACK_ALIGNMENT
		     || ! stack_realign_fp)));
    }

  /* Count the number of eliminable registers and build the FROM and TO
     REG rtx's.  Note that code in gen_rtx_REG will cause, e.g.,
     gen_rtx_REG (Pmode, STACK_POINTER_REGNUM) to equal stack_pointer_rtx.
     We depend on this.  */
  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
    {
      num_eliminable += ep->can_eliminate;
      ep->from_rtx = gen_rtx_REG (Pmode, ep->from);
      ep->to_rtx = gen_rtx_REG (Pmode, ep->to);
    }
}

/* Find all the pseudo registers that didn't get hard regs
   but do have known equivalent constants or memory slots.
   These include parameters (known equivalent to parameter slots)
   and cse'd or loop-moved constant memory addresses.

   Record constant equivalents in reg_equiv_constant
   so they will be substituted by find_reloads.
   Record memory equivalents in reg_mem_equiv so they can
   be substituted eventually by altering the REG-rtx's.  */

static void
init_eliminable_invariants (rtx_insn *first, bool do_subregs)
{
  int i;
  rtx_insn *insn;

  grow_reg_equivs ();
  if (do_subregs)
    reg_max_ref_mode = XCNEWVEC (machine_mode, max_regno);
  else
    reg_max_ref_mode = NULL;

  num_eliminable_invariants = 0;

  first_label_num = get_first_label_num ();
  num_labels = max_label_num () - first_label_num;

  /* Allocate the tables used to store offset information at labels.  */
  offsets_known_at = XNEWVEC (char, num_labels);
  offsets_at = (poly_int64_pod (*)[NUM_ELIMINABLE_REGS])
    xmalloc (num_labels * NUM_ELIMINABLE_REGS * sizeof (poly_int64));

/* Look for REG_EQUIV notes; record what each pseudo is equivalent
   to.  If DO_SUBREGS is true, also find all paradoxical subregs and
   find largest such for each pseudo.  FIRST is the head of the insn
   list.  */

  for (insn = first; insn; insn = NEXT_INSN (insn))
    {
      rtx set = single_set (insn);

      /* We may introduce USEs that we want to remove at the end, so
	 we'll mark them with QImode.  Make sure there are no
	 previously-marked insns left by say regmove.  */
      if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
	  && GET_MODE (insn) != VOIDmode)
	PUT_MODE (insn, VOIDmode);

      if (do_subregs && NONDEBUG_INSN_P (insn))
	scan_paradoxical_subregs (PATTERN (insn));

      if (set != 0 && REG_P (SET_DEST (set)))
	{
	  rtx note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
	  rtx x;

	  if (! note)
	    continue;

	  i = REGNO (SET_DEST (set));
	  x = XEXP (note, 0);

	  if (i <= LAST_VIRTUAL_REGISTER)
	    continue;

	  /* If flag_pic and we have constant, verify it's legitimate.  */
	  if (!CONSTANT_P (x)
	      || !flag_pic || LEGITIMATE_PIC_OPERAND_P (x))
	    {
	      /* It can happen that a REG_EQUIV note contains a MEM
		 that is not a legitimate memory operand.  As later
		 stages of reload assume that all addresses found
		 in the reg_equiv_* arrays were originally legitimate,
		 we ignore such REG_EQUIV notes.  */
	      if (memory_operand (x, VOIDmode))
		{
		  /* Always unshare the equivalence, so we can
		     substitute into this insn without touching the
		       equivalence.  */
		  reg_equiv_memory_loc (i) = copy_rtx (x);
		}
	      else if (function_invariant_p (x))
		{
		  machine_mode mode;

		  mode = GET_MODE (SET_DEST (set));
		  if (GET_CODE (x) == PLUS)
		    {
		      /* This is PLUS of frame pointer and a constant,
			 and might be shared.  Unshare it.  */
		      reg_equiv_invariant (i) = copy_rtx (x);
		      num_eliminable_invariants++;
		    }
		  else if (x == frame_pointer_rtx || x == arg_pointer_rtx)
		    {
		      reg_equiv_invariant (i) = x;
		      num_eliminable_invariants++;
		    }
		  else if (targetm.legitimate_constant_p (mode, x))
		    reg_equiv_constant (i) = x;
		  else
		    {
		      reg_equiv_memory_loc (i) = force_const_mem (mode, x);
		      if (! reg_equiv_memory_loc (i))
			reg_equiv_init (i) = NULL;
		    }
		}
	      else
		{
		  reg_equiv_init (i) = NULL;
		  continue;
		}
	    }
	  else
	    reg_equiv_init (i) = NULL;
	}
    }

  if (dump_file)
    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
      if (reg_equiv_init (i))
	{
	  fprintf (dump_file, "init_insns for %u: ", i);
	  print_inline_rtx (dump_file, reg_equiv_init (i), 20);
	  fprintf (dump_file, "\n");
	}
}

/* Indicate that we no longer have known memory locations or constants.
   Free all data involved in tracking these.  */

static void
free_reg_equiv (void)
{
  int i;

  free (offsets_known_at);
  free (offsets_at);
  offsets_at = 0;
  offsets_known_at = 0;

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (reg_equiv_alt_mem_list (i))
      free_EXPR_LIST_list (&reg_equiv_alt_mem_list (i));
  vec_free (reg_equivs);
}

/* Kick all pseudos out of hard register REGNO.

   If CANT_ELIMINATE is nonzero, it means that we are doing this spill
   because we found we can't eliminate some register.  In the case, no pseudos
   are allowed to be in the register, even if they are only in a block that
   doesn't require spill registers, unlike the case when we are spilling this
   hard reg to produce another spill register.

   Return nonzero if any pseudos needed to be kicked out.  */

static void
spill_hard_reg (unsigned int regno, int cant_eliminate)
{
  int i;

  if (cant_eliminate)
    {
      SET_HARD_REG_BIT (bad_spill_regs_global, regno);
      df_set_regs_ever_live (regno, true);
    }

  /* Spill every pseudo reg that was allocated to this reg
     or to something that overlaps this reg.  */

  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
    if (reg_renumber[i] >= 0
	&& (unsigned int) reg_renumber[i] <= regno
	&& end_hard_regno (PSEUDO_REGNO_MODE (i), reg_renumber[i]) > regno)
      SET_REGNO_REG_SET (&spilled_pseudos, i);
}

/* After spill_hard_reg was called and/or find_reload_regs was run for all
   insns that need reloads, this function is used to actually spill pseudo
   registers and try to reallocate them.  It also sets up the spill_regs
   array for use by choose_reload_regs.

   GLOBAL nonzero means we should attempt to reallocate any pseudo registers
   that we displace from hard registers.  */

static int
finish_spills (int global)
{
  struct insn_chain *chain;
  int something_changed = 0;
  unsigned i;
  reg_set_iterator rsi;

  /* Build the spill_regs array for the function.  */
  /* If there are some registers still to eliminate and one of the spill regs
     wasn't ever used before, additional stack space may have to be
     allocated to store this register.  Thus, we may have changed the offset
     between the stack and frame pointers, so mark that something has changed.

     One might think that we need only set VAL to 1 if this is a call-used
     register.  However, the set of registers that must be saved by the
     prologue is not identical to the call-used set.  For example, the
     register used by the call insn for the return PC is a call-used register,
     but must be saved by the prologue.  */

  n_spills = 0;
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (TEST_HARD_REG_BIT (used_spill_regs, i))
      {
	spill_reg_order[i] = n_spills;
	spill_regs[n_spills++] = i;
	if (num_eliminable && ! df_regs_ever_live_p (i))
	  something_changed = 1;
	df_set_regs_ever_live (i, true);
      }
    else
      spill_reg_order[i] = -1;

  EXECUTE_IF_SET_IN_REG_SET (&spilled_pseudos, FIRST_PSEUDO_REGISTER, i, rsi)
    if (! ira_conflicts_p || reg_renumber[i] >= 0)
      {
	/* Record the current hard register the pseudo is allocated to
	   in pseudo_previous_regs so we avoid reallocating it to the
	   same hard reg in a later pass.  */
	gcc_assert (reg_renumber[i] >= 0);

	SET_HARD_REG_BIT (pseudo_previous_regs[i], reg_renumber[i]);
	/* Mark it as no longer having a hard register home.  */
	reg_renumber[i] = -1;
	if (ira_conflicts_p)
	  /* Inform IRA about the change.  */
	  ira_mark_allocation_change (i);
	/* We will need to scan everything again.  */
	something_changed = 1;
      }

  /* Retry global register allocation if possible.  */
  if (global && ira_conflicts_p)
    {
      unsigned int n;

      memset (pseudo_forbidden_regs, 0, max_regno * sizeof (HARD_REG_SET));
      /* For every insn that needs reloads, set the registers used as spill
	 regs in pseudo_forbidden_regs for every pseudo live across the
	 insn.  */
      for (chain = insns_need_reload; chain; chain = chain->next_need_reload)
	{
	  EXECUTE_IF_SET_IN_REG_SET
	    (&chain->live_throughout, FIRST_PSEUDO_REGISTER, i, rsi)
	    {
	      IOR_HARD_REG_SET (pseudo_forbidden_regs[i],
				chain->used_spill_regs);
	    }
	  EXECUTE_IF_SET_IN_REG_SET
	    (&chain->dead_or_set, FIRST_PSEUDO_REGISTER, i, rsi)
	    {
	      IOR_HARD_REG_SET (pseudo_forbidden_regs[i],
				chain->used_spill_regs);
	    }
	}

      /* Retry allocating the pseudos spilled in IRA and the
	 reload.  For each reg, merge the various reg sets that
	 indicate which hard regs can't be used, and call
	 ira_reassign_pseudos.  */
      for (n = 0, i = FIRST_PSEUDO_REGISTER; i < (unsigned) max_regno; i++)
	if (reg_old_renumber[i] != reg_renumber[i])
	  {
	    if (reg_renumber[i] < 0)
	      temp_pseudo_reg_arr[n++] = i;
	    else
	      CLEAR_REGNO_REG_SET (&spilled_pseudos, i);
	  }
      if (ira_reassign_pseudos (temp_pseudo_reg_arr, n,
				bad_spill_regs_global,
				pseudo_forbidden_regs, pseudo_previous_regs,
				&spilled_pseudos))
	something_changed = 1;
    }
  /* Fix up the register information in the insn chain.
     This involves deleting those of the spilled pseudos which did not get
     a new hard register home from the live_{before,after} sets.  */
  for (chain = reload_insn_chain; chain; chain = chain->next)
    {
      HARD_REG_SET used_by_pseudos;
      HARD_REG_SET used_by_pseudos2;

      if (! ira_conflicts_p)
	{
	  /* Don't do it for IRA because IRA and the reload still can
	     assign hard registers to the spilled pseudos on next
	     reload iterations.  */
	  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_throughout);
	  REG_SET_TO_HARD_REG_SET (used_by_pseudos2, &chain->dead_or_set);
	  IOR_HARD_REG_SET (used_by_pseudos, used_by_pseudos2);

	  compute_use_by_pseudos (&used_by_pseudos, &chain->live_throughout);
	  compute_use_by_pseudos (&used_by_pseudos, &chain->dead_or_set);
	  /* Value of chain->used_spill_regs from previous iteration
	     may be not included in the value calculated here because
	     of possible removing caller-saves insns (see function
	     delete_caller_save_insns.  */
	  COMPL_HARD_REG_SET (chain->used_spill_regs, used_by_pseudos);
	  AND_HARD_REG_SET (chain->used_spill_regs, used_spill_regs);
	}
    }

  CLEAR_REG_SET (&changed_allocation_pseudos);
  /* Let alter_reg modify the reg rtx's for the modified pseudos.  */
  for (i = FIRST_PSEUDO_REGISTER; i < (unsigned)max_regno; i++)
    {
      int regno = reg_renumber[i];
      if (reg_old_renumber[i] == regno)
	continue;

      SET_REGNO_REG_SET (&changed_allocation_pseudos, i);

      alter_reg (i, reg_old_renumber[i], false);
      reg_old_renumber[i] = regno;
      if (dump_file)
	{
	  if (regno == -1)
	    fprintf (dump_file, " Register %d now on stack.\n\n", i);
	  else
	    fprintf (dump_file, " Register %d now in %d.\n\n",
		     i, reg_renumber[i]);
	}
    }

  return something_changed;
}

/* Find all paradoxical subregs within X and update reg_max_ref_mode.  */

static void
scan_paradoxical_subregs (rtx x)
{
  int i;
  const char *fmt;
  enum rtx_code code = GET_CODE (x);

  switch (code)
    {
    case REG:
    case CONST:
    case SYMBOL_REF:
    case LABEL_REF:
    CASE_CONST_ANY:
    case CC0:
    case PC:
    case USE:
    case CLOBBER:
    case CLOBBER_HIGH:
      return;

    case SUBREG:
      if (REG_P (SUBREG_REG (x)))
	{
	  unsigned int regno = REGNO (SUBREG_REG (x));
	  if (partial_subreg_p (reg_max_ref_mode[regno], GET_MODE (x)))
	    {
	      reg_max_ref_mode[regno] = GET_MODE (x);
	      mark_home_live_1 (regno, 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')
	{
	  int j;
	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	    scan_paradoxical_subregs (XVECEXP (x, i, j));
	}
    }
}

/* *OP_PTR and *OTHER_PTR are two operands to a conceptual reload.
   If *OP_PTR is a paradoxical subreg, try to remove that subreg
   and apply the corresponding narrowing subreg to *OTHER_PTR.
   Return true if the operands were changed, false otherwise.  */

static bool
strip_paradoxical_subreg (rtx *op_ptr, rtx *other_ptr)
{
  rtx op, inner, other, tem;

  op = *op_ptr;
  if (!paradoxical_subreg_p (op))
    return false;
  inner = SUBREG_REG (op);

  other = *other_ptr;
  tem = gen_lowpart_common (GET_MODE (inner), other);
  if (!tem)
    return false;

  /* If the lowpart operation turned a hard register into a subreg,
     rather than simplifying it to another hard register, then the
     mode change cannot be properly represented.  For example, OTHER
     might be valid in its current mode, but not in the new one.  */
  if (GET_CODE (tem) == SUBREG
      && REG_P (other)
      && HARD_REGISTER_P (other))
    return false;

  *op_ptr = inner;
  *other_ptr = tem;
  return true;
}

/* A subroutine of reload_as_needed.  If INSN has a REG_EH_REGION note,
   examine all of the reload insns between PREV and NEXT exclusive, and
   annotate all that may trap.  */

static void
fixup_eh_region_note (rtx_insn *insn, rtx_insn *prev, rtx_insn *next)
{
  rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
  if (note == NULL)
    return;
  if (!insn_could_throw_p (insn))
    remove_note (insn, note);
  copy_reg_eh_region_note_forward (note, NEXT_INSN (prev), next);
}

/* Reload pseudo-registers into hard regs around each insn as needed.
   Additional register load insns are output before the insn that needs it
   and perhaps store insns after insns that modify the reloaded pseudo reg.

   reg_last_reload_reg and reg_reloaded_contents keep track of
   which registers are already available in reload registers.
   We update these for the reloads that we perform,
   as the insns are scanned.  */

static void
reload_as_needed (int live_known)
{
  struct insn_chain *chain;
#if AUTO_INC_DEC
  int i;
#endif
  rtx_note *marker;

  memset (spill_reg_rtx, 0, sizeof spill_reg_rtx);
  memset (spill_reg_store, 0, sizeof spill_reg_store);
  reg_last_reload_reg = XCNEWVEC (rtx, max_regno);
  INIT_REG_SET (&reg_has_output_reload);
  CLEAR_HARD_REG_SET (reg_reloaded_valid);
  CLEAR_HARD_REG_SET (reg_reloaded_call_part_clobbered);

  set_initial_elim_offsets ();

  /* Generate a marker insn that we will move around.  */
  marker = emit_note (NOTE_INSN_DELETED);
  unlink_insn_chain (marker, marker);

  for (chain = reload_insn_chain; chain; chain = chain->next)
    {
      rtx_insn *prev = 0;
      rtx_insn *insn = chain->insn;
      rtx_insn *old_next = NEXT_INSN (insn);
#if AUTO_INC_DEC
      rtx_insn *old_prev = PREV_INSN (insn);
#endif

      if (will_delete_init_insn_p (insn))
	continue;

      /* If we pass a label, copy the offsets from the label information
	 into the current offsets of each elimination.  */
      if (LABEL_P (insn))
	set_offsets_for_label (insn);

      else if (INSN_P (insn))
	{
	  regset_head regs_to_forget;
	  INIT_REG_SET (&regs_to_forget);
	  note_stores (PATTERN (insn), forget_old_reloads_1, &regs_to_forget);

	  /* If this is a USE and CLOBBER of a MEM, ensure that any
	     references to eliminable registers have been removed.  */

	  if ((GET_CODE (PATTERN (insn)) == USE
	       || GET_CODE (PATTERN (insn)) == CLOBBER)
	      && MEM_P (XEXP (PATTERN (insn), 0)))
	    XEXP (XEXP (PATTERN (insn), 0), 0)
	      = eliminate_regs (XEXP (XEXP (PATTERN (insn), 0), 0),
				GET_MODE (XEXP (PATTERN (insn), 0)),
				NULL_RTX);

	  /* If we need to do register elimination processing, do so.
	     This might delete the insn, in which case we are done.  */
	  if ((num_eliminable || num_eliminable_invariants) && chain->need_elim)
	    {
	      eliminate_regs_in_insn (insn, 1);
	      if (NOTE_P (insn))
		{
		  update_eliminable_offsets ();
		  CLEAR_REG_SET (&regs_to_forget);
		  continue;
		}
	    }

	  /* If need_elim is nonzero but need_reload is zero, one might think
	     that we could simply set n_reloads to 0.  However, find_reloads
	     could have done some manipulation of the insn (such as swapping
	     commutative operands), and these manipulations are lost during
	     the first pass for every insn that needs register elimination.
	     So the actions of find_reloads must be redone here.  */

	  if (! chain->need_elim && ! chain->need_reload
	      && ! chain->need_operand_change)
	    n_reloads = 0;
	  /* First find the pseudo regs that must be reloaded for this insn.
	     This info is returned in the tables reload_... (see reload.h).
	     Also modify the body of INSN by substituting RELOAD
	     rtx's for those pseudo regs.  */
	  else
	    {
	      CLEAR_REG_SET (&reg_has_output_reload);
	      CLEAR_HARD_REG_SET (reg_is_output_reload);

	      find_reloads (insn, 1, spill_indirect_levels, live_known,
			    spill_reg_order);
	    }

	  if (n_reloads > 0)
	    {
	      rtx_insn *next = NEXT_INSN (insn);

	      /* ??? PREV can get deleted by reload inheritance.
		 Work around this by emitting a marker note.  */
	      prev = PREV_INSN (insn);
	      reorder_insns_nobb (marker, marker, prev);

	      /* Now compute which reload regs to reload them into.  Perhaps
		 reusing reload regs from previous insns, or else output
		 load insns to reload them.  Maybe output store insns too.
		 Record the choices of reload reg in reload_reg_rtx.  */
	      choose_reload_regs (chain);

	      /* Generate the insns to reload operands into or out of
		 their reload regs.  */
	      emit_reload_insns (chain);

	      /* Substitute the chosen reload regs from reload_reg_rtx
		 into the insn's body (or perhaps into the bodies of other
		 load and store insn that we just made for reloading
		 and that we moved the structure into).  */
	      subst_reloads (insn);

	      prev = PREV_INSN (marker);
	      unlink_insn_chain (marker, marker);

	      /* Adjust the exception region notes for loads and stores.  */
	      if (cfun->can_throw_non_call_exceptions && !CALL_P (insn))
		fixup_eh_region_note (insn, prev, next);

	      /* Adjust the location of REG_ARGS_SIZE.  */
	      rtx p = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
	      if (p)
		{
		  remove_note (insn, p);
		  fixup_args_size_notes (prev, PREV_INSN (next),
					 get_args_size (p));
		}

	      /* If this was an ASM, make sure that all the reload insns
		 we have generated are valid.  If not, give an error
		 and delete them.  */
	      if (asm_noperands (PATTERN (insn)) >= 0)
		for (rtx_insn *p = NEXT_INSN (prev);
		     p != next;
		     p = NEXT_INSN (p))
		  if (p != insn && INSN_P (p)
		      && GET_CODE (PATTERN (p)) != USE
		      && (recog_memoized (p) < 0
			  || (extract_insn (p),
			      !(constrain_operands (1,
				  get_enabled_alternatives (p))))))
		    {
		      error_for_asm (insn,
				     "%<asm%> operand requires "
				     "impossible reload");
		      delete_insn (p);
		    }
	    }

	  if (num_eliminable && chain->need_elim)
	    update_eliminable_offsets ();

	  /* Any previously reloaded spilled pseudo reg, stored in this insn,
	     is no longer validly lying around to save a future reload.
	     Note that this does not detect pseudos that were reloaded
	     for this insn in order to be stored in
	     (obeying register constraints).  That is correct; such reload
	     registers ARE still valid.  */
	  forget_marked_reloads (&regs_to_forget);
	  CLEAR_REG_SET (&regs_to_forget);

	  /* There may have been CLOBBER insns placed after INSN.  So scan
	     between INSN and NEXT and use them to forget old reloads.  */
	  for (rtx_insn *x = NEXT_INSN (insn); x != old_next; x = NEXT_INSN (x))
	    if (NONJUMP_INSN_P (x) && GET_CODE (PATTERN (x)) == CLOBBER)
	      note_stores (PATTERN (x), forget_old_reloads_1, NULL);

#if AUTO_INC_DEC
	  /* Likewise for regs altered by auto-increment in this insn.
	     REG_INC notes have been changed by reloading:
	     find_reloads_address_1 records substitutions for them,
	     which have been performed by subst_reloads above.  */
	  for (i = n_reloads - 1; i >= 0; i--)
	    {
	      rtx in_reg = rld[i].in_reg;
	      if (in_reg)
		{
		  enum rtx_code code = GET_CODE (in_reg);
		  /* PRE_INC / PRE_DEC will have the reload register ending up
		     with the same value as the stack slot, but that doesn't
		     hold true for POST_INC / POST_DEC.  Either we have to
		     convert the memory access to a true POST_INC / POST_DEC,
		     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 (rld[i].reg_rtx))
		      /* Make sure it is the inc/dec pseudo, and not
			 some other (e.g. output operand) pseudo.  */
		      && ((unsigned) reg_reloaded_contents[REGNO (rld[i].reg_rtx)]
			  == REGNO (XEXP (in_reg, 0))))

		    {
		      rtx reload_reg = rld[i].reg_rtx;
		      machine_mode mode = GET_MODE (reload_reg);
		      int n = 0;
		      rtx_insn *p;

		      for (p = PREV_INSN (old_next); p != prev; p = PREV_INSN (p))
			{
			  /* We really want to ignore REG_INC notes here, so
			     use PATTERN (p) as argument to reg_set_p .  */
			  if (reg_set_p (reload_reg, PATTERN (p)))
			    break;
			  n = count_occurrences (PATTERN (p), reload_reg, 0);
			  if (! n)
			    continue;
			  if (n == 1)
			    {
			      rtx replace_reg
				= gen_rtx_fmt_e (code, mode, reload_reg);

			      validate_replace_rtx_group (reload_reg,
							  replace_reg, p);
			      n = verify_changes (0);

			      /* We must also verify that the constraints
				 are met after the replacement.  Make sure
				 extract_insn is only called for an insn
				 where the replacements were found to be
				 valid so far. */
			      if (n)
				{
				  extract_insn (p);
				  n = constrain_operands (1,
				    get_enabled_alternatives (p));
				}

			      /* If the constraints were not met, then
				 undo the replacement, else confirm it.  */
			      if (!n)
				cancel_changes (0);
			      else
				confirm_change_group ();
			    }
			  break;
			}
		      if (n == 1)
			{
			  add_reg_note (p, REG_INC, reload_reg);
			  /* Mark this as having an output reload so that the
			     REG_INC processing code below won't invalidate
			     the reload for inheritance.  */
			  SET_HARD_REG_BIT (reg_is_output_reload,
					    REGNO (reload_reg));
			  SET_REGNO_REG_SET (&reg_has_output_reload,
					     REGNO (XEXP (in_reg, 0)));
			}
		      else
			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 (rld[i].reg_rtx))
			   /* Make sure it is the inc/dec pseudo, and not
			      some other (e.g. output operand) pseudo.  */
			   && ((unsigned) reg_reloaded_contents[REGNO (rld[i].reg_rtx)]
			       == REGNO (XEXP (in_reg, 0))))
		    {
		      SET_HARD_REG_BIT (reg_is_output_reload,
					REGNO (rld[i].reg_rtx));
		      SET_REGNO_REG_SET (&reg_has_output_reload,
					 REGNO (XEXP (in_reg, 0)));
		    }
		  else if (code == PRE_INC || code == PRE_DEC
			   || code == POST_INC || code == POST_DEC)
		    {
		      int in_regno = REGNO (XEXP (in_reg, 0));

		      if (reg_last_reload_reg[in_regno] != NULL_RTX)
			{
			  int in_hard_regno;
			  bool forget_p = true;

			  in_hard_regno = REGNO (reg_last_reload_reg[in_regno]);
			  if (TEST_HARD_REG_BIT (reg_reloaded_valid,
						 in_hard_regno))
			    {
			      for (rtx_insn *x = (old_prev ?
						  NEXT_INSN (old_prev) : insn);
				   x != old_next;
				   x = NEXT_INSN (x))
				if (x == reg_reloaded_insn[in_hard_regno])
				  {
				    forget_p = false;
				    break;
				  }
			    }
			  /* If for some reasons, we didn't set up
			     reg_last_reload_reg in this insn,
			     invalidate inheritance from previous
			     insns for the incremented/decremented
			     register.  Such registers will be not in
			     reg_has_output_reload.  Invalidate it
			     also if the corresponding element in
			     reg_reloaded_insn is also
			     invalidated.  */
			  if (forget_p)
			    forget_old_reloads_1 (XEXP (in_reg, 0),
						  NULL_RTX, NULL);
			}
		    }
		}
	    }
	  /* If a pseudo that got a hard register is auto-incremented,
	     we must purge records of copying it into pseudos without
	     hard registers.  */
	  for (rtx x = REG_NOTES (insn); x; x = XEXP (x, 1))
	    if (REG_NOTE_KIND (x) == REG_INC)
	      {
		/* See if this pseudo reg was reloaded in this insn.
		   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 (rld[i].out == XEXP (x, 0))
		    break;

		if (i == n_reloads)
		  forget_old_reloads_1 (XEXP (x, 0), NULL_RTX, NULL);
	      }
#endif
	}
      /* A reload reg's contents are unknown after a label.  */
      if (LABEL_P (insn))
	CLEAR_HARD_REG_SET (reg_reloaded_valid);

      /* Don't assume a reload reg is still good after a call insn
	 if it is a call-used reg, or if it contains a value that will
         be partially clobbered by the call.  */
      else if (CALL_P (insn))
	{
	  AND_COMPL_HARD_REG_SET (reg_reloaded_valid, call_used_reg_set);
	  AND_COMPL_HARD_REG_SET (reg_reloaded_valid, reg_reloaded_call_part_clobbered);

	  /* If this is a call to a setjmp-type function, we must not
	     reuse any reload reg contents across the call; that will
	     just be clobbered by other uses of the register in later
	     code, before the longjmp.  */
	  if (find_reg_note (insn, REG_SETJMP, NULL_RTX))
	    CLEAR_HARD_REG_SET (reg_reloaded_valid);
	}
    }

  /* Clean up.  */
  free (reg_last_reload_reg);
  CLEAR_REG_SET (&reg_has_output_reload);
}

/* Discard all record of any value reloaded from X,
   or reloaded in X from someplace else;
   unless X is an output reload reg of the current insn.

   X may be a hard reg (the reload reg)
   or it may be a pseudo reg that was reloaded from.

   When DATA is non-NULL just mark the registers in regset
   to be forgotten later.  */

static void
forget_old_reloads_1 (rtx x, const_rtx setter,
		      void *data)
{
  unsigned int regno;
  unsigned int nr;
  regset regs = (regset) data;

  /* note_stores does give us subregs of hard regs,
     subreg_regno_offset requires a hard reg.  */
  while (GET_CODE (x) == SUBREG)
    {
      /* We ignore the subreg offset when calculating the regno,
	 because we are using the entire underlying hard register
	 below.  */
      x = SUBREG_REG (x);
    }

  if (!REG_P (x))
    return;

  /* CLOBBER_HIGH is only supported for LRA.  */
  gcc_assert (setter == NULL_RTX || GET_CODE (setter) != CLOBBER_HIGH);

  regno = REGNO (x);

  if (regno >= FIRST_PSEUDO_REGISTER)
    nr = 1;
  else
    {
      unsigned int i;

      nr = REG_NREGS (x);
      /* Storing into a spilled-reg invalidates its contents.
	 This can happen if a block-local pseudo is allocated to that reg
	 and it wasn't spilled because this block's total need is 0.
	 Then some insn might have an optional reload and use this reg.  */
      if (!regs)
	for (i = 0; i < nr; i++)
	  /* But don't do this if the reg actually serves as an output
	     reload reg in the current instruction.  */
	  if (n_reloads == 0
	      || ! TEST_HARD_REG_BIT (reg_is_output_reload, regno + i))
	    {
	      CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i);
	      spill_reg_store[regno + i] = 0;
	    }
    }

  if (regs)
    while (nr-- > 0)
      SET_REGNO_REG_SET (regs, regno + nr);
  else
    {
      /* Since value of X has changed,
	 forget any value previously copied from it.  */

      while (nr-- > 0)
	/* But don't forget a copy if this is the output reload
	   that establishes the copy's validity.  */
	if (n_reloads == 0
	    || !REGNO_REG_SET_P (&reg_has_output_reload, regno + nr))
	  reg_last_reload_reg[regno + nr] = 0;
     }
}

/* Forget the reloads marked in regset by previous function.  */
static void
forget_marked_reloads (regset regs)
{
  unsigned int reg;
  reg_set_iterator rsi;
  EXECUTE_IF_SET_IN_REG_SET (regs, 0, reg, rsi)
    {
      if (reg < FIRST_PSEUDO_REGISTER
	  /* But don't do this if the reg actually serves as an output
	     reload reg in the current instruction.  */
	  && (n_reloads == 0
	      || ! TEST_HARD_REG_BIT (reg_is_output_reload, reg)))
	  {
	    CLEAR_HARD_REG_BIT (reg_reloaded_valid, reg);
	    spill_reg_store[reg] = 0;
	  }
      if (n_reloads == 0
	  || !REGNO_REG_SET_P (&reg_has_output_reload, reg))
	reg_last_reload_reg[reg] = 0;
    }
}

/* The following HARD_REG_SETs indicate when each hard register is
   used for a reload of various parts of the current insn.  */

/* If reg is unavailable for all reloads.  */
static HARD_REG_SET reload_reg_unavailable;
/* If reg is in use as a reload reg for a RELOAD_OTHER reload.  */
static HARD_REG_SET reload_reg_used;
/* If reg is in use for a RELOAD_FOR_INPUT_ADDRESS reload for operand I.  */
static HARD_REG_SET reload_reg_used_in_input_addr[MAX_RECOG_OPERANDS];
/* If reg is in use for a RELOAD_FOR_INPADDR_ADDRESS reload for operand I.  */
static HARD_REG_SET reload_reg_used_in_inpaddr_addr[MAX_RECOG_OPERANDS];
/* If reg is in use for a RELOAD_FOR_OUTPUT_ADDRESS reload for operand I.  */
static HARD_REG_SET reload_reg_used_in_output_addr[MAX_RECOG_OPERANDS];
/* If reg is in use for a RELOAD_FOR_OUTADDR_ADDRESS reload for operand I.  */
static HARD_REG_SET reload_reg_used_in_outaddr_addr[MAX_RECOG_OPERANDS];
/* If reg is in use for a RELOAD_FOR_INPUT reload for operand I.  */
static HARD_REG_SET reload_reg_used_in_input[MAX_RECOG_OPERANDS];
/* If reg is in use for a RELOAD_FOR_OUTPUT reload for operand I.  */
static HARD_REG_SET reload_reg_used_in_output[MAX_RECOG_OPERANDS];
/* If reg is in use for a RELOAD_FOR_OPERAND_ADDRESS reload.  */
static HARD_REG_SET reload_reg_used_in_op_addr;
/* If reg is in use for a RELOAD_FOR_OPADDR_ADDR reload.  */
static HARD_REG_SET reload_reg_used_in_op_addr_reload;
/* If reg is in use for a RELOAD_FOR_INSN reload.  */
static HARD_REG_SET reload_reg_used_in_insn;
/* If reg is in use for a RELOAD_FOR_OTHER_ADDRESS reload.  */
static HARD_REG_SET reload_reg_used_in_other_addr;

/* If reg is in use as a reload reg for any sort of reload.  */
static HARD_REG_SET reload_reg_used_at_all;

/* If reg is use as an inherited reload.  We just mark the first register
   in the group.  */
static HARD_REG_SET reload_reg_used_for_inherit;

/* Records which hard regs are used in any way, either as explicit use or
   by being allocated to a pseudo during any point of the current insn.  */
static HARD_REG_SET reg_used_in_insn;

/* Mark reg REGNO as in use for a reload of the sort spec'd by OPNUM and
   TYPE. MODE is used to indicate how many consecutive regs are
   actually used.  */

static void
mark_reload_reg_in_use (unsigned int regno, int opnum, enum reload_type type,
			machine_mode mode)
{
  switch (type)
    {
    case RELOAD_OTHER:
      add_to_hard_reg_set (&reload_reg_used, mode, regno);
      break;

    case RELOAD_FOR_INPUT_ADDRESS:
      add_to_hard_reg_set (&reload_reg_used_in_input_addr[opnum], mode, regno);
      break;

    case RELOAD_FOR_INPADDR_ADDRESS:
      add_to_hard_reg_set (&reload_reg_used_in_inpaddr_addr[opnum], mode, regno);
      break;

    case RELOAD_FOR_OUTPUT_ADDRESS:
      add_to_hard_reg_set (&reload_reg_used_in_output_addr[opnum], mode, regno);
      break;

    case RELOAD_FOR_OUTADDR_ADDRESS:
      add_to_hard_reg_set (&reload_reg_used_in_outaddr_addr[opnum], mode, regno);
      break;

    case RELOAD_FOR_OPERAND_ADDRESS:
      add_to_hard_reg_set (&reload_reg_used_in_op_addr, mode, regno);
      break;

    case RELOAD_FOR_OPADDR_ADDR:
      add_to_hard_reg_set (&reload_reg_used_in_op_addr_reload, mode, regno);
      break;

    case RELOAD_FOR_OTHER_ADDRESS:
      add_to_hard_reg_set (&reload_reg_used_in_other_addr, mode, regno);
      break;

    case RELOAD_FOR_INPUT:
      add_to_hard_reg_set (&reload_reg_used_in_input[opnum], mode, regno);
      break;

    case RELOAD_FOR_OUTPUT:
      add_to_hard_reg_set (&reload_reg_used_in_output[opnum], mode, regno);
      break;

    case RELOAD_FOR_INSN:
      add_to_hard_reg_set (&reload_reg_used_in_insn,  mode, regno);
      break;
    }

  add_to_hard_reg_set (&reload_reg_used_at_all, mode, regno);
}

/* Similarly, but show REGNO is no longer in use for a reload.  */

static void
clear_reload_reg_in_use (unsigned int regno, int opnum,
			 enum reload_type type, machine_mode mode)
{
  unsigned int nregs = hard_regno_nregs (regno, mode);
  unsigned int start_regno, end_regno, r;
  int i;
  /* A complication is that for some reload types, inheritance might
     allow multiple reloads of the same types to share a reload register.
     We set check_opnum if we have to check only reloads with the same
     operand number, and check_any if we have to check all reloads.  */
  int check_opnum = 0;
  int check_any = 0;
  HARD_REG_SET *used_in_set;

  switch (type)
    {
    case RELOAD_OTHER:
      used_in_set = &reload_reg_used;
      break;

    case RELOAD_FOR_INPUT_ADDRESS:
      used_in_set = &reload_reg_used_in_input_addr[opnum];
      break;

    case RELOAD_FOR_INPADDR_ADDRESS:
      check_opnum = 1;
      used_in_set = &reload_reg_used_in_inpaddr_addr[opnum];
      break;

    case RELOAD_FOR_OUTPUT_ADDRESS:
      used_in_set = &reload_reg_used_in_output_addr[opnum];
      break;

    case RELOAD_FOR_OUTADDR_ADDRESS:
      check_opnum = 1;
      used_in_set = &reload_reg_used_in_outaddr_addr[opnum];
      break;

    case RELOAD_FOR_OPERAND_ADDRESS:
      used_in_set = &reload_reg_used_in_op_addr;
      break;

    case RELOAD_FOR_OPADDR_ADDR:
      check_any = 1;
      used_in_set = &reload_reg_used_in_op_addr_reload;
      break;

    case RELOAD_FOR_OTHER_ADDRESS:
      used_in_set = &reload_reg_used_in_other_addr;
      check_any = 1;
      break;

    case RELOAD_FOR_INPUT:
      used_in_set = &reload_reg_used_in_input[opnum];
      break;

    case RELOAD_FOR_OUTPUT:
      used_in_set = &reload_reg_used_in_output[opnum];
      break;

    case RELOAD_FOR_INSN:
      used_in_set = &reload_reg_used_in_insn;
      break;
    default:
      gcc_unreachable ();
    }
  /* We resolve conflicts with remaining reloads of the same type by
     excluding the intervals of reload registers by them from the
     interval of freed reload registers.  Since we only keep track of
     one set of interval bounds, we might have to exclude somewhat
     more than what would be necessary if we used a HARD_REG_SET here.
     But this should only happen very infrequently, so there should
     be no reason to worry about it.  */

  start_regno = regno;
  end_regno = regno + nregs;
  if (check_opnum || check_any)
    {
      for (i = n_reloads - 1; i >= 0; i--)
	{
	  if (rld[i].when_needed == type
	      && (check_any || rld[i].opnum == opnum)
	      && rld[i].reg_rtx)
	    {
	      unsigned int conflict_start = true_regnum (rld[i].reg_rtx);
	      unsigned int conflict_end
		= end_hard_regno (rld[i].mode, conflict_start);

	      /* If there is an overlap with the first to-be-freed register,
		 adjust the interval start.  */
	      if (conflict_start <= start_regno && conflict_end > start_regno)
		start_regno = conflict_end;
	      /* Otherwise, if there is a conflict with one of the other
		 to-be-freed registers, adjust the interval end.  */
	      if (conflict_start > start_regno && conflict_start < end_regno)
		end_regno = conflict_start;
	    }
	}
    }

  for (r = start_regno; r < end_regno; r++)
    CLEAR_HARD_REG_BIT (*used_in_set, r);
}

/* 1 if reg REGNO is free as a reload reg for a reload of the sort
   specified by OPNUM and TYPE.  */

static int
reload_reg_free_p (unsigned int regno, int opnum, enum reload_type type)
{
  int i;

  /* In use for a RELOAD_OTHER means it's not available for anything.  */
  if (TEST_HARD_REG_BIT (reload_reg_used, regno)
      || TEST_HARD_REG_BIT (reload_reg_unavailable, regno))
    return 0;

  switch (type)
    {
    case RELOAD_OTHER:
      /* In use for anything means we can't use it for RELOAD_OTHER.  */
      if (TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno)
	  || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
	  || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
	  || TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno))
	return 0;

      for (i = 0; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
	  return 0;

      return 1;

    case RELOAD_FOR_INPUT:
      if (TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
	  || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno))
	return 0;

      if (TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno))
	return 0;

      /* If it is used for some other input, can't use it.  */
      for (i = 0; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
	  return 0;

      /* If it is used in a later operand's address, can't use it.  */
      for (i = opnum + 1; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno))
	  return 0;

      return 1;

    case RELOAD_FOR_INPUT_ADDRESS:
      /* Can't use a register if it is used for an input address for this
	 operand or used as an input in an earlier one.  */
      if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], regno)
	  || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], regno))
	return 0;

      for (i = 0; i < opnum; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
	  return 0;

      return 1;

    case RELOAD_FOR_INPADDR_ADDRESS:
      /* Can't use a register if it is used for an input address
	 for this operand or used as an input in an earlier
	 one.  */
      if (TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], regno))
	return 0;

      for (i = 0; i < opnum; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
	  return 0;

      return 1;

    case RELOAD_FOR_OUTPUT_ADDRESS:
      /* Can't use a register if it is used for an output address for this
	 operand or used as an output in this or a later operand.  Note
	 that multiple output operands are emitted in reverse order, so
	 the conflicting ones are those with lower indices.  */
      if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], regno))
	return 0;

      for (i = 0; i <= opnum; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
	  return 0;

      return 1;

    case RELOAD_FOR_OUTADDR_ADDRESS:
      /* Can't use a register if it is used for an output address
	 for this operand or used as an output in this or a
	 later operand.  Note that multiple output operands are
	 emitted in reverse order, so the conflicting ones are
	 those with lower indices.  */
      if (TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], regno))
	return 0;

      for (i = 0; i <= opnum; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
	  return 0;

      return 1;

    case RELOAD_FOR_OPERAND_ADDRESS:
      for (i = 0; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
	  return 0;

      return (! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
	      && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno));

    case RELOAD_FOR_OPADDR_ADDR:
      for (i = 0; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
	  return 0;

      return (!TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno));

    case RELOAD_FOR_OUTPUT:
      /* This cannot share a register with RELOAD_FOR_INSN reloads, other
	 outputs, or an operand address for this or an earlier output.
	 Note that multiple output operands are emitted in reverse order,
	 so the conflicting ones are those with higher indices.  */
      if (TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno))
	return 0;

      for (i = 0; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
	  return 0;

      for (i = opnum; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno))
	  return 0;

      return 1;

    case RELOAD_FOR_INSN:
      for (i = 0; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
	  return 0;

      return (! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
	      && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno));

    case RELOAD_FOR_OTHER_ADDRESS:
      return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno);

    default:
      gcc_unreachable ();
    }
}

/* Return 1 if the value in reload reg REGNO, as used by the reload with
   the number RELOADNUM, is still available in REGNO at the end of the insn.

   We can assume that the reload reg was already tested for availability
   at the time it is needed, and we should not check this again,
   in case the reg has already been marked in use.  */

static int
reload_reg_reaches_end_p (unsigned int regno, int reloadnum)
{
  int opnum = rld[reloadnum].opnum;
  enum reload_type type = rld[reloadnum].when_needed;
  int i;

  /* See if there is a reload with the same type for this operand, using
     the same register. This case is not handled by the code below.  */
  for (i = reloadnum + 1; i < n_reloads; i++)
    {
      rtx reg;

      if (rld[i].opnum != opnum || rld[i].when_needed != type)
	continue;
      reg = rld[i].reg_rtx;
      if (reg == NULL_RTX)
	continue;
      if (regno >= REGNO (reg) && regno < END_REGNO (reg))
	return 0;
    }
  
  switch (type)
    {
    case RELOAD_OTHER:
      /* Since a RELOAD_OTHER reload claims the reg for the entire insn,
	 its value must reach the end.  */
      return 1;

      /* If this use is for part of the insn,
	 its value reaches if no subsequent part uses the same register.
	 Just like the above function, don't try to do this with lots
	 of fallthroughs.  */

    case RELOAD_FOR_OTHER_ADDRESS:
      /* Here we check for everything else, since these don't conflict
	 with anything else and everything comes later.  */

      for (i = 0; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
	  return 0;

      return (! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
	      && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
	      && ! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
	      && ! TEST_HARD_REG_BIT (reload_reg_used, regno));

    case RELOAD_FOR_INPUT_ADDRESS:
    case RELOAD_FOR_INPADDR_ADDRESS:
      /* Similar, except that we check only for this and subsequent inputs
	 and the address of only subsequent inputs and we do not need
	 to check for RELOAD_OTHER objects since they are known not to
	 conflict.  */

      for (i = opnum; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
	  return 0;

      /* Reload register of reload with type RELOAD_FOR_INPADDR_ADDRESS
	 could be killed if the register is also used by reload with type
	 RELOAD_FOR_INPUT_ADDRESS, so check it.  */
      if (type == RELOAD_FOR_INPADDR_ADDRESS
	  && TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], regno))
	return 0;

      for (i = opnum + 1; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno))
	  return 0;

      for (i = 0; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
	  return 0;

      if (TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno))
	return 0;

      return (!TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
	      && !TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
	      && !TEST_HARD_REG_BIT (reload_reg_used, regno));

    case RELOAD_FOR_INPUT:
      /* Similar to input address, except we start at the next operand for
	 both input and input address and we do not check for
	 RELOAD_FOR_OPERAND_ADDRESS and RELOAD_FOR_INSN since these
	 would conflict.  */

      for (i = opnum + 1; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
	  return 0;

      /* ... fall through ...  */

    case RELOAD_FOR_OPERAND_ADDRESS:
      /* Check outputs and their addresses.  */

      for (i = 0; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
	  return 0;

      return (!TEST_HARD_REG_BIT (reload_reg_used, regno));

    case RELOAD_FOR_OPADDR_ADDR:
      for (i = 0; i < reload_n_operands; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
	  return 0;

      return (!TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
	      && !TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
	      && !TEST_HARD_REG_BIT (reload_reg_used, regno));

    case RELOAD_FOR_INSN:
      /* These conflict with other outputs with RELOAD_OTHER.  So
	 we need only check for output addresses.  */

      opnum = reload_n_operands;

      /* fall through */

    case RELOAD_FOR_OUTPUT:
    case RELOAD_FOR_OUTPUT_ADDRESS:
    case RELOAD_FOR_OUTADDR_ADDRESS:
      /* We already know these can't conflict with a later output.  So the
	 only thing to check are later output addresses.
	 Note that multiple output operands are emitted in reverse order,
	 so the conflicting ones are those with lower indices.  */
      for (i = 0; i < opnum; i++)
	if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
	    || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno))
	  return 0;

      /* Reload register of reload with type RELOAD_FOR_OUTADDR_ADDRESS
	 could be killed if the register is also used by reload with type
	 RELOAD_FOR_OUTPUT_ADDRESS, so check it.  */
      if (type == RELOAD_FOR_OUTADDR_ADDRESS
	  && TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], regno))
	return 0;

      return 1;

    default:
      gcc_unreachable ();
    }
}

/* Like reload_reg_reaches_end_p, but check that the condition holds for
   every register in REG.  */

static bool
reload_reg_rtx_reaches_end_p (rtx reg, int reloadnum)
{
  unsigned int i;

  for (i = REGNO (reg); i < END_REGNO (reg); i++)
    if (!reload_reg_reaches_end_p (i, reloadnum))
      return false;
  return true;
}


/*  Returns whether R1 and R2 are uniquely chained: the value of one
    is used by the other, and that value is not used by any other
    reload for this insn.  This is used to partially undo the decision
    made in find_reloads when in the case of multiple
    RELOAD_FOR_OPERAND_ADDRESS reloads it converts all
    RELOAD_FOR_OPADDR_ADDR reloads into RELOAD_FOR_OPERAND_ADDRESS
    reloads.  This code tries to avoid the conflict created by that
    change.  It might be cleaner to explicitly keep track of which
    RELOAD_FOR_OPADDR_ADDR reload is associated with which
    RELOAD_FOR_OPERAND_ADDRESS reload, rather than to try to detect
    this after the fact. */
static bool
reloads_unique_chain_p (int r1, int r2)
{
  int i;

  /* We only check input reloads.  */
  if (! rld[r1].in || ! rld[r2].in)
    return false;

  /* Avoid anything with output reloads.  */
  if (rld[r1].out || rld[r2].out)
    return false;

  /* "chained" means one reload is a component of the other reload,
     not the same as the other reload.  */
  if (rld[r1].opnum != rld[r2].opnum
      || rtx_equal_p (rld[r1].in, rld[r2].in)
      || rld[r1].optional || rld[r2].optional
      || ! (reg_mentioned_p (rld[r1].in, rld[r2].in)
	    || reg_mentioned_p (rld[r2].in, rld[r1].in)))
    return false;

  /* The following loop assumes that r1 is the reload that feeds r2.  */
  if (r1 > r2)
    std::swap (r1, r2);

  for (i = 0; i < n_reloads; i ++)
    /* Look for input reloads that aren't our two */
    if (i != r1 && i != r2 && rld[i].in)
      {
	/* If our reload is mentioned at all, it isn't a simple chain.  */
	if (reg_mentioned_p (rld[r1].in, rld[i].in))
	  return false;
      }
  return true;
}

/* The recursive function change all occurrences of WHAT in *WHERE
   to REPL.  */
static void
substitute (rtx *where, const_rtx what, rtx repl)
{
  const char *fmt;
  int i;
  enum rtx_code code;

  if (*where == 0)
    return;

  if (*where == what || rtx_equal_p (*where, what))
    {
      /* Record the location of the changed rtx.  */
      substitute_stack.safe_push (where);
      *where = repl;
      return;
    }

  code = GET_CODE (*where);
  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'E')
	{
	  int j;

	  for (j = XVECLEN (*where, i) - 1; j >= 0; j--)
	    substitute (&XVECEXP (*where, i, j), what, repl);
	}
      else if (fmt[i] == 'e')
	substitute (&XEXP (*where, i), what, repl);
    }
}

/* The function returns TRUE if chain of reload R1 and R2 (in any
   order) can be evaluated without usage of intermediate register for
   the reload containing another reload.  It is important to see
   gen_reload to understand what the function is trying to do.  As an
   example, let us have reload chain

      r2: const
      r1: <something> + const

   and reload R2 got reload reg HR.  The function returns true if
   there is a correct insn HR = HR + <something>.  Otherwise,
   gen_reload will use intermediate register (and this is the reload
   reg for R1) to reload <something>.

   We need this function to find a conflict for chain reloads.  In our
   example, if HR = HR + <something> is incorrect insn, then we cannot
   use HR as a reload register for R2.  If we do use it then we get a
   wrong code:

      HR = const
      HR = <something>
      HR = HR + HR

*/
static bool
gen_reload_chain_without_interm_reg_p (int r1, int r2)
{
  /* Assume other cases in gen_reload are not possible for
     chain reloads or do need an intermediate hard registers.  */
  bool result = true;
  int regno, code;
  rtx out, in;
  rtx_insn *insn;
  rtx_insn *last = get_last_insn ();

  /* Make r2 a component of r1.  */
  if (reg_mentioned_p (rld[r1].in, rld[r2].in))
    std::swap (r1, r2);

  gcc_assert (reg_mentioned_p (rld[r2].in, rld[r1].in));
  regno = rld[r1].regno >= 0 ? rld[r1].regno : rld[r2].regno;
  gcc_assert (regno >= 0);
  out = gen_rtx_REG (rld[r1].mode, regno);
  in = rld[r1].in;
  substitute (&in, rld[r2].in, gen_rtx_REG (rld[r2].mode, regno));

  /* If IN is a paradoxical SUBREG, remove it and try to put the
     opposite SUBREG on OUT.  Likewise for a paradoxical SUBREG on OUT.  */
  strip_paradoxical_subreg (&in, &out);

  if (GET_CODE (in) == PLUS
      && (REG_P (XEXP (in, 0))
	  || GET_CODE (XEXP (in, 0)) == SUBREG
	  || MEM_P (XEXP (in, 0)))
      && (REG_P (XEXP (in, 1))
	  || GET_CODE (XEXP (in, 1)) == SUBREG
	  || CONSTANT_P (XEXP (in, 1))
	  || MEM_P (XEXP (in, 1))))
    {
      insn = emit_insn (gen_rtx_SET (out, in));
      code = recog_memoized (insn);
      result = false;

      if (code >= 0)
	{
	  extract_insn (insn);
	  /* We want constrain operands to treat this insn strictly in
	     its validity determination, i.e., the way it would after
	     reload has completed.  */
	  result = constrain_operands (1, get_enabled_alternatives (insn));
	}

      delete_insns_since (last);
    }

  /* Restore the original value at each changed address within R1.  */
  while (!substitute_stack.is_empty ())
    {
      rtx *where = substitute_stack.pop ();
      *where = rld[r2].in;
    }

  return result;
}

/* Return 1 if the reloads denoted by R1 and R2 cannot share a register.
   Return 0 otherwise.

   This function uses the same algorithm as reload_reg_free_p above.  */

static int
reloads_conflict (int r1, int 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)
    return 1;

  /* Otherwise, check conflicts differently for each type.  */

  switch (r1_type)
    {
    case RELOAD_FOR_INPUT:
      return (r2_type == RELOAD_FOR_INSN
	      || r2_type == RELOAD_FOR_OPERAND_ADDRESS
	      || r2_type == RELOAD_FOR_OPADDR_ADDR
	      || r2_type == RELOAD_FOR_INPUT
	      || ((r2_type == RELOAD_FOR_INPUT_ADDRESS
		   || r2_type == RELOAD_FOR_INPADDR_ADDRESS)
		  && r2_opnum > r1_opnum));

    case RELOAD_FOR_INPUT_ADDRESS:
      return ((r2_type == RELOAD_FOR_INPUT_ADDRESS && r1_opnum == r2_opnum)
	      || (r2_type == RELOAD_FOR_INPUT && r2_opnum < r1_opnum));

    case RELOAD_FOR_INPADDR_ADDRESS:
      return ((r2_type == RELOAD_FOR_INPADDR_ADDRESS && r1_opnum == r2_opnum)
	      || (r2_type == RELOAD_FOR_INPUT && r2_opnum < r1_opnum));

    case RELOAD_FOR_OUTPUT_ADDRESS:
      return ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS && r2_opnum == r1_opnum)
	      || (r2_type == RELOAD_FOR_OUTPUT && r2_opnum <= r1_opnum));

    case RELOAD_FOR_OUTADDR_ADDRESS:
      return ((r2_type == RELOAD_FOR_OUTADDR_ADDRESS && r2_opnum == r1_opnum)
	      || (r2_type == RELOAD_FOR_OUTPUT && r2_opnum <= r1_opnum));

    case RELOAD_FOR_OPERAND_ADDRESS:
      return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_INSN
	      || (r2_type == RELOAD_FOR_OPERAND_ADDRESS
		  && (!reloads_unique_chain_p (r1, r2)
		      || !gen_reload_chain_without_interm_reg_p (r1, r2))));

    case RELOAD_FOR_OPADDR_ADDR:
      return (r2_type == RELOAD_FOR_INPUT
	      || r2_type == RELOAD_FOR_OPADDR_ADDR);

    case RELOAD_FOR_OUTPUT:
      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));

    case RELOAD_FOR_INSN:
      return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_OUTPUT
	      || r2_type == RELOAD_FOR_INSN
	      || r2_type == RELOAD_FOR_OPERAND_ADDRESS);

    case RELOAD_FOR_OTHER_ADDRESS:
      return r2_type == RELOAD_FOR_OTHER_ADDRESS;

    case RELOAD_OTHER:
      return 1;

    default:
      gcc_unreachable ();
    }
}

/* Indexed by reload number, 1 if incoming value
   inherited from previous insns.  */
static char reload_inherited[MAX_RELOADS];

/* For an inherited reload, this is the insn the reload was inherited from,
   if we know it.  Otherwise, this is 0.  */
static rtx_insn *reload_inheritance_insn[MAX_RELOADS];

/* If nonzero, this is a place to get the value of the reload,
   rather than using reload_in.  */
static rtx reload_override_in[MAX_RELOADS];

/* For each reload, the hard register number of the register used,
   or -1 if we did not need a register for this reload.  */
static int reload_spill_index[MAX_RELOADS];

/* Index X is the value of rld[X].reg_rtx, adjusted for the input mode.  */
static rtx reload_reg_rtx_for_input[MAX_RELOADS];

/* Index X is the value of rld[X].reg_rtx, adjusted for the output mode.  */
static rtx reload_reg_rtx_for_output[MAX_RELOADS];

/* Subroutine of free_for_value_p, used to check a single register.
   START_REGNO is the starting regno of the full reload register
   (possibly comprising multiple hard registers) that we are considering.  */

static int
reload_reg_free_for_value_p (int start_regno, int regno, int opnum,
			     enum reload_type type, rtx value, rtx out,
			     int 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;

  if (TEST_HARD_REG_BIT (reload_reg_unavailable, regno))
    return 0;

  if (out == const0_rtx)
    {
      copy = 1;
      out = NULL_RTX;
    }

  /* We use some pseudo 'time' value to check if the lifetimes of the
     new register use would overlap with the one of a previous reload
     that is not read-only or uses a different value.
     The 'time' used doesn't have to be linear in any shape or form, just
     monotonic.
     Some reload types use different 'buckets' for each operand.
     So there are MAX_RECOG_OPERANDS different time values for each
     such reload type.
     We compute TIME1 as the time when the register for the prospective
     new reload ceases to be live, and TIME2 for each existing
     reload as the time when that the reload register of that reload
     becomes live.
     Where there is little to be gained by exact lifetime calculations,
     we just make conservative assumptions, i.e. a longer lifetime;
     this is done in the 'default:' cases.  */
  switch (type)
    {
    case RELOAD_FOR_OTHER_ADDRESS:
      /* RELOAD_FOR_OTHER_ADDRESS conflicts with RELOAD_OTHER reloads.  */
      time1 = copy ? 0 : 1;
      break;
    case RELOAD_OTHER:
      time1 = copy ? 1 : MAX_RECOG_OPERANDS * 5 + 5;
      break;
      /* For each input, we may have a sequence of RELOAD_FOR_INPADDR_ADDRESS,
	 RELOAD_FOR_INPUT_ADDRESS and RELOAD_FOR_INPUT.  By adding 0 / 1 / 2 ,
	 respectively, to the time values for these, we get distinct time
	 values.  To get distinct time values for each operand, we have to
	 multiply opnum by at least three.  We round that up to four because
	 multiply by four is often cheaper.  */
    case RELOAD_FOR_INPADDR_ADDRESS:
      time1 = opnum * 4 + 2;
      break;
    case RELOAD_FOR_INPUT_ADDRESS:
      time1 = opnum * 4 + 3;
      break;
    case RELOAD_FOR_INPUT:
      /* All RELOAD_FOR_INPUT reloads remain live till the instruction
	 executes (inclusive).  */
      time1 = copy ? opnum * 4 + 4 : MAX_RECOG_OPERANDS * 4 + 3;
      break;
    case RELOAD_FOR_OPADDR_ADDR:
      /* opnum * 4 + 4
	 <= (MAX_RECOG_OPERANDS - 1) * 4 + 4 == MAX_RECOG_OPERANDS * 4 */
      time1 = MAX_RECOG_OPERANDS * 4 + 1;
      break;
    case RELOAD_FOR_OPERAND_ADDRESS:
      /* RELOAD_FOR_OPERAND_ADDRESS reloads are live even while the insn
	 is executed.  */
      time1 = copy ? MAX_RECOG_OPERANDS * 4 + 2 : MAX_RECOG_OPERANDS * 4 + 3;
      break;
    case RELOAD_FOR_OUTADDR_ADDRESS:
      time1 = MAX_RECOG_OPERANDS * 4 + 4 + opnum;
      break;
    case RELOAD_FOR_OUTPUT_ADDRESS:
      time1 = MAX_RECOG_OPERANDS * 4 + 5 + opnum;
      break;
    default:
      time1 = MAX_RECOG_OPERANDS * 5 + 5;
    }

  for (i = 0; i < n_reloads; i++)
    {
      rtx reg = rld[i].reg_rtx;
      if (reg && REG_P (reg)
	  && (unsigned) regno - true_regnum (reg) < REG_NREGS (reg)
	  && i != reloadnum)
	{
	  rtx other_input = rld[i].in;

	  /* If the other reload loads the same input value, that
	     will not cause a conflict only if it's loading it into
	     the same register.  */
	  if (true_regnum (reg) != start_regno)
	    other_input = NULL_RTX;
	  if (! other_input || ! rtx_equal_p (other_input, value)
	      || rld[i].out || out)
	    {
	      int time2;
	      switch (rld[i].when_needed)
		{
		case RELOAD_FOR_OTHER_ADDRESS:
		  time2 = 0;
		  break;
		case RELOAD_FOR_INPADDR_ADDRESS:
		  /* find_reloads makes sure that a
		     RELOAD_FOR_{INP,OP,OUT}ADDR_ADDRESS reload is only used
		     by at most one - the first -
		     RELOAD_FOR_{INPUT,OPERAND,OUTPUT}_ADDRESS .  If the
		     address reload is inherited, the address address reload
		     goes away, so we can ignore this conflict.  */
		  if (type == RELOAD_FOR_INPUT_ADDRESS && reloadnum == i + 1
		      && ignore_address_reloads
		      /* Unless the RELOAD_FOR_INPUT is an auto_inc expression.
			 Then the address address is still needed to store
			 back the new address.  */
		      && ! 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 == rld[i].opnum
		      && ignore_address_reloads
		      /* Unless we are reloading an auto_inc expression.  */
		      && ! rld[reloadnum].out)
		    continue;
		  time2 = rld[i].opnum * 4 + 2;
		  break;
		case RELOAD_FOR_INPUT_ADDRESS:
		  if (type == RELOAD_FOR_INPUT && opnum == rld[i].opnum
		      && ignore_address_reloads
		      && ! rld[reloadnum].out)
		    continue;
		  time2 = rld[i].opnum * 4 + 3;
		  break;
		case RELOAD_FOR_INPUT:
		  time2 = rld[i].opnum * 4 + 4;
		  check_earlyclobber = 1;
		  break;
		  /* 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
		      && ! 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;
		  break;
		case RELOAD_FOR_OUTPUT:
		  /* All RELOAD_FOR_OUTPUT reloads become live just after the
		     instruction is executed.  */
		  time2 = MAX_RECOG_OPERANDS * 4 + 4;
		  break;
		  /* The first RELOAD_FOR_OUTADDR_ADDRESS reload conflicts with
		     the RELOAD_FOR_OUTPUT reloads, so assign it the same time
		     value.  */
		case RELOAD_FOR_OUTADDR_ADDRESS:
		  if (type == RELOAD_FOR_OUTPUT_ADDRESS && reloadnum == i + 1
		      && ignore_address_reloads
		      && ! rld[reloadnum].out)
		    continue;
		  time2 = MAX_RECOG_OPERANDS * 4 + 4 + rld[i].opnum;
		  break;
		case RELOAD_FOR_OUTPUT_ADDRESS:
		  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 (! rld[i].in || rtx_equal_p (other_input, 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;
		  /* RELOAD_OTHER might be live beyond instruction execution,
		     but this is not obvious when we set time2 = 1.  So check
		     here if there might be a problem with the new reload
		     clobbering the register used by the RELOAD_OTHER.  */
		  if (out)
		    return 0;
		  break;
		default:
		  return 0;
		}
	      if ((time1 >= time2
		   && (! rld[i].in || rld[i].out
		       || ! rtx_equal_p (other_input, 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;
}

/* Return 1 if the value in reload reg REGNO, as used by a reload
   needed for the part of the insn specified by OPNUM and TYPE,
   may be used to load VALUE into it.

   MODE is the mode in which the register is used, this is needed to
   determine how many hard regs to test.

   Other read-only reloads with the same value do not conflict
   unless OUT is nonzero and these other reloads have to live while
   output reloads live.
   If OUT is CONST0_RTX, this is a special case: it means that the
   test should not be for using register REGNO as reload register, but
   for copying from register REGNO into the reload register.

   RELOADNUM is the number of the reload we want to load this value for;
   a reload does not conflict with itself.

   When IGNORE_ADDRESS_RELOADS is set, we cannot have conflicts with
   reloads that load an address for the very reload we are considering.

   The caller has to make sure that there is no conflict with the return
   register.  */

static int
free_for_value_p (int regno, machine_mode mode, int opnum,
		  enum reload_type type, rtx value, rtx out, int reloadnum,
		  int ignore_address_reloads)
{
  int nregs = hard_regno_nregs (regno, mode);
  while (nregs-- > 0)
    if (! reload_reg_free_for_value_p (regno, regno + nregs, opnum, type,
				       value, out, reloadnum,
				       ignore_address_reloads))
      return 0;
  return 1;
}

/* Return nonzero if the rtx X is invariant over the current function.  */
/* ??? Actually, the places where we use this expect exactly what is
   tested here, and not everything that is function invariant.  In
   particular, the frame pointer and arg pointer are special cased;
   pic_offset_table_rtx is not, and we must not spill these things to
   memory.  */

int
function_invariant_p (const_rtx x)
{
  if (CONSTANT_P (x))
    return 1;
  if (x == frame_pointer_rtx || x == arg_pointer_rtx)
    return 1;
  if (GET_CODE (x) == PLUS
      && (XEXP (x, 0) == frame_pointer_rtx || XEXP (x, 0) == arg_pointer_rtx)
      && GET_CODE (XEXP (x, 1)) == CONST_INT)
    return 1;
  return 0;
}

/* Determine whether the reload reg X overlaps any rtx'es used for
   overriding inheritance.  Return nonzero if so.  */

static int
conflicts_with_override (rtx x)
{
  int i;
  for (i = 0; i < n_reloads; i++)
    if (reload_override_in[i]
	&& reg_overlap_mentioned_p (x, reload_override_in[i]))
      return 1;
  return 0;
}

/* Give an error message saying we failed to find a reload for INSN,
   and clear out reload R.  */
static void
failed_reload (rtx_insn *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 (int i, int 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 (targetm.hard_regno_mode_ok (regno, rld[r].mode))
    {
      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
	     && !targetm.hard_regno_mode_ok (regno, test_mode)))
	if (! (rld[r].out != 0
	       && !targetm.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 nonzero if this is the last reload for the insn being
   processed.

   Set rld[R].reg_rtx to the register allocated.

   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 (struct insn_chain *chain ATTRIBUTE_UNUSED, int r,
		     int last_reload)
{
  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
     reg that some other reload needs.
     (That can happen when we have a 68000 DATA_OR_FP_REG
     which is a group of data regs or one fp reg.)
     We need not be so restrictive if there are no more reloads
     for this insn.

     ??? Really it would be nicer to have smarter handling
     for that kind of reg class, where a problem like this is normal.
     Perhaps those classes should be avoided for reloading
     by use of more alternatives.  */

  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.
     If we want a consecutive group, here is where we look for it.

     We use three passes so we can first look for reload regs to
     reuse, which are already in use for other reloads in this insn,
     and only then use additional registers which are not "bad", then
     finally any register.

     I think that maximizing reuse is needed to make sure we don't
     run out of reload regs.  Suppose we have three reloads, and
     reloads A and B can share regs.  These need two regs.
     Suppose A and B are given different regs.
     That leaves none for C.  */
  for (pass = 0; pass < 3; pass++)
    {
      /* 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.  */

      i = last_spill_reg;

      for (count = 0; count < n_spills; count++)
	{
	  int rclass = (int) rld[r].rclass;
	  int regnum;

	  i++;
	  if (i >= n_spills)
	    i -= n_spills;
	  regnum = spill_regs[i];

	  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)
		   && free_for_value_p (regnum, rld[r].mode, rld[r].opnum,
					rld[r].when_needed, rld[r].in,
					rld[r].out, r, 1)))
	      && TEST_HARD_REG_BIT (reg_class_contents[rclass], regnum)
	      && targetm.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.  */
	      && (pass
		  || (TEST_HARD_REG_BIT (reload_reg_used_at_all,
					 regnum)
		      && ! TEST_HARD_REG_BIT (reload_reg_used_for_inherit,
					      regnum))))
	    {
	      int nr = hard_regno_nregs (regnum, rld[r].mode);

	      /* During the second pass we want to avoid reload registers
		 which are "bad" for this reload.  */
	      if (pass == 1
		  && ira_bad_reload_regno (regnum, rld[r].in, rld[r].out))
		continue;

	      /* 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 = rld[r].nregs;
	      /* If we need only one reg, we have already won.  */
	      if (nr == 1)
		{
		  /* But reject a single reg if we demand a group.  */
		  if (force_group)
		    continue;
		  break;
		}
	      /* Otherwise check that as many consecutive regs as we need
		 are available here.  */
	      while (nr > 1)
		{
		  int regno = regnum + nr - 1;
		  if (!(TEST_HARD_REG_BIT (reg_class_contents[rclass], regno)
			&& spill_reg_order[regno] >= 0
			&& reload_reg_free_p (regno, rld[r].opnum,
					      rld[r].when_needed)))
		    break;
		  nr--;
		}
	      if (nr == 1)
		break;
	    }
	}

      /* If we found something on the current pass, omit later passes.  */
      if (count < n_spills)
	break;
    }

  /* We should have found a spill register by now.  */
  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.  */

  return set_reload_reg (i, r);
}

/* 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_init (struct insn_chain *chain, rtx *save_reload_reg_rtx)
{
  int i;

  for (i = 0; i < n_reloads; i++)
    rld[i].reg_rtx = save_reload_reg_rtx[i];

  memset (reload_inherited, 0, MAX_RELOADS);
  memset (reload_inheritance_insn, 0, MAX_RELOADS * sizeof (rtx));
  memset (reload_override_in, 0, MAX_RELOADS * sizeof (rtx));

  CLEAR_HARD_REG_SET (reload_reg_used);
  CLEAR_HARD_REG_SET (reload_reg_used_at_all);
  CLEAR_HARD_REG_SET (reload_reg_used_in_op_addr);
  CLEAR_HARD_REG_SET (reload_reg_used_in_op_addr_reload);
  CLEAR_HARD_REG_SET (reload_reg_used_in_insn);
  CLEAR_HARD_REG_SET (reload_reg_used_in_other_addr);

  CLEAR_HARD_REG_SET (reg_used_in_insn);
  {
    HARD_REG_SET tmp;
    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->dead_or_set);
    IOR_HARD_REG_SET (reg_used_in_insn, tmp);
    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++)
    {
      CLEAR_HARD_REG_SET (reload_reg_used_in_output[i]);
      CLEAR_HARD_REG_SET (reload_reg_used_in_input[i]);
      CLEAR_HARD_REG_SET (reload_reg_used_in_input_addr[i]);
      CLEAR_HARD_REG_SET (reload_reg_used_in_inpaddr_addr[i]);
      CLEAR_HARD_REG_SET (reload_reg_used_in_output_addr[i]);
      CLEAR_HARD_REG_SET (reload_reg_used_in_outaddr_addr[i]);
    }

  COMPL_HARD_REG_SET (reload_reg_unavailable, chain->used_spill_regs);

  CLEAR_HARD_REG_SET (reload_reg_used_for_inherit);

  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);
}

/* If X is not a subreg, return it unmodified.  If it is a subreg,
   look up whether we made a replacement for the SUBREG_REG.  Return
   either the replacement or the SUBREG_REG.  */

static rtx
replaced_subreg (rtx x)
{
  if (GET_CODE (x) == SUBREG)
    return find_replacement (&SUBREG_REG (x));
  return x;
}

/* Compute the offset to pass to subreg_regno_offset, for a pseudo of
   mode OUTERMODE that is available in a hard reg of mode INNERMODE.
   SUBREG is non-NULL if the pseudo is a subreg whose reg is a pseudo,
   otherwise it is NULL.  */

static poly_int64
compute_reload_subreg_offset (machine_mode outermode,
			      rtx subreg,
			      machine_mode innermode)
{
  poly_int64 outer_offset;
  machine_mode middlemode;

  if (!subreg)
    return subreg_lowpart_offset (outermode, innermode);

  outer_offset = SUBREG_BYTE (subreg);
  middlemode = GET_MODE (SUBREG_REG (subreg));

  /* If SUBREG is paradoxical then return the normal lowpart offset
     for OUTERMODE and INNERMODE.  Our caller has already checked
     that OUTERMODE fits in INNERMODE.  */
  if (paradoxical_subreg_p (outermode, middlemode))
    return subreg_lowpart_offset (outermode, innermode);

  /* SUBREG is normal, but may not be lowpart; return OUTER_OFFSET
     plus the normal lowpart offset for MIDDLEMODE and INNERMODE.  */
  return outer_offset + subreg_lowpart_offset (middlemode, innermode);
}

/* 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 (struct insn_chain *chain)
{
  rtx_insn *insn = chain->insn;
  int i, j;
  unsigned 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.
     Then our grabbing of reload registers will parallel the process
     that provided the reload registers.

     Also note whether any of the reloads wants a consecutive group of regs.
     If so, record the maximum size of the group desired and what
     register class contains all the groups needed by this insn.  */

  for (j = 0; j < n_reloads; j++)
    {
      reload_order[j] = j;
      if (rld[j].reg_rtx != NULL_RTX)
	{
	  gcc_assert (REG_P (rld[j].reg_rtx)
		      && HARD_REGISTER_P (rld[j].reg_rtx));
	  reload_spill_index[j] = REGNO (rld[j].reg_rtx);
	}
      else
	reload_spill_index[j] = -1;

      if (rld[j].nregs > 1)
	{
	  max_group_size = MAX (rld[j].nregs, max_group_size);
	  group_class
	    = reg_class_superunion[(int) rld[j].rclass][(int) group_class];
	}

      save_reload_reg_rtx[j] = rld[j].reg_rtx;
    }

  if (n_reloads > 1)
    qsort (reload_order, n_reloads, sizeof (short), reload_reg_class_lower);

  /* 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.

	 This used to look for an existing reloaded home for all of the
	 reloads, and only then perform any new reloads.  But that could lose
	 if the reloads were done out of reg-class order because a later
	 reload with a looser constraint might have an old home in a register
	 needed by an earlier reload with a tighter constraint.

	 To solve this, we make two passes over the reloads, in the order
	 described above.  In the first pass we try to inherit a reload
	 from a previous insn.  If there is a later reload that needs a
	 class that is a proper subset of the class being processed, we must
	 also allocate a spill register during the first pass.

	 Then make a second pass over the reloads to allocate any reloads
	 that haven't been given registers yet.  */

      for (j = 0; j < n_reloads; j++)
	{
	  int r = reload_order[j];
	  rtx search_equiv = NULL_RTX;

	  /* Ignore reloads that got marked inoperative.  */
	  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
	     register, we don't need to chose one.  Otherwise, try even if it
	     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 (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)
		      && !MEM_P (rld[r].in)
		      && true_regnum (rld[r].in) < FIRST_PSEUDO_REGISTER)))
	    continue;

#if 0 /* No longer needed for correct operation.
	 It might give better code, or might not; worth an experiment?  */
	  /* If this is an optional reload, we can't inherit from earlier insns
	     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 (rld[r].optional != 0)
	    for (i = 0; i < j; i++)
	      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
	     for a previous insn.  We cannot try to inherit for reloads
	     that are smaller than the maximum number of registers needed
	     for groups unless the register we would allocate cannot be used
	     for the groups.

	     We could check here to see if this is a secondary reload for
	     an object that is already in a register of the desired class.
	     This would avoid the need for the secondary reload register.
	     But this is complex because we can't easily determine what
	     objects might want to be loaded via this reload.  So let a
	     register be allocated here.  In `emit_reload_insns' we suppress
	     one of the loads in the case described above.  */

	  if (inheritance)
	    {
	      poly_int64 byte = 0;
	      int regno = -1;
	      machine_mode mode = VOIDmode;
	      rtx subreg = NULL_RTX;

	      if (rld[r].in == 0)
		;
	      else if (REG_P (rld[r].in))
		{
		  regno = REGNO (rld[r].in);
		  mode = GET_MODE (rld[r].in);
		}
	      else if (REG_P (rld[r].in_reg))
		{
		  regno = REGNO (rld[r].in_reg);
		  mode = GET_MODE (rld[r].in_reg);
		}
	      else if (GET_CODE (rld[r].in_reg) == SUBREG
		       && REG_P (SUBREG_REG (rld[r].in_reg)))
		{
		  regno = REGNO (SUBREG_REG (rld[r].in_reg));
		  if (regno < FIRST_PSEUDO_REGISTER)
		    regno = subreg_regno (rld[r].in_reg);
		  else
		    {
		      subreg = rld[r].in_reg;
		      byte = SUBREG_BYTE (subreg);
		    }
		  mode = GET_MODE (rld[r].in_reg);
		}
#if AUTO_INC_DEC
	      else if (GET_RTX_CLASS (GET_CODE (rld[r].in_reg)) == RTX_AUTOINC
		       && REG_P (XEXP (rld[r].in_reg, 0)))
		{
		  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 (rld[r].in) == SUBREG
		       && REG_P (SUBREG_REG (rld[r].in)))
		regno = subreg_regno (rld[r].in);
#endif

	      if (regno >= 0
		  && reg_last_reload_reg[regno] != 0
		  && (known_ge
		      (GET_MODE_SIZE (GET_MODE (reg_last_reload_reg[regno])),
		       GET_MODE_SIZE (mode) + byte))
		  /* Verify that the register it's in can be used in
		     mode MODE.  */
		  && (REG_CAN_CHANGE_MODE_P
		      (REGNO (reg_last_reload_reg[regno]),
		       GET_MODE (reg_last_reload_reg[regno]),
		       mode)))
		{
		  enum reg_class rclass = rld[r].rclass, last_class;
		  rtx last_reg = reg_last_reload_reg[regno];

		  i = REGNO (last_reg);
		  byte = compute_reload_subreg_offset (mode,
						       subreg,
						       GET_MODE (last_reg));
		  i += subreg_regno_offset (i, GET_MODE (last_reg), byte, mode);
		  last_class = REGNO_REG_CLASS (i);

		  if (reg_reloaded_contents[i] == regno
		      && TEST_HARD_REG_BIT (reg_reloaded_valid, i)
		      && targetm.hard_regno_mode_ok (i, rld[r].mode)
		      && (TEST_HARD_REG_BIT (reg_class_contents[(int) rclass], i)
			  /* Even if we can't use this register as a reload
			     register, we might use it for reload_override_in,
			     if copying it to the desired class is cheap
			     enough.  */
			  || ((register_move_cost (mode, last_class, rclass)
			       < memory_move_cost (mode, rclass, true))
			      && (secondary_reload_class (1, rclass, mode,
							  last_reg)
				  == NO_REGS)
			      && !(targetm.secondary_memory_needed
				   (mode, last_class, rclass))))
		      && (rld[r].nregs == max_group_size
			  || ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class],
						  i))
		      && free_for_value_p (i, rld[r].mode, 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, rld[r].mode);
		      int k;

		      for (k = 1; k < nr; k++)
			if (reg_reloaded_contents[i + k] != regno
			    || ! TEST_HARD_REG_BIT (reg_reloaded_valid, i + k))
			  break;

		      if (k == nr)
			{
			  int i1;
			  int bad_for_class;

			  last_reg = (GET_MODE (last_reg) == mode
				      ? last_reg : gen_rtx_REG (mode, i));

			  bad_for_class = 0;
			  for (k = 0; k < nr; k++)
			    bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].rclass],
								  i+k);

			  /* We found a register that contains the
			     value we need.  If this register is the
			     same as an `earlyclobber' operand of the
			     current insn, just mark it as a place to
			     reload from since we can't use it as the
			     reload register itself.  */

			  for (i1 = 0; i1 < n_earlyclobbers; i1++)
			    if (reg_overlap_mentioned_for_reload_p
				(reg_last_reload_reg[regno],
				 reload_earlyclobbers[i1]))
			      break;

			  if (i1 != n_earlyclobbers
			      || ! (free_for_value_p (i, rld[r].mode,
						      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)
				  && rld[r].out
				  && ! TEST_HARD_REG_BIT (reg_reloaded_dead, i))
			      /* Don't clobber the frame pointer.  */
			      || (i == HARD_FRAME_POINTER_REGNUM
				  && frame_pointer_needed
				  && rld[r].out)
			      /* Don't really use the inherited spill reg
				 if we need it wider than we've got it.  */
			      || paradoxical_subreg_p (rld[r].mode, mode)
			      || bad_for_class

			      /* If find_reloads chose reload_out as reload
				 register, stay with it - that leaves the
				 inherited register for subsequent reloads.  */
			      || (rld[r].out && rld[r].reg_rtx
				  && rtx_equal_p (rld[r].out, rld[r].reg_rtx)))
			    {
			      if (! rld[r].optional)
				{
				  reload_override_in[r] = last_reg;
				  reload_inheritance_insn[r]
				    = reg_reloaded_insn[i];
				}
			    }
			  else
			    {
			      int k;
			      /* We can use this as a reload reg.  */
			      /* Mark the register as in use for this part of
				 the insn.  */
			      mark_reload_reg_in_use (i,
						      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];
			      reload_spill_index[r] = i;
			      for (k = 0; k < nr; k++)
				SET_HARD_REG_BIT (reload_reg_used_for_inherit,
						  i + k);
			    }
			}
		    }
		}
	    }

	  /* Here's another way to see if the value is already lying around.  */
	  if (inheritance
	      && rld[r].in != 0
	      && ! reload_inherited[r]
	      && rld[r].out == 0
	      && (CONSTANT_P (rld[r].in)
		  || GET_CODE (rld[r].in) == PLUS
		  || REG_P (rld[r].in)
		  || MEM_P (rld[r].in))
	      && (rld[r].nregs == max_group_size
		  || ! reg_classes_intersect_p (rld[r].rclass, group_class)))
	    search_equiv = rld[r].in;

	  if (search_equiv)
	    {
	      rtx equiv
		= find_equiv_reg (search_equiv, insn, rld[r].rclass,
				  -1, NULL, 0, rld[r].mode);
	      int regno = 0;

	      if (equiv != 0)
		{
		  if (REG_P (equiv))
		    regno = REGNO (equiv);
		  else
		    {
		      /* This must be a SUBREG of a hard register.
			 Make a new REG since this might be used in an
			 address and not all machines support SUBREGs
			 there.  */
		      gcc_assert (GET_CODE (equiv) == SUBREG);
		      regno = subreg_regno (equiv);
		      equiv = gen_rtx_REG (rld[r].mode, regno);
		      /* If we choose EQUIV as the reload register, but the
			 loop below decides to cancel the inheritance, we'll
			 end up reloading EQUIV in rld[r].mode, not the mode
			 it had originally.  That isn't safe when EQUIV isn't
			 available as a spill register since its value might
			 still be live at this point.  */
		      for (i = regno; i < regno + (int) rld[r].nregs; i++)
			if (TEST_HARD_REG_BIT (reload_reg_unavailable, i))
			  equiv = 0;
		    }
		}

	      /* If we found a spill reg, reject it unless it is free
		 and of the desired class.  */
	      if (equiv != 0)
		{
		  int regs_used = 0;
		  int bad_for_class = 0;
		  int max_regno = regno + rld[r].nregs;

		  for (i = regno; i < max_regno; i++)
		    {
		      regs_used |= TEST_HARD_REG_BIT (reload_reg_used_at_all,
						      i);
		      bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].rclass],
							   i);
		    }

		  if ((regs_used
		       && ! free_for_value_p (regno, rld[r].mode,
					      rld[r].opnum, rld[r].when_needed,
					      rld[r].in, rld[r].out, r, 1))
		      || bad_for_class)
		    equiv = 0;
		}

	      if (equiv != 0
		  && !targetm.hard_regno_mode_ok (regno, rld[r].mode))
		equiv = 0;

	      /* We found a register that contains the value we need.
		 If this register is the same as an `earlyclobber' operand
		 of the current insn, just mark it as a place to reload from
		 since we can't use it as the reload register itself.  */

	      if (equiv != 0)
		for (i = 0; i < n_earlyclobbers; i++)
		  if (reg_overlap_mentioned_for_reload_p (equiv,
							  reload_earlyclobbers[i]))
		    {
		      if (! rld[r].optional)
			reload_override_in[r] = equiv;
		      equiv = 0;
		      break;
		    }

	      /* If the equiv register we have found is explicitly clobbered
		 in the current insn, it depends on the reload type if we
		 can use it, use it for reload_override_in, or not at all.
		 In particular, we then can't use EQUIV for a
		 RELOAD_FOR_OUTPUT_ADDRESS reload.  */

	      if (equiv != 0)
		{
		  if (regno_clobbered_p (regno, insn, rld[r].mode, 2))
		    switch (rld[r].when_needed)
		      {
		      case RELOAD_FOR_OTHER_ADDRESS:
		      case RELOAD_FOR_INPADDR_ADDRESS:
		      case RELOAD_FOR_INPUT_ADDRESS:
		      case RELOAD_FOR_OPADDR_ADDR:
			break;
		      case RELOAD_OTHER:
		      case RELOAD_FOR_INPUT:
		      case RELOAD_FOR_OPERAND_ADDRESS:
			if (! rld[r].optional)
			  reload_override_in[r] = equiv;
			/* Fall through.  */
		      default:
			equiv = 0;
			break;
		      }
		  else if (regno_clobbered_p (regno, insn, rld[r].mode, 1))
		    switch (rld[r].when_needed)
		      {
		      case RELOAD_FOR_OTHER_ADDRESS:
		      case RELOAD_FOR_INPADDR_ADDRESS:
		      case RELOAD_FOR_INPUT_ADDRESS:
		      case RELOAD_FOR_OPADDR_ADDR:
		      case RELOAD_FOR_OPERAND_ADDRESS:
		      case RELOAD_FOR_INPUT:
			break;
		      case RELOAD_OTHER:
			if (! rld[r].optional)
			  reload_override_in[r] = equiv;
			/* Fall through.  */
		      default:
			equiv = 0;
			break;
		      }
		}

	      /* If we found an equivalent reg, say no code need be generated
		 to load it, and use it as our reload reg.  */
	      if (equiv != 0
		  && (regno != HARD_FRAME_POINTER_REGNUM
		      || !frame_pointer_needed))
		{
		  int nr = hard_regno_nregs (regno, rld[r].mode);
		  int k;
		  rld[r].reg_rtx = equiv;
		  reload_spill_index[r] = regno;
		  reload_inherited[r] = 1;

		  /* If reg_reloaded_valid is not set for this register,
		     there might be a stale spill_reg_store lying around.
		     We must clear it, since otherwise emit_reload_insns
		     might delete the store.  */
		  if (! TEST_HARD_REG_BIT (reg_reloaded_valid, regno))
		    spill_reg_store[regno] = NULL;
		  /* If any of the hard registers in EQUIV are spill
		     registers, mark them as in use for this insn.  */
		  for (k = 0; k < nr; k++)
		    {
		      i = spill_reg_order[regno + k];
		      if (i >= 0)
			{
			  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);
			}
		    }
		}
	    }

	  /* If we found a register to use already, or if this is an optional
	     reload, we are done.  */
	  if (rld[r].reg_rtx != 0 || rld[r].optional != 0)
	    continue;

#if 0
	  /* No longer needed for correct operation.  Might or might
	     not give better code on the average.  Want to experiment?  */

	  /* See if there is a later reload that has a class different from our
	     class that intersects our class or that requires less register
	     than our reload.  If so, we must allocate a register to this
	     reload now, since that reload might inherit a previous reload
	     and take the only available register in our class.  Don't do this
	     for optional reloads since they will force all previous reloads
	     to be allocated.  Also don't do this for reloads that have been
	     turned off.  */

	  for (i = j + 1; i < n_reloads; i++)
	    {
	      int s = reload_order[i];

	      if ((rld[s].in == 0 && rld[s].out == 0
		   && ! rld[s].secondary_p)
		  || rld[s].optional)
		continue;

	      if ((rld[s].rclass != rld[r].rclass
		   && reg_classes_intersect_p (rld[r].rclass,
					       rld[s].rclass))
		  || rld[s].nregs < rld[r].nregs)
		break;
	    }

	  if (i == n_reloads)
	    continue;

	  allocate_reload_reg (chain, r, j == n_reloads - 1);
#endif
	}

      /* Now allocate reload registers for anything non-optional that
	 didn't get one yet.  */
      for (j = 0; j < n_reloads; j++)
	{
	  int r = reload_order[j];

	  /* Ignore reloads that got marked inoperative.  */
	  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 (rld[r].reg_rtx != 0 || rld[r].optional)
	    continue;

	  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)
	{
	  win = 1;
	  break;
	}

      /* Loop around and try without any inheritance.  */
    }

  if (! win)
    {
      /* First undo everything done by the failed attempt
	 to allocate with inheritance.  */
      choose_reload_regs_init (chain, save_reload_reg_rtx);

      /* Some sanity tests to verify that the reloads found in the first
	 pass are identical to the ones we have now.  */
      gcc_assert (chain->n_reloads == n_reloads);

      for (i = 0; i < n_reloads; i++)
	{
	  if (chain->rld[i].regno < 0 || chain->rld[i].reg_rtx != 0)
	    continue;
	  gcc_assert (chain->rld[i].when_needed == rld[i].when_needed);
	  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);
	}
    }

  /* If we thought we could inherit a reload, because it seemed that
     nothing else wanted the same reload register earlier in the insn,
     verify that assumption, now that all reloads have been assigned.
     Likewise for reloads where reload_override_in has been set.  */

  /* If doing expensive optimizations, do one preliminary pass that doesn't
     cancel any inheritance, but removes reloads that have been needed only
     for reloads that we know can be inherited.  */
  for (pass = flag_expensive_optimizations; pass >= 0; pass--)
    {
      for (j = 0; j < n_reloads; j++)
	{
	  int r = reload_order[j];
	  rtx check_reg;
	  rtx tem;
	  if (reload_inherited[r] && rld[r].reg_rtx)
	    check_reg = rld[r].reg_rtx;
	  else if (reload_override_in[r]
		   && (REG_P (reload_override_in[r])
		       || GET_CODE (reload_override_in[r]) == SUBREG))
	    check_reg = reload_override_in[r];
	  else
	    continue;
	  if (! free_for_value_p (true_regnum (check_reg), rld[r].mode,
				  rld[r].opnum, rld[r].when_needed, rld[r].in,
				  (reload_inherited[r]
				   ? rld[r].out : const0_rtx),
				  r, 1))
	    {
	      if (pass)
		continue;
	      reload_inherited[r] = 0;
	      reload_override_in[r] = 0;
	    }
	  /* If we can inherit a RELOAD_FOR_INPUT, or can use a
	     reload_override_in, then we do not need its related
	     RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS reloads;
	     likewise for other reload types.
	     We handle this by removing a reload when its only replacement
	     is mentioned in reload_in of the reload we are going to inherit.
	     A special case are auto_inc expressions; even if the input is
	     inherited, we still need the address for the output.  We can
	     recognize them because they have RELOAD_OUT set to RELOAD_IN.
	     If we succeeded 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 (rld[r].in
		   && rld[r].out != rld[r].in
		   && remove_address_replacements (rld[r].in))
	    {
	      if (pass)
	        pass = 2;
	    }
	  /* If we needed a memory location for the reload, we also have to
	     remove its related reloads.  */
	  else if (rld[r].in
		   && rld[r].out != rld[r].in
		   && (tem = replaced_subreg (rld[r].in), REG_P (tem))		   
		   && REGNO (tem) < FIRST_PSEUDO_REGISTER
		   && (targetm.secondary_memory_needed
		       (rld[r].inmode, REGNO_REG_CLASS (REGNO (tem)),
			rld[r].rclass))
		   && remove_address_replacements
		      (get_secondary_mem (tem, rld[r].inmode, rld[r].opnum,
					  rld[r].when_needed)))
	    {
	      if (pass)
	        pass = 2;
	    }
	}
    }

  /* Now that reload_override_in is known valid,
     actually override reload_in.  */
  for (j = 0; j < n_reloads; j++)
    if (reload_override_in[j])
      rld[j].in = reload_override_in[j];

  /* If this reload won't be done because it has been canceled 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 (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 (rld[j].reg_rtx);

	if (spill_reg_order[regno] >= 0)
	  clear_reload_reg_in_use (regno, rld[j].opnum,
				   rld[j].when_needed, rld[j].mode);
	rld[j].reg_rtx = 0;
	reload_spill_index[j] = -1;
      }

  /* Record which pseudos and which spill regs have output reloads.  */
  for (j = 0; j < n_reloads; j++)
    {
      int r = reload_order[j];

      i = reload_spill_index[r];

      /* I is nonneg if this reload uses a register.
	 If rld[r].reg_rtx is 0, this is an optional reload
	 that we opted to ignore.  */
      if (rld[r].out_reg != 0 && REG_P (rld[r].out_reg)
	  && rld[r].reg_rtx != 0)
	{
	  int nregno = REGNO (rld[r].out_reg);
	  int nr = 1;

	  if (nregno < FIRST_PSEUDO_REGISTER)
	    nr = hard_regno_nregs (nregno, rld[r].mode);

	  while (--nr >= 0)
	    SET_REGNO_REG_SET (&reg_has_output_reload,
			       nregno + nr);

	  if (i >= 0)
	    add_to_hard_reg_set (&reg_is_output_reload, rld[r].mode, i);

	  gcc_assert (rld[r].when_needed == RELOAD_OTHER
		      || rld[r].when_needed == RELOAD_FOR_OUTPUT
		      || rld[r].when_needed == RELOAD_FOR_INSN);
	}
    }
}

/* Deallocate the reload register for reload R.  This is called from
   remove_address_replacements.  */

void
deallocate_reload_reg (int r)
{
  int regno;

  if (! rld[r].reg_rtx)
    return;
  regno = true_regnum (rld[r].reg_rtx);
  rld[r].reg_rtx = 0;
  if (spill_reg_order[regno] >= 0)
    clear_reload_reg_in_use (regno, rld[r].opnum, rld[r].when_needed,
			     rld[r].mode);
  reload_spill_index[r] = -1;
}

/* These arrays are filled by emit_reload_insns and its subroutines.  */
static rtx_insn *input_reload_insns[MAX_RECOG_OPERANDS];
static rtx_insn *other_input_address_reload_insns = 0;
static rtx_insn *other_input_reload_insns = 0;
static rtx_insn *input_address_reload_insns[MAX_RECOG_OPERANDS];
static rtx_insn *inpaddr_address_reload_insns[MAX_RECOG_OPERANDS];
static rtx_insn *output_reload_insns[MAX_RECOG_OPERANDS];
static rtx_insn *output_address_reload_insns[MAX_RECOG_OPERANDS];
static rtx_insn *outaddr_address_reload_insns[MAX_RECOG_OPERANDS];
static rtx_insn *operand_reload_insns = 0;
static rtx_insn *other_operand_reload_insns = 0;
static rtx_insn *other_output_reload_insns[MAX_RECOG_OPERANDS];

/* Values to be put in spill_reg_store are put here first.  Instructions
   must only be placed here if the associated reload register reaches
   the end of the instruction's reload sequence.  */
static rtx_insn *new_spill_reg_store[FIRST_PSEUDO_REGISTER];
static HARD_REG_SET reg_reloaded_died;

/* Check if *RELOAD_REG is suitable as an intermediate or scratch register
   of class NEW_CLASS with mode NEW_MODE.  Or alternatively, if alt_reload_reg
   is nonzero, if that is suitable.  On success, change *RELOAD_REG to the
   adjusted register, and return true.  Otherwise, return false.  */
static bool
reload_adjust_reg_for_temp (rtx *reload_reg, rtx alt_reload_reg,
			    enum reg_class new_class,
			    machine_mode new_mode)

{
  rtx reg;

  for (reg = *reload_reg; reg; reg = alt_reload_reg, alt_reload_reg = 0)
    {
      unsigned regno = REGNO (reg);

      if (!TEST_HARD_REG_BIT (reg_class_contents[(int) new_class], regno))
	continue;
      if (GET_MODE (reg) != new_mode)
	{
	  if (!targetm.hard_regno_mode_ok (regno, new_mode))
	    continue;
	  if (hard_regno_nregs (regno, new_mode) > REG_NREGS (reg))
	    continue;
	  reg = reload_adjust_reg_for_mode (reg, new_mode);
	}
      *reload_reg = reg;
      return true;
    }
  return false;
}

/* Check if *RELOAD_REG is suitable as a scratch register for the reload
   pattern with insn_code ICODE, or alternatively, if alt_reload_reg is
   nonzero, if that is suitable.  On success, change *RELOAD_REG to the
   adjusted register, and return true.  Otherwise, return false.  */
static bool
reload_adjust_reg_for_icode (rtx *reload_reg, rtx alt_reload_reg,
			     enum insn_code icode)

{
  enum reg_class new_class = scratch_reload_class (icode);
  machine_mode new_mode = insn_data[(int) icode].operand[2].mode;

  return reload_adjust_reg_for_temp (reload_reg, alt_reload_reg,
				     new_class, new_mode);
}

/* Generate insns to perform reload RL, which is for the insn in CHAIN and
   has the number J.  OLD contains the value to be used as input.  */

static void
emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
			 rtx old, int j)
{
  rtx_insn *insn = chain->insn;
  rtx reloadreg;
  rtx oldequiv_reg = 0;
  rtx oldequiv = 0;
  int special = 0;
  machine_mode mode;
  rtx_insn **where;

  /* delete_output_reload is only invoked properly if old contains
     the original pseudo register.  Since this is replaced with a
     hard reg when RELOAD_OVERRIDE_IN is set, see if we can
     find the pseudo in RELOAD_IN_REG.  This is also used to
     determine whether a secondary reload is needed.  */
  if (reload_override_in[j]
      && (REG_P (rl->in_reg)
	  || (GET_CODE (rl->in_reg) == SUBREG
	      && REG_P (SUBREG_REG (rl->in_reg)))))
    {
      oldequiv = old;
      old = rl->in_reg;
    }
  if (oldequiv == 0)
    oldequiv = old;
  else if (REG_P (oldequiv))
    oldequiv_reg = oldequiv;
  else if (GET_CODE (oldequiv) == SUBREG)
    oldequiv_reg = SUBREG_REG (oldequiv);

  reloadreg = reload_reg_rtx_for_input[j];
  mode = GET_MODE (reloadreg);

  /* If we are reloading from a register that was recently stored in
     with an output-reload, see if we can prove there was
     actually no need to store the old value in it.  */

  if (optimize && REG_P (oldequiv)
      && REGNO (oldequiv) < FIRST_PSEUDO_REGISTER
      && spill_reg_store[REGNO (oldequiv)]
      && REG_P (old)
      && (dead_or_set_p (insn, spill_reg_stored_to[REGNO (oldequiv)])
	  || rtx_equal_p (spill_reg_stored_to[REGNO (oldequiv)],
			  rl->out_reg)))
    delete_output_reload (insn, j, REGNO (oldequiv), reloadreg);

  /* Encapsulate OLDEQUIV into the reload mode, then load RELOADREG from
     OLDEQUIV.  */

  while (GET_CODE (oldequiv) == SUBREG && GET_MODE (oldequiv) != mode)
    oldequiv = SUBREG_REG (oldequiv);
  if (GET_MODE (oldequiv) != VOIDmode
      && mode != GET_MODE (oldequiv))
    oldequiv = gen_lowpart_SUBREG (mode, oldequiv);

  /* Switch to the right place to emit the reload insns.  */
  switch (rl->when_needed)
    {
    case RELOAD_OTHER:
      where = &other_input_reload_insns;
      break;
    case RELOAD_FOR_INPUT:
      where = &input_reload_insns[rl->opnum];
      break;
    case RELOAD_FOR_INPUT_ADDRESS:
      where = &input_address_reload_insns[rl->opnum];
      break;
    case RELOAD_FOR_INPADDR_ADDRESS:
      where = &inpaddr_address_reload_insns[rl->opnum];
      break;
    case RELOAD_FOR_OUTPUT_ADDRESS:
      where = &output_address_reload_insns[rl->opnum];
      break;
    case RELOAD_FOR_OUTADDR_ADDRESS:
      where = &outaddr_address_reload_insns[rl->opnum];
      break;
    case RELOAD_FOR_OPERAND_ADDRESS:
      where = &operand_reload_insns;
      break;
    case RELOAD_FOR_OPADDR_ADDR:
      where = &other_operand_reload_insns;
      break;
    case RELOAD_FOR_OTHER_ADDRESS:
      where = &other_input_address_reload_insns;
      break;
    default:
      gcc_unreachable ();
    }

  push_to_sequence (*where);

  /* Auto-increment addresses must be reloaded in a special way.  */
  if (rl->out && ! rl->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.  */
      gcc_assert (rl->secondary_in_reload < 0);

      if (reload_inherited[j])
	oldequiv = reloadreg;

      old = XEXP (rl->in_reg, 0);

      /* Prevent normal processing of this reload.  */
      special = 1;
      /* Output a special code sequence for this case.  */
      inc_for_reload (reloadreg, oldequiv, rl->out, rl->inc);
    }

  /* If we are reloading a pseudo-register that was set by the previous
     insn, see if we can get rid of that pseudo-register entirely
     by redirecting the previous insn into our reload register.  */

  else if (optimize && REG_P (old)
	   && REGNO (old) >= FIRST_PSEUDO_REGISTER
	   && dead_or_set_p (insn, old)
	   /* This is unsafe if some other reload
	      uses the same reg first.  */
	   && ! conflicts_with_override (reloadreg)
	   && free_for_value_p (REGNO (reloadreg), rl->mode, rl->opnum,
				rl->when_needed, old, rl->out, j, 0))
    {
      rtx_insn *temp = PREV_INSN (insn);
      while (temp && (NOTE_P (temp) || DEBUG_INSN_P (temp)))
	temp = PREV_INSN (temp);
      if (temp
	  && NONJUMP_INSN_P (temp)
	  && GET_CODE (PATTERN (temp)) == SET
	  && SET_DEST (PATTERN (temp)) == old
	  /* Make sure we can access insn_operand_constraint.  */
	  && asm_noperands (PATTERN (temp)) < 0
	  /* This is unsafe if operand occurs more than once in current
	     insn.  Perhaps some occurrences aren't reloaded.  */
	  && count_occurrences (PATTERN (insn), old, 0) == 1)
	{
	  rtx old = SET_DEST (PATTERN (temp));
	  /* Store into the reload register instead of the pseudo.  */
	  SET_DEST (PATTERN (temp)) = reloadreg;

	  /* Verify that resulting insn is valid. 

	     Note that we have replaced the destination of TEMP with
	     RELOADREG.  If TEMP references RELOADREG within an
	     autoincrement addressing mode, then the resulting insn
	     is ill-formed and we must reject this optimization.  */
	  extract_insn (temp);
	  if (constrain_operands (1, get_enabled_alternatives (temp))
	      && (!AUTO_INC_DEC || ! find_reg_note (temp, REG_INC, reloadreg)))
	    {
	      /* If the previous insn is an output reload, the source is
		 a reload register, and its spill_reg_store entry will
		 contain the previous destination.  This is now
		 invalid.  */
	      if (REG_P (SET_SRC (PATTERN (temp)))
		  && REGNO (SET_SRC (PATTERN (temp))) < FIRST_PSEUDO_REGISTER)
		{
		  spill_reg_store[REGNO (SET_SRC (PATTERN (temp)))] = 0;
		  spill_reg_stored_to[REGNO (SET_SRC (PATTERN (temp)))] = 0;
		}

	      /* If these are the only uses of the pseudo reg,
		 pretend for GDB it lives in the reload reg we used.  */
	      if (REG_N_DEATHS (REGNO (old)) == 1
		  && REG_N_SETS (REGNO (old)) == 1)
		{
		  reg_renumber[REGNO (old)] = REGNO (reloadreg);
		  if (ira_conflicts_p)
		    /* Inform IRA about the change.  */
		    ira_mark_allocation_change (REGNO (old));
		  alter_reg (REGNO (old), -1, false);
		}
	      special = 1;

	      /* Adjust any debug insns between temp and insn.  */
	      while ((temp = NEXT_INSN (temp)) != insn)
		if (DEBUG_BIND_INSN_P (temp))
		  INSN_VAR_LOCATION_LOC (temp)
		    = simplify_replace_rtx (INSN_VAR_LOCATION_LOC (temp),
					    old, reloadreg);
		else
		  gcc_assert (DEBUG_INSN_P (temp) || NOTE_P (temp));
	    }
	  else
	    {
	      SET_DEST (PATTERN (temp)) = old;
	    }
	}
    }

  /* We can't do that, so output an insn to load RELOADREG.  */

  /* If we have a secondary reload, pick up the secondary register
     and icode, if any.  If OLDEQUIV and OLD are different or
     if this is an in-out reload, recompute whether or not we
     still need a secondary register and what the icode should
     be.  If we still need a secondary register and the class or
     icode is different, go back to reloading from OLD if using
     OLDEQUIV means that we got the wrong type of register.  We
     cannot have different class or icode due to an in-out reload
     because we don't make such reloads when both the input and
     output need secondary reload registers.  */

  if (! special && rl->secondary_in_reload >= 0)
    {
      rtx second_reload_reg = 0;
      rtx third_reload_reg = 0;
      int secondary_reload = rl->secondary_in_reload;
      rtx real_oldequiv = oldequiv;
      rtx real_old = old;
      rtx tmp;
      enum insn_code icode;
      enum insn_code tertiary_icode = CODE_FOR_nothing;

      /* If OLDEQUIV is a pseudo with a MEM, get the real MEM
	 and similarly for OLD.
	 See comments in get_secondary_reload in reload.c.  */
      /* If it is a pseudo that cannot be replaced with its
	 equivalent MEM, we must fall back to reload_in, which
	 will have all the necessary substitutions registered.
	 Likewise for a pseudo that can't be replaced with its
	 equivalent constant.

	 Take extra care for subregs of such pseudos.  Note that
	 we cannot use reg_equiv_mem in this case because it is
	 not in the right mode.  */

      tmp = oldequiv;
      if (GET_CODE (tmp) == SUBREG)
	tmp = SUBREG_REG (tmp);
      if (REG_P (tmp)
	  && REGNO (tmp) >= FIRST_PSEUDO_REGISTER
	  && (reg_equiv_memory_loc (REGNO (tmp)) != 0
	      || reg_equiv_constant (REGNO (tmp)) != 0))
	{
	  if (! reg_equiv_mem (REGNO (tmp))
	      || num_not_at_initial_offset
	      || GET_CODE (oldequiv) == SUBREG)
	    real_oldequiv = rl->in;
	  else
	    real_oldequiv = reg_equiv_mem (REGNO (tmp));
	}

      tmp = old;
      if (GET_CODE (tmp) == SUBREG)
	tmp = SUBREG_REG (tmp);
      if (REG_P (tmp)
	  && REGNO (tmp) >= FIRST_PSEUDO_REGISTER
	  && (reg_equiv_memory_loc (REGNO (tmp)) != 0
	      || reg_equiv_constant (REGNO (tmp)) != 0))
	{
	  if (! reg_equiv_mem (REGNO (tmp))
	      || num_not_at_initial_offset
	      || GET_CODE (old) == SUBREG)
	    real_old = rl->in;
	  else
	    real_old = reg_equiv_mem (REGNO (tmp));
	}

      second_reload_reg = rld[secondary_reload].reg_rtx;
      if (rld[secondary_reload].secondary_in_reload >= 0)
	{
	  int tertiary_reload = rld[secondary_reload].secondary_in_reload;

	  third_reload_reg = rld[tertiary_reload].reg_rtx;
	  tertiary_icode = rld[secondary_reload].secondary_in_icode;
	  /* We'd have to add more code for quartary reloads.  */
	  gcc_assert (rld[tertiary_reload].secondary_in_reload < 0);
	}
      icode = rl->secondary_in_icode;

      if ((old != oldequiv && ! rtx_equal_p (old, oldequiv))
	  || (rl->in != 0 && rl->out != 0))
	{
	  secondary_reload_info sri, sri2;
	  enum reg_class new_class, new_t_class;

	  sri.icode = CODE_FOR_nothing;
	  sri.prev_sri = NULL;
	  new_class
	    = (enum reg_class) targetm.secondary_reload (1, real_oldequiv,
							 rl->rclass, mode,
							 &sri);

	  if (new_class == NO_REGS && sri.icode == CODE_FOR_nothing)
	    second_reload_reg = 0;
	  else if (new_class == NO_REGS)
	    {
	      if (reload_adjust_reg_for_icode (&second_reload_reg,
					       third_reload_reg,
					       (enum insn_code) sri.icode))
		{
		  icode = (enum insn_code) sri.icode;
		  third_reload_reg = 0;
		}
	      else
		{
		  oldequiv = old;
		  real_oldequiv = real_old;
		}
	    }
	  else if (sri.icode != CODE_FOR_nothing)
	    /* We currently lack a way to express this in reloads.  */
	    gcc_unreachable ();
	  else
	    {
	      sri2.icode = CODE_FOR_nothing;
	      sri2.prev_sri = &sri;
	      new_t_class
		= (enum reg_class) targetm.secondary_reload (1, real_oldequiv,
							     new_class, mode,
							     &sri);
	      if (new_t_class == NO_REGS && sri2.icode == CODE_FOR_nothing)
		{
		  if (reload_adjust_reg_for_temp (&second_reload_reg,
						  third_reload_reg,
						  new_class, mode))
		    {
		      third_reload_reg = 0;
		      tertiary_icode = (enum insn_code) sri2.icode;
		    }
		  else
		    {
		      oldequiv = old;
		      real_oldequiv = real_old;
		    }
		}
	      else if (new_t_class == NO_REGS && sri2.icode != CODE_FOR_nothing)
		{
		  rtx intermediate = second_reload_reg;

		  if (reload_adjust_reg_for_temp (&intermediate, NULL,
						  new_class, mode)
		      && reload_adjust_reg_for_icode (&third_reload_reg, NULL,
						      ((enum insn_code)
						       sri2.icode)))
		    {
		      second_reload_reg = intermediate;
		      tertiary_icode = (enum insn_code) sri2.icode;
		    }
		  else
		    {
		      oldequiv = old;
		      real_oldequiv = real_old;
		    }
		}
	      else if (new_t_class != NO_REGS && sri2.icode == CODE_FOR_nothing)
		{
		  rtx intermediate = second_reload_reg;

		  if (reload_adjust_reg_for_temp (&intermediate, NULL,
						  new_class, mode)
		      && reload_adjust_reg_for_temp (&third_reload_reg, NULL,
						      new_t_class, mode))
		    {
		      second_reload_reg = intermediate;
		      tertiary_icode = (enum insn_code) sri2.icode;
		    }
		  else
		    {
		      oldequiv = old;
		      real_oldequiv = real_old;
		    }
		}
	      else
		{
		  /* This could be handled more intelligently too.  */
		  oldequiv = old;
		  real_oldequiv = real_old;
		}
	    }
	}

      /* If we still need a secondary reload register, check
	 to see if it is being used as a scratch or intermediate
	 register and generate code appropriately.  If we need
	 a scratch register, use REAL_OLDEQUIV since the form of
	 the insn may depend on the actual address if it is
	 a MEM.  */

      if (second_reload_reg)
	{
	  if (icode != CODE_FOR_nothing)
	    {
	      /* We'd have to add extra code to handle this case.  */
	      gcc_assert (!third_reload_reg);

	      emit_insn (GEN_FCN (icode) (reloadreg, real_oldequiv,
					  second_reload_reg));
	      special = 1;
	    }
	  else
	    {
	      /* See if we need a scratch register to load the
		 intermediate register (a tertiary reload).  */
	      if (tertiary_icode != CODE_FOR_nothing)
		{
		  emit_insn ((GEN_FCN (tertiary_icode)
			      (second_reload_reg, real_oldequiv,
			       third_reload_reg)));
		}
	      else if (third_reload_reg)
		{
		  gen_reload (third_reload_reg, real_oldequiv,
			      rl->opnum,
			      rl->when_needed);
		  gen_reload (second_reload_reg, third_reload_reg,
			      rl->opnum,
			      rl->when_needed);
		}
	      else
		gen_reload (second_reload_reg, real_oldequiv,
			    rl->opnum,
			    rl->when_needed);

	      oldequiv = second_reload_reg;
	    }
	}
    }

  if (! special && ! rtx_equal_p (reloadreg, oldequiv))
    {
      rtx real_oldequiv = oldequiv;

      if ((REG_P (oldequiv)
	   && REGNO (oldequiv) >= FIRST_PSEUDO_REGISTER
	   && (reg_equiv_memory_loc (REGNO (oldequiv)) != 0
	       || reg_equiv_constant (REGNO (oldequiv)) != 0))
	  || (GET_CODE (oldequiv) == SUBREG
	      && REG_P (SUBREG_REG (oldequiv))
	      && (REGNO (SUBREG_REG (oldequiv))
		  >= FIRST_PSEUDO_REGISTER)
	      && ((reg_equiv_memory_loc (REGNO (SUBREG_REG (oldequiv))) != 0)
		  || (reg_equiv_constant (REGNO (SUBREG_REG (oldequiv))) != 0)))
	  || (CONSTANT_P (oldequiv)
	      && (targetm.preferred_reload_class (oldequiv,
						  REGNO_REG_CLASS (REGNO (reloadreg)))
		  == NO_REGS)))
	real_oldequiv = rl->in;
      gen_reload (reloadreg, real_oldequiv, rl->opnum,
		  rl->when_needed);
    }

  if (cfun->can_throw_non_call_exceptions)
    copy_reg_eh_region_note_forward (insn, get_insns (), NULL);

  /* End this sequence.  */
  *where = get_insns ();
  end_sequence ();

  /* Update reload_override_in so that delete_address_reloads_1
     can see the actual register usage.  */
  if (oldequiv_reg)
    reload_override_in[j] = oldequiv;
}

/* Generate insns to for the output reload RL, which is for the insn described
   by CHAIN and has the number J.  */
static void
emit_output_reload_insns (struct insn_chain *chain, struct reload *rl,
			  int j)
{
  rtx reloadreg;
  rtx_insn *insn = chain->insn;
  int special = 0;
  rtx old = rl->out;
  machine_mode mode;
  rtx_insn *p;
  rtx rl_reg_rtx;

  if (rl->when_needed == RELOAD_OTHER)
    start_sequence ();
  else
    push_to_sequence (output_reload_insns[rl->opnum]);

  rl_reg_rtx = reload_reg_rtx_for_output[j];
  mode = GET_MODE (rl_reg_rtx);

  reloadreg = rl_reg_rtx;

  /* If we need two reload regs, set RELOADREG to the intermediate
     one, since it will be stored into OLD.  We might need a secondary
     register only for an input reload, so check again here.  */

  if (rl->secondary_out_reload >= 0)
    {
      rtx real_old = old;
      int secondary_reload = rl->secondary_out_reload;
      int tertiary_reload = rld[secondary_reload].secondary_out_reload;

      if (REG_P (old) && REGNO (old) >= FIRST_PSEUDO_REGISTER
	  && reg_equiv_mem (REGNO (old)) != 0)
	real_old = reg_equiv_mem (REGNO (old));

      if (secondary_reload_class (0, rl->rclass, mode, real_old) != NO_REGS)
	{
	  rtx second_reloadreg = reloadreg;
	  reloadreg = rld[secondary_reload].reg_rtx;

	  /* See if RELOADREG is to be used as a scratch register
	     or as an intermediate register.  */
	  if (rl->secondary_out_icode != CODE_FOR_nothing)
	    {
	      /* We'd have to add extra code to handle this case.  */
	      gcc_assert (tertiary_reload < 0);

	      emit_insn ((GEN_FCN (rl->secondary_out_icode)
			  (real_old, second_reloadreg, reloadreg)));
	      special = 1;
	    }
	  else
	    {
	      /* See if we need both a scratch and intermediate reload
		 register.  */

	      enum insn_code tertiary_icode
		= rld[secondary_reload].secondary_out_icode;

	      /* We'd have to add more code for quartary reloads.  */
	      gcc_assert (tertiary_reload < 0
			  || rld[tertiary_reload].secondary_out_reload < 0);

	      if (GET_MODE (reloadreg) != mode)
		reloadreg = reload_adjust_reg_for_mode (reloadreg, mode);

	      if (tertiary_icode != CODE_FOR_nothing)
		{
		  rtx third_reloadreg = rld[tertiary_reload].reg_rtx;

		  /* Copy primary reload reg to secondary reload reg.
		     (Note that these have been swapped above, then
		     secondary reload reg to OLD using our insn.)  */

		  /* If REAL_OLD is a paradoxical SUBREG, remove it
		     and try to put the opposite SUBREG on
		     RELOADREG.  */
		  strip_paradoxical_subreg (&real_old, &reloadreg);

		  gen_reload (reloadreg, second_reloadreg,
			      rl->opnum, rl->when_needed);
		  emit_insn ((GEN_FCN (tertiary_icode)
			      (real_old, reloadreg, third_reloadreg)));
		  special = 1;
		}

	      else
		{
		  /* Copy between the reload regs here and then to
		     OUT later.  */

		  gen_reload (reloadreg, second_reloadreg,
			      rl->opnum, rl->when_needed);
		  if (tertiary_reload >= 0)
		    {
		      rtx third_reloadreg = rld[tertiary_reload].reg_rtx;

		      gen_reload (third_reloadreg, reloadreg,
				  rl->opnum, rl->when_needed);
		      reloadreg = third_reloadreg;
		    }
		}
	    }
	}
    }

  /* Output the last reload insn.  */
  if (! special)
    {
      rtx set;

      /* Don't output the last reload if OLD is not the dest of
	 INSN and is in the src and is clobbered by INSN.  */
      if (! flag_expensive_optimizations
	  || !REG_P (old)
	  || !(set = single_set (insn))
	  || rtx_equal_p (old, SET_DEST (set))
	  || !reg_mentioned_p (old, SET_SRC (set))
	  || !((REGNO (old) < FIRST_PSEUDO_REGISTER)
	       && regno_clobbered_p (REGNO (old), insn, rl->mode, 0)))
	gen_reload (old, reloadreg, rl->opnum,
		    rl->when_needed);
    }

  /* Look at all insns we emitted, just to be safe.  */
  for (p = get_insns (); p; p = NEXT_INSN (p))
    if (INSN_P (p))
      {
	rtx pat = PATTERN (p);

	/* If this output reload doesn't come from a spill reg,
	   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, NULL);

	if (reg_mentioned_p (rl_reg_rtx, pat))
	  {
	    rtx set = single_set (insn);
	    if (reload_spill_index[j] < 0
		&& set
		&& SET_SRC (set) == rl_reg_rtx)
	      {
		int src = REGNO (SET_SRC (set));

		reload_spill_index[j] = src;
		SET_HARD_REG_BIT (reg_is_output_reload, src);
		if (find_regno_note (insn, REG_DEAD, src))
		  SET_HARD_REG_BIT (reg_reloaded_died, src);
	      }
	    if (HARD_REGISTER_P (rl_reg_rtx))
	      {
		int s = rl->secondary_out_reload;
		set = single_set (p);
		/* If this reload copies only to the secondary reload
		   register, the secondary reload does the actual
		   store.  */
		if (s >= 0 && set == NULL_RTX)
		  /* We can't tell what function the secondary reload
		     has and where the actual store to the pseudo is
		     made; leave new_spill_reg_store alone.  */
		  ;
		else if (s >= 0
			 && SET_SRC (set) == rl_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 = rld[s].reg_rtx;
		    rtx_insn *next = NEXT_INSN (p);
		    rld[s].out = rl->out;
		    rld[s].out_reg = rl->out_reg;
		    set = single_set (next);
		    if (set && SET_SRC (set) == s_reg
			&& reload_reg_rtx_reaches_end_p (s_reg, s))
		      {
			SET_HARD_REG_BIT (reg_is_output_reload,
					  REGNO (s_reg));
			new_spill_reg_store[REGNO (s_reg)] = next;
		      }
		  }
		else if (reload_reg_rtx_reaches_end_p (rl_reg_rtx, j))
		  new_spill_reg_store[REGNO (rl_reg_rtx)] = p;
	      }
	  }
      }

  if (rl->when_needed == RELOAD_OTHER)
    {
      emit_insn (other_output_reload_insns[rl->opnum]);
      other_output_reload_insns[rl->opnum] = get_insns ();
    }
  else
    output_reload_insns[rl->opnum] = get_insns ();

  if (cfun->can_throw_non_call_exceptions)
    copy_reg_eh_region_note_forward (insn, get_insns (), NULL);

  end_sequence ();
}

/* Do input reloading for reload RL, which is for the insn described by CHAIN
   and has the number J.  */
static void
do_input_reload (struct insn_chain *chain, struct reload *rl, int j)
{
  rtx_insn *insn = chain->insn;
  rtx old = (rl->in && MEM_P (rl->in)
	     ? rl->in_reg : rl->in);
  rtx reg_rtx = rl->reg_rtx;

  if (old && reg_rtx)
    {
      machine_mode mode;

      /* 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 (rl->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.
	 It turns out that RELOADREG's mode is irrelevant:
	 we can change that arbitrarily.

	 Consider (SUBREG:SI foo:QI) as an operand that must be SImode;
	 then the reload reg may not support QImode moves, so use SImode.
	 If foo is in memory due to spilling a pseudo reg, this is safe,
	 because the QImode value is in the least significant part of a
	 slot big enough for a SImode.  If foo is some other sort of
	 memory reference, then it is impossible to reload this case,
	 so previous passes had better make sure this never happens.

	 Then consider a one-word union which has SImode and one of its
	 members is a float, being fetched as (SUBREG:SF union:SI).
	 We must fetch that as SFmode because we could be loading into
	 a float-only register.  In this case OLD's mode is correct.

	 Consider an immediate integer: it has VOIDmode.  Here we need
	 to get a mode from something else.

	 In some cases, there is a fourth mode, the operand's
	 containing mode.  If the insn specifies a containing mode for
	 this operand, it overrides all others.

	 I am not sure whether the algorithm here is always right,
	 but it does the right things in those cases.  */

      mode = GET_MODE (old);
      if (mode == VOIDmode)
	mode = rl->inmode;

      /* We cannot use gen_lowpart_common since it can do the wrong thing
	 when REG_RTX has a multi-word mode.  Note that REG_RTX must
	 always be a REG here.  */
      if (GET_MODE (reg_rtx) != mode)
	reg_rtx = reload_adjust_reg_for_mode (reg_rtx, mode);
    }
  reload_reg_rtx_for_input[j] = reg_rtx;

  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] || (rl->out && ! rl->out_reg))
      && ! rtx_equal_p (reg_rtx, old)
      && reg_rtx != 0)
    emit_input_reload_insns (chain, rld + j, old, j);

  /* When inheriting a wider reload, we have a MEM in rl->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] && rl->in
      && MEM_P (rl->in)
      && MEM_P (rl->in_reg)
      && reload_spill_index[j] >= 0
      && TEST_HARD_REG_BIT (reg_reloaded_valid, reload_spill_index[j]))
    rl->in = regno_reg_rtx[reg_reloaded_contents[reload_spill_index[j]]];

  /* If we are reloading a register that was recently stored in with an
     output-reload, see if we can prove there was
     actually no need to store the old value in it.  */

  if (optimize
      && (reload_inherited[j] || reload_override_in[j])
      && reg_rtx
      && REG_P (reg_rtx)
      && spill_reg_store[REGNO (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.  */
      && !HARD_REGISTER_P (spill_reg_stored_to[REGNO (reg_rtx)])
#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 (reg_rtx)])
	  || rtx_equal_p (spill_reg_stored_to[REGNO (reg_rtx)], rl->out_reg)))
    delete_output_reload (insn, j, REGNO (reg_rtx), reg_rtx);
}

/* Do output reloading for reload RL, which is for the insn described by
   CHAIN and has the number J.
   ??? At some point we need to support handling output reloads of
   JUMP_INSNs or insns that set cc0.  */
static void
do_output_reload (struct insn_chain *chain, struct reload *rl, int j)
{
  rtx note, old;
  rtx_insn *insn = chain->insn;
  /* If this is an output reload that stores something that is
     not loaded in this same reload, see if we can eliminate a previous
     store.  */
  rtx pseudo = rl->out_reg;
  rtx reg_rtx = rl->reg_rtx;

  if (rl->out && reg_rtx)
    {
      machine_mode mode;

      /* Determine the mode to reload in.
	 See comments above (for input reloading).  */
      mode = GET_MODE (rl->out);
      if (mode == VOIDmode)
	{
	  /* VOIDmode should never happen for an output.  */
	  if (asm_noperands (PATTERN (insn)) < 0)
	    /* It's the compiler's fault.  */
	    fatal_insn ("VOIDmode on an output", insn);
	  error_for_asm (insn, "output operand is constant in %<asm%>");
	  /* Prevent crash--use something we know is valid.  */
	  mode = word_mode;
	  rl->out = gen_rtx_REG (mode, REGNO (reg_rtx));
	}
      if (GET_MODE (reg_rtx) != mode)
	reg_rtx = reload_adjust_reg_for_mode (reg_rtx, mode);
    }
  reload_reg_rtx_for_output[j] = reg_rtx;

  if (pseudo
      && optimize
      && REG_P (pseudo)
      && ! rtx_equal_p (rl->in_reg, pseudo)
      && REGNO (pseudo) >= FIRST_PSEUDO_REGISTER
      && reg_last_reload_reg[REGNO (pseudo)])
    {
      int pseudo_no = REGNO (pseudo);
      int last_regno = REGNO (reg_last_reload_reg[pseudo_no]);

      /* We don't need to test full validity of last_regno for
	 inherit here; we only want to know if the store actually
	 matches the pseudo.  */
      if (TEST_HARD_REG_BIT (reg_reloaded_valid, last_regno)
	  && reg_reloaded_contents[last_regno] == pseudo_no
	  && spill_reg_store[last_regno]
	  && rtx_equal_p (pseudo, spill_reg_stored_to[last_regno]))
	delete_output_reload (insn, j, last_regno, reg_rtx);
    }

  old = rl->out_reg;
  if (old == 0
      || reg_rtx == 0
      || rtx_equal_p (old, reg_rtx))
    return;

  /* An output operand that dies right away does need a reload,
     but need not be copied from it.  Show the new location in the
     REG_UNUSED note.  */
  if ((REG_P (old) || GET_CODE (old) == SCRATCH)
      && (note = find_reg_note (insn, REG_UNUSED, old)) != 0)
    {
      XEXP (note, 0) = reg_rtx;
      return;
    }
  /* Likewise for a SUBREG of an operand that dies.  */
  else if (GET_CODE (old) == SUBREG
	   && REG_P (SUBREG_REG (old))
	   && (note = find_reg_note (insn, REG_UNUSED,
				     SUBREG_REG (old))) != 0)
    {
      XEXP (note, 0) = gen_lowpart_common (GET_MODE (old), reg_rtx);
      return;
    }
  else if (GET_CODE (old) == SCRATCH)
    /* If we aren't optimizing, there won't be a REG_UNUSED note,
       but we don't want to make an output reload.  */
    return;

  /* If is a JUMP_INSN, we can't support output reloads yet.  */
  gcc_assert (NONJUMP_INSN_P (insn));

  emit_output_reload_insns (chain, rld + j, j);
}

/* A reload copies values of MODE from register SRC to register DEST.
   Return true if it can be treated for inheritance purposes like a
   group of reloads, each one reloading a single hard register.  The
   caller has already checked that (reg:MODE SRC) and (reg:MODE DEST)
   occupy the same number of hard registers.  */

static bool
inherit_piecemeal_p (int dest ATTRIBUTE_UNUSED,
		     int src ATTRIBUTE_UNUSED,
		     machine_mode mode ATTRIBUTE_UNUSED)
{
  return (REG_CAN_CHANGE_MODE_P (dest, mode, reg_raw_mode[dest])
	  && REG_CAN_CHANGE_MODE_P (src, mode, reg_raw_mode[src]));
}

/* Output insns to reload values in and out of the chosen reload regs.  */

static void
emit_reload_insns (struct insn_chain *chain)
{
  rtx_insn *insn = chain->insn;

  int j;

  CLEAR_HARD_REG_SET (reg_reloaded_died);

  for (j = 0; j < reload_n_operands; j++)
    input_reload_insns[j] = input_address_reload_insns[j]
      = inpaddr_address_reload_insns[j]
      = output_reload_insns[j] = output_address_reload_insns[j]
      = outaddr_address_reload_insns[j]
      = other_output_reload_insns[j] = 0;
  other_input_address_reload_insns = 0;
  other_input_reload_insns = 0;
  operand_reload_insns = 0;
  other_operand_reload_insns = 0;

  /* Dump reloads into the dump file.  */
  if (dump_file)
    {
      fprintf (dump_file, "\nReloads for insn # %d\n", INSN_UID (insn));
      debug_reload_to_stream (dump_file);
    }

  for (j = 0; j < n_reloads; j++)
    if (rld[j].reg_rtx && HARD_REGISTER_P (rld[j].reg_rtx))
      {
	unsigned int i;

	for (i = REGNO (rld[j].reg_rtx); i < END_REGNO (rld[j].reg_rtx); i++)
	  new_spill_reg_store[i] = 0;
      }

  /* Now output the instructions to copy the data into and out of the
     reload registers.  Do these in the order that the reloads were reported,
     since reloads of base and index registers precede reloads of operands
     and the operands may need the base and index registers reloaded.  */

  for (j = 0; j < n_reloads; j++)
    {
      do_input_reload (chain, rld + j, j);
      do_output_reload (chain, rld + j, j);
    }

  /* Now write all the insns we made for reloads in the order expected by
     the allocation functions.  Prior to the insn being reloaded, we write
     the following reloads:

     RELOAD_FOR_OTHER_ADDRESS reloads for input addresses.

     RELOAD_OTHER reloads.

     For each operand, any RELOAD_FOR_INPADDR_ADDRESS reloads followed
     by any RELOAD_FOR_INPUT_ADDRESS reloads followed by the
     RELOAD_FOR_INPUT reload for the operand.

     RELOAD_FOR_OPADDR_ADDRS reloads.

     RELOAD_FOR_OPERAND_ADDRESS reloads.

     After the insn being reloaded, we write the following:

     For each operand, any RELOAD_FOR_OUTADDR_ADDRESS reloads followed
     by any RELOAD_FOR_OUTPUT_ADDRESS reload followed by the
     RELOAD_FOR_OUTPUT reload, followed by any RELOAD_OTHER output
     reloads for the operand.  The RELOAD_OTHER output reloads are
     output in descending order by reload number.  */

  emit_insn_before (other_input_address_reload_insns, insn);
  emit_insn_before (other_input_reload_insns, insn);

  for (j = 0; j < reload_n_operands; j++)
    {
      emit_insn_before (inpaddr_address_reload_insns[j], insn);
      emit_insn_before (input_address_reload_insns[j], insn);
      emit_insn_before (input_reload_insns[j], insn);
    }

  emit_insn_before (other_operand_reload_insns, insn);
  emit_insn_before (operand_reload_insns, insn);

  for (j = 0; j < reload_n_operands; j++)
    {
      rtx_insn *x = emit_insn_after (outaddr_address_reload_insns[j], insn);
      x = emit_insn_after (output_address_reload_insns[j], x);
      x = emit_insn_after (output_reload_insns[j], x);
      emit_insn_after (other_output_reload_insns[j], x);
    }

  /* For all the spill regs newly reloaded in this instruction,
     record what they were reloaded from, so subsequent instructions
     can inherit the reloads.

     Update spill_reg_store for the reloads of this insn.
     Copy the elements that were updated in the loop above.  */

  for (j = 0; j < n_reloads; j++)
    {
      int r = reload_order[j];
      int i = reload_spill_index[r];

      /* If this is a non-inherited input reload from a pseudo, we must
	 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 (rld[r].in_reg != 0
	  && ! (reload_inherited[r] || reload_override_in[r]))
	{
	  rtx reg = rld[r].in_reg;

	  if (GET_CODE (reg) == SUBREG)
	    reg = SUBREG_REG (reg);

	  if (REG_P (reg)
	      && REGNO (reg) >= FIRST_PSEUDO_REGISTER
	      && !REGNO_REG_SET_P (&reg_has_output_reload, REGNO (reg)))
	    {
	      int nregno = REGNO (reg);

	      if (reg_last_reload_reg[nregno])
		{
		  int last_regno = REGNO (reg_last_reload_reg[nregno]);

		  if (reg_reloaded_contents[last_regno] == nregno)
		    spill_reg_store[last_regno] = 0;
		}
	    }
	}

      /* I is nonneg if this reload used a register.
	 If rld[r].reg_rtx is 0, this is an optional reload
	 that we opted to ignore.  */

      if (i >= 0 && rld[r].reg_rtx != 0)
	{
	  int nr = hard_regno_nregs (i, GET_MODE (rld[r].reg_rtx));
	  int k;

	  /* For a multi register reload, we need to check if all or part
	     of the value lives to the end.  */
	  for (k = 0; k < nr; k++)
	    if (reload_reg_reaches_end_p (i + k, r))
	      CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k);

	  /* Maybe the spill reg contains a copy of reload_out.  */
	  if (rld[r].out != 0
	      && (REG_P (rld[r].out)
		  || (rld[r].out_reg
		      ? REG_P (rld[r].out_reg)
		      /* The reload value is an auto-modification of
			 some kind.  For PRE_INC, POST_INC, PRE_DEC
			 and POST_DEC, we record an equivalence
			 between the reload register and the operand
			 on the optimistic assumption that we can make
			 the equivalence hold.  reload_as_needed must
			 then either make it hold or invalidate the
			 equivalence.

			 PRE_MODIFY and POST_MODIFY addresses are reloaded
			 somewhat differently, and allowing them here leads
			 to problems.  */
		      : (GET_CODE (rld[r].out) != POST_MODIFY
			 && GET_CODE (rld[r].out) != PRE_MODIFY))))
	    {
	      rtx reg;

	      reg = reload_reg_rtx_for_output[r];
	      if (reload_reg_rtx_reaches_end_p (reg, r))
		{
		  machine_mode mode = GET_MODE (reg);
		  int regno = REGNO (reg);
		  int nregs = REG_NREGS (reg);
		  rtx out = (REG_P (rld[r].out)
			     ? rld[r].out
			     : rld[r].out_reg
			     ? rld[r].out_reg
/* AUTO_INC */		     : XEXP (rld[r].in_reg, 0));
		  int out_regno = REGNO (out);
		  int out_nregs = (!HARD_REGISTER_NUM_P (out_regno) ? 1
				   : hard_regno_nregs (out_regno, mode));
		  bool piecemeal;

		  spill_reg_store[regno] = new_spill_reg_store[regno];
		  spill_reg_stored_to[regno] = out;
		  reg_last_reload_reg[out_regno] = reg;

		  piecemeal = (HARD_REGISTER_NUM_P (out_regno)
			       && nregs == out_nregs
			       && inherit_piecemeal_p (out_regno, regno, mode));

		  /* If OUT_REGNO is a hard register, it may occupy more than
		     one register.  If it does, say what is in the
		     rest of the registers assuming that both registers
		     agree on how many words the object takes.  If not,
		     invalidate the subsequent registers.  */

		  if (HARD_REGISTER_NUM_P (out_regno))
		    for (k = 1; k < out_nregs; k++)
		      reg_last_reload_reg[out_regno + k]
			= (piecemeal ? regno_reg_rtx[regno + k] : 0);

		  /* Now do the inverse operation.  */
		  for (k = 0; k < nregs; k++)
		    {
		      CLEAR_HARD_REG_BIT (reg_reloaded_dead, regno + k);
		      reg_reloaded_contents[regno + k]
			= (!HARD_REGISTER_NUM_P (out_regno) || !piecemeal
			   ? out_regno
			   : out_regno + k);
		      reg_reloaded_insn[regno + k] = insn;
		      SET_HARD_REG_BIT (reg_reloaded_valid, regno + k);
		      if (targetm.hard_regno_call_part_clobbered (NULL,
								  regno + k,
								  mode))
			SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
					  regno + k);
		      else
			CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
					    regno + k);
		    }
		}
	    }
	  /* 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 (rld[r].out_reg == 0
		   && rld[r].in != 0
		   && ((REG_P (rld[r].in)
			&& !HARD_REGISTER_P (rld[r].in)
			&& !REGNO_REG_SET_P (&reg_has_output_reload,
					     REGNO (rld[r].in)))
		       || (REG_P (rld[r].in_reg)
			   && !REGNO_REG_SET_P (&reg_has_output_reload,
						REGNO (rld[r].in_reg))))
		   && !reg_set_p (reload_reg_rtx_for_input[r], PATTERN (insn)))
	    {
	      rtx reg;

	      reg = reload_reg_rtx_for_input[r];
	      if (reload_reg_rtx_reaches_end_p (reg, r))
		{
		  machine_mode mode;
		  int regno;
		  int nregs;
		  int in_regno;
		  int in_nregs;
		  rtx in;
		  bool piecemeal;

		  mode = GET_MODE (reg);
		  regno = REGNO (reg);
		  nregs = REG_NREGS (reg);
		  if (REG_P (rld[r].in)
		      && REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER)
		    in = rld[r].in;
		  else if (REG_P (rld[r].in_reg))
		    in = rld[r].in_reg;
		  else
		    in = XEXP (rld[r].in_reg, 0);
		  in_regno = REGNO (in);

		  in_nregs = (!HARD_REGISTER_NUM_P (in_regno) ? 1
			      : hard_regno_nregs (in_regno, mode));

		  reg_last_reload_reg[in_regno] = reg;

		  piecemeal = (HARD_REGISTER_NUM_P (in_regno)
			       && nregs == in_nregs
			       && inherit_piecemeal_p (regno, in_regno, mode));

		  if (HARD_REGISTER_NUM_P (in_regno))
		    for (k = 1; k < in_nregs; k++)
		      reg_last_reload_reg[in_regno + k]
			= (piecemeal ? regno_reg_rtx[regno + k] : 0);

		  /* Unless we inherited this reload, show we haven't
		     recently done a store.
		     Previous stores of inherited auto_inc expressions
		     also have to be discarded.  */
		  if (! reload_inherited[r]
		      || (rld[r].out && ! rld[r].out_reg))
		    spill_reg_store[regno] = 0;

		  for (k = 0; k < nregs; k++)
		    {
		      CLEAR_HARD_REG_BIT (reg_reloaded_dead, regno + k);
		      reg_reloaded_contents[regno + k]
			= (!HARD_REGISTER_NUM_P (in_regno) || !piecemeal
			   ? in_regno
			   : in_regno + k);
		      reg_reloaded_insn[regno + k] = insn;
		      SET_HARD_REG_BIT (reg_reloaded_valid, regno + k);
		      if (targetm.hard_regno_call_part_clobbered (NULL,
								  regno + k,
								  mode))
			SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
					  regno + k);
		      else
			CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
					    regno + k);
		    }
		}
	    }
	}

      /* The following if-statement was #if 0'd in 1.34 (or before...).
	 It's reenabled in 1.35 because supposedly nothing else
	 deals with this problem.  */

      /* If a register gets output-reloaded from a non-spill register,
	 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.
	 Also do the same thing for RELOAD_OTHER constraints where the
	 output is discarded.  */
      if (i < 0
	  && ((rld[r].out != 0
	       && (REG_P (rld[r].out)
		   || (MEM_P (rld[r].out)
		       && REG_P (rld[r].out_reg))))
	      || (rld[r].out == 0 && rld[r].out_reg
		  && REG_P (rld[r].out_reg))))
	{
	  rtx out = ((rld[r].out && REG_P (rld[r].out))
		     ? rld[r].out : rld[r].out_reg);
	  int out_regno = REGNO (out);
	  machine_mode mode = GET_MODE (out);

	  /* REG_RTX is now set or clobbered by the main instruction.
	     As the comment above explains, forget_old_reloads_1 only
	     sees the original instruction, and there is no guarantee
	     that the original instruction also clobbered REG_RTX.
	     For example, if find_reloads sees that the input side of
	     a matched operand pair dies in this instruction, it may
	     use the input register as the reload register.

	     Calling forget_old_reloads_1 is a waste of effort if
	     REG_RTX is also the output register.

	     If we know that REG_RTX holds the value of a pseudo
	     register, the code after the call will record that fact.  */
	  if (rld[r].reg_rtx && rld[r].reg_rtx != out)
	    forget_old_reloads_1 (rld[r].reg_rtx, NULL_RTX, NULL);

	  if (!HARD_REGISTER_NUM_P (out_regno))
	    {
	      rtx src_reg;
	      rtx_insn *store_insn = NULL;

	      reg_last_reload_reg[out_regno] = 0;

	      /* 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_for_output[r];

	      if (src_reg)
		{
		  if (reload_reg_rtx_reaches_end_p (src_reg, r))
		    store_insn = new_spill_reg_store[REGNO (src_reg)];
		  else
		    src_reg = NULL_RTX;
		}
	      else
		{
		  /* If this is an optional reload, try to find the
		     source reg from an input reload.  */
		  rtx set = single_set (insn);
		  if (set && SET_DEST (set) == rld[r].out)
		    {
		      int k;

		      src_reg = SET_SRC (set);
		      store_insn = insn;
		      for (k = 0; k < n_reloads; k++)
			{
			  if (rld[k].in == src_reg)
			    {
			      src_reg = reload_reg_rtx_for_input[k];
			      break;
			    }
			}
		    }
		}
	      if (src_reg && REG_P (src_reg)
		  && REGNO (src_reg) < FIRST_PSEUDO_REGISTER)
		{
		  int src_regno, src_nregs, k;
		  rtx note;

		  gcc_assert (GET_MODE (src_reg) == mode);
		  src_regno = REGNO (src_reg);
		  src_nregs = hard_regno_nregs (src_regno, 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
		     notes, so just check both locations.  */
		  note = find_regno_note (insn, REG_DEAD, src_regno);
		  if (! note && store_insn)
		    note = find_regno_note (store_insn, REG_DEAD, src_regno);
		  for (k = 0; k < src_nregs; k++)
		    {
		      spill_reg_store[src_regno + k] = store_insn;
		      spill_reg_stored_to[src_regno + k] = out;
		      reg_reloaded_contents[src_regno + k] = out_regno;
		      reg_reloaded_insn[src_regno + k] = store_insn;
		      CLEAR_HARD_REG_BIT (reg_reloaded_dead, src_regno + k);
		      SET_HARD_REG_BIT (reg_reloaded_valid, src_regno + k);
		      if (targetm.hard_regno_call_part_clobbered
			  (NULL, src_regno + k, mode))
			SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
					  src_regno + k);
		      else
			CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
					    src_regno + k);
		      SET_HARD_REG_BIT (reg_is_output_reload, src_regno + k);
		      if (note)
			SET_HARD_REG_BIT (reg_reloaded_died, src_regno);
		      else
			CLEAR_HARD_REG_BIT (reg_reloaded_died, src_regno);
		    }
		  reg_last_reload_reg[out_regno] = src_reg;
		  /* We have to set reg_has_output_reload here, or else
		     forget_old_reloads_1 will clear reg_last_reload_reg
		     right away.  */
		  SET_REGNO_REG_SET (&reg_has_output_reload,
				     out_regno);
		}
	    }
	  else
	    {
	      int k, out_nregs = hard_regno_nregs (out_regno, mode);

	      for (k = 0; k < out_nregs; k++)
		reg_last_reload_reg[out_regno + k] = 0;
	    }
	}
    }
  IOR_HARD_REG_SET (reg_reloaded_dead, reg_reloaded_died);
}

/* Go through the motions to emit INSN and test if it is strictly valid.
   Return the emitted insn if valid, else return NULL.  */

static rtx_insn *
emit_insn_if_valid_for_reload (rtx pat)
{
  rtx_insn *last = get_last_insn ();
  int code;

  rtx_insn *insn = emit_insn (pat);
  code = recog_memoized (insn);

  if (code >= 0)
    {
      extract_insn (insn);
      /* We want constrain operands to treat this insn strictly in its
	 validity determination, i.e., the way it would after reload has
	 completed.  */
      if (constrain_operands (1, get_enabled_alternatives (insn)))
	return insn;
    }

  delete_insns_since (last);
  return NULL;
}

/* Emit code to perform a reload from IN (which may be a reload register) to
   OUT (which may also be a reload register).  IN or OUT is from operand
   OPNUM with reload type TYPE.

   Returns first insn emitted.  */

static rtx_insn *
gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
{
  rtx_insn *last = get_last_insn ();
  rtx_insn *tem;
  rtx tem1, tem2;

  /* If IN is a paradoxical SUBREG, remove it and try to put the
     opposite SUBREG on OUT.  Likewise for a paradoxical SUBREG on OUT.  */
  if (!strip_paradoxical_subreg (&in, &out))
    strip_paradoxical_subreg (&out, &in);

  /* How to do this reload can get quite tricky.  Normally, we are being
     asked to reload a simple operand, such as a MEM, a constant, or a pseudo
     register that didn't get a hard register.  In that case we can just
     call emit_move_insn.

     We can also be asked to reload a PLUS that adds a register or a MEM to
     another register, constant or MEM.  This can occur during frame pointer
     elimination and while reloading addresses.  This case is handled by
     trying to emit a single insn to perform the add.  If it is not valid,
     we use a two insn sequence.

     Or we can be asked to reload an unary operand that was a fragment of
     an addressing mode, into a register.  If it isn't recognized as-is,
     we try making the unop operand and the reload-register the same:
     (set reg:X (unop:X expr:Y))
     -> (set reg:Y expr:Y) (set reg:X (unop:X reg:Y)).

     Finally, we could be called to handle an 'o' constraint by putting
     an address into a register.  In that case, we first try to do this
     with a named pattern of "reload_load_address".  If no such pattern
     exists, we just emit a SET insn and hope for the best (it will normally
     be valid on machines that use 'o').

     This entire process is made complex because reload will never
     process the insns we generate here and so we must ensure that
     they will fit their constraints and also by the fact that parts of
     IN might be being reloaded separately and replaced with spill registers.
     Because of this, we are, in some sense, just guessing the right approach
     here.  The one listed above seems to work.

     ??? At some point, this whole thing needs to be rethought.  */

  if (GET_CODE (in) == PLUS
      && (REG_P (XEXP (in, 0))
	  || GET_CODE (XEXP (in, 0)) == SUBREG
	  || MEM_P (XEXP (in, 0)))
      && (REG_P (XEXP (in, 1))
	  || GET_CODE (XEXP (in, 1)) == SUBREG
	  || CONSTANT_P (XEXP (in, 1))
	  || MEM_P (XEXP (in, 1))))
    {
      /* We need to compute the sum of a register or a MEM and another
	 register, constant, or MEM, and put it into the reload
	 register.  The best possible way of doing this is if the machine
	 has a three-operand ADD insn that accepts the required operands.

	 The simplest approach is to try to generate such an insn and see if it
	 is recognized and matches its constraints.  If so, it can be used.

	 It might be better not to actually emit the insn unless it is valid,
	 but we need to pass the insn as an operand to `recog' and
	 `extract_insn' and it is simpler to emit and then delete the insn if
	 not valid than to dummy things up.  */

      rtx op0, op1, tem;
      rtx_insn *insn;
      enum insn_code code;

      op0 = find_replacement (&XEXP (in, 0));
      op1 = find_replacement (&XEXP (in, 1));

      /* Since constraint checking is strict, commutativity won't be
	 checked, so we need to do that here to avoid spurious failure
	 if the add instruction is two-address and the second operand
	 of the add is the same as the reload reg, which is frequently
	 the case.  If the insn would be A = B + A, rearrange it so
	 it will be A = A + B as constrain_operands expects.  */

      if (REG_P (XEXP (in, 1))
	  && REGNO (out) == REGNO (XEXP (in, 1)))
	tem = op0, op0 = op1, op1 = tem;

      if (op0 != XEXP (in, 0) || op1 != XEXP (in, 1))
	in = gen_rtx_PLUS (GET_MODE (in), op0, op1);

      insn = emit_insn_if_valid_for_reload (gen_rtx_SET (out, in));
      if (insn)
	return insn;

      /* If that failed, we must use a conservative two-insn sequence.

	 Use a move to copy one operand into the reload register.  Prefer
	 to reload a constant, MEM or pseudo since the move patterns can
	 handle an arbitrary operand.  If OP1 is not a constant, MEM or
	 pseudo and OP1 is not a valid operand for an add instruction, then
	 reload OP1.

	 After reloading one of the operands into the reload register, add
	 the reload register to the output register.

	 If there is another way to do this for a specific machine, a
	 DEFINE_PEEPHOLE should be specified that recognizes the sequence
	 we emit below.  */

      code = optab_handler (add_optab, GET_MODE (out));

      if (CONSTANT_P (op1) || MEM_P (op1) || GET_CODE (op1) == SUBREG
	  || (REG_P (op1)
	      && REGNO (op1) >= FIRST_PSEUDO_REGISTER)
	  || (code != CODE_FOR_nothing
	      && !insn_operand_matches (code, 2, op1)))
	tem = op0, op0 = op1, op1 = tem;

      gen_reload (out, op0, opnum, type);

      /* If OP0 and OP1 are the same, we can use OUT for OP1.
	 This fixes a problem on the 32K where the stack pointer cannot
	 be used as an operand of an add insn.  */

      if (rtx_equal_p (op0, op1))
	op1 = out;

      insn = emit_insn_if_valid_for_reload (gen_add2_insn (out, op1));
      if (insn)
	{
	  /* Add a REG_EQUIV note so that find_equiv_reg can find it.  */
	  set_dst_reg_note (insn, REG_EQUIV, in, out);
	  return insn;
	}

      /* If that failed, copy the address register to the reload register.
	 Then add the constant to the reload register.  */

      gcc_assert (!reg_overlap_mentioned_p (out, op0));
      gen_reload (out, op1, opnum, type);
      insn = emit_insn (gen_add2_insn (out, op0));
      set_dst_reg_note (insn, REG_EQUIV, in, out);
    }

  /* If we need a memory location to do the move, do it that way.  */
  else if ((tem1 = replaced_subreg (in), tem2 = replaced_subreg (out),
	    (REG_P (tem1) && REG_P (tem2)))
	   && REGNO (tem1) < FIRST_PSEUDO_REGISTER
	   && REGNO (tem2) < FIRST_PSEUDO_REGISTER
	   && targetm.secondary_memory_needed (GET_MODE (out),
					       REGNO_REG_CLASS (REGNO (tem1)),
					       REGNO_REG_CLASS (REGNO (tem2))))
    {
      /* Get the memory to use and rewrite both registers to its mode.  */
      rtx loc = get_secondary_mem (in, GET_MODE (out), opnum, type);

      if (GET_MODE (loc) != GET_MODE (out))
	out = gen_rtx_REG (GET_MODE (loc), reg_or_subregno (out));

      if (GET_MODE (loc) != GET_MODE (in))
	in = gen_rtx_REG (GET_MODE (loc), reg_or_subregno (in));

      gen_reload (loc, in, opnum, type);
      gen_reload (out, loc, opnum, type);
    }
  else if (REG_P (out) && UNARY_P (in))
    {
      rtx op1;
      rtx out_moded;
      rtx_insn *set;

      op1 = find_replacement (&XEXP (in, 0));
      if (op1 != XEXP (in, 0))
	in = gen_rtx_fmt_e (GET_CODE (in), GET_MODE (in), op1);

      /* First, try a plain SET.  */
      set = emit_insn_if_valid_for_reload (gen_rtx_SET (out, in));
      if (set)
	return set;

      /* If that failed, move the inner operand to the reload
	 register, and try the same unop with the inner expression
	 replaced with the reload register.  */

      if (GET_MODE (op1) != GET_MODE (out))
	out_moded = gen_rtx_REG (GET_MODE (op1), REGNO (out));
      else
	out_moded = out;

      gen_reload (out_moded, op1, opnum, type);

      rtx temp = gen_rtx_SET (out, gen_rtx_fmt_e (GET_CODE (in), GET_MODE (in),
						  out_moded));
      rtx_insn *insn = emit_insn_if_valid_for_reload (temp);
      if (insn)
	{
	  set_unique_reg_note (insn, REG_EQUIV, in);
	  return insn;
	}

      fatal_insn ("failure trying to reload:", set);
    }
  /* If IN is a simple operand, use gen_move_insn.  */
  else if (OBJECT_P (in) || GET_CODE (in) == SUBREG)
    {
      tem = emit_insn (gen_move_insn (out, in));
      /* IN may contain a LABEL_REF, if so add a REG_LABEL_OPERAND note.  */
      mark_jump_label (in, tem, 0);
    }

  else if (targetm.have_reload_load_address ())
    emit_insn (targetm.gen_reload_load_address (out, in));

  /* Otherwise, just write (set OUT IN) and hope for the best.  */
  else
    emit_insn (gen_rtx_SET (out, in));

  /* Return the first insn emitted.
     We cannot just return get_last_insn, because there may have
     been multiple instructions emitted.  Also note that gen_move_insn may
     emit more than one insn itself, so we cannot assume that there is one
     insn emitted per emit_insn_before call.  */

  return last ? NEXT_INSN (last) : get_insns ();
}

/* Delete a previously made output-reload whose result we now believe
   is not needed.  First we double-check.

   INSN is the insn now being processed.
   LAST_RELOAD_REG is the hard register number for which we want to delete
   the last output reload.
   J is the reload-number that originally used REG.  The caller has made
   certain that reload J doesn't use REG any longer for input.
   NEW_RELOAD_REG is reload register that reload J is using for REG.  */

static void
delete_output_reload (rtx_insn *insn, int j, int last_reload_reg,
		      rtx new_reload_reg)
{
  rtx_insn *output_reload_insn = spill_reg_store[last_reload_reg];
  rtx reg = spill_reg_stored_to[last_reload_reg];
  int k;
  int n_occurrences;
  int n_inherited = 0;
  rtx substed;
  unsigned regno;
  int nregs;

  /* It is possible that this reload has been only used to set another reload
     we eliminated earlier and thus deleted this instruction too.  */
  if (output_reload_insn->deleted ())
    return;

  /* Get the raw pseudo-register referred to.  */

  while (GET_CODE (reg) == SUBREG)
    reg = SUBREG_REG (reg);
  substed = reg_equiv_memory_loc (REGNO (reg));

  /* This is unsafe if the operand occurs more often in the current
     insn than it is inherited.  */
  for (k = n_reloads - 1; k >= 0; k--)
    {
      rtx reg2 = rld[k].in;
      if (! reg2)
	continue;
      if (MEM_P (reg2) || reload_override_in[k])
	reg2 = rld[k].in_reg;

      if (AUTO_INC_DEC && rld[k].out && ! rld[k].out_reg)
	reg2 = XEXP (rld[k].in_reg, 0);

      while (GET_CODE (reg2) == SUBREG)
	reg2 = SUBREG_REG (reg2);
      if (rtx_equal_p (reg2, reg))
	{
	  if (reload_inherited[k] || reload_override_in[k] || k == j)
	    n_inherited++;
	  else
	    return;
	}
    }
  n_occurrences = count_occurrences (PATTERN (insn), reg, 0);
  if (CALL_P (insn) && CALL_INSN_FUNCTION_USAGE (insn))
    n_occurrences += count_occurrences (CALL_INSN_FUNCTION_USAGE (insn),
					reg, 0);
  if (substed)
    n_occurrences += count_occurrences (PATTERN (insn),
					eliminate_regs (substed, VOIDmode,
							NULL_RTX), 0);
  for (rtx i1 = reg_equiv_alt_mem_list (REGNO (reg)); i1; i1 = XEXP (i1, 1))
    {
      gcc_assert (!rtx_equal_p (XEXP (i1, 0), substed));
      n_occurrences += count_occurrences (PATTERN (insn), XEXP (i1, 0), 0);
    }
  if (n_occurrences > n_inherited)
    return;

  regno = REGNO (reg);
  nregs = REG_NREGS (reg);

  /* If the pseudo-reg we are reloading is no longer referenced
     anywhere between the store into it and here,
     and we're within the same basic block, then the value can only
     pass through the reload reg and end up here.
     Otherwise, give up--return.  */
  for (rtx_insn *i1 = NEXT_INSN (output_reload_insn);
       i1 != insn; i1 = NEXT_INSN (i1))
    {
      if (NOTE_INSN_BASIC_BLOCK_P (i1))
	return;
      if ((NONJUMP_INSN_P (i1) || CALL_P (i1))
	  && refers_to_regno_p (regno, regno + nregs, PATTERN (i1), NULL))
	{
	  /* If this is USE in front of INSN, we only have to check that
	     there are no more references than accounted for by inheritance.  */
	  while (NONJUMP_INSN_P (i1) && GET_CODE (PATTERN (i1)) == USE)
	    {
	      n_occurrences += rtx_equal_p (reg, XEXP (PATTERN (i1), 0)) != 0;
	      i1 = NEXT_INSN (i1);
	    }
	  if (n_occurrences <= n_inherited && i1 == insn)
	    break;
	  return;
	}
    }

  /* We will be deleting the insn.  Remove the spill reg information.  */
  for (k = hard_regno_nregs (last_reload_reg, GET_MODE (reg)); k-- > 0; )
    {
      spill_reg_store[last_reload_reg + k] = 0;
      spill_reg_stored_to[last_reload_reg + k] = 0;
    }

  /* The caller has already checked that REG dies or is set in INSN.
     It has also checked that we are optimizing, and thus some
     inaccuracies in the debugging information are acceptable.
     So we could just delete output_reload_insn.  But in some cases
     we can improve the debugging information without sacrificing
     optimization - maybe even improving the code: 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 (rld[j].out != rld[j].in
      && REG_N_DEATHS (REGNO (reg)) == 1
      && REG_N_SETS (REGNO (reg)) == 1
      && REG_BASIC_BLOCK (REGNO (reg)) >= NUM_FIXED_BLOCKS
      && find_regno_note (insn, REG_DEAD, REGNO (reg)))
    {
      rtx_insn *i2;

      /* We know that it was used only between here and the beginning of
	 the current basic block.  (We also know that the last use before
	 INSN was the output reload we are thinking of deleting, but never
	 mind that.)  Search that range; see if any ref remains.  */
      for (i2 = PREV_INSN (insn); i2; i2 = PREV_INSN (i2))
	{
	  rtx set = single_set (i2);

	  /* Uses which just store in the pseudo don't count,
	     since if they are the only uses, they are dead.  */
	  if (set != 0 && SET_DEST (set) == reg)
	    continue;
	  if (LABEL_P (i2) || JUMP_P (i2))
	    break;
	  if ((NONJUMP_INSN_P (i2) || CALL_P (i2))
	      && reg_mentioned_p (reg, PATTERN (i2)))
	    {
	      /* Some other ref remains; just delete the output reload we
		 know to be dead.  */
	      delete_address_reloads (output_reload_insn, insn);
	      delete_insn (output_reload_insn);
	      return;
	    }
	}

      /* Delete the now-dead stores into this pseudo.  Note that this
	 loop also takes care of deleting output_reload_insn.  */
      for (i2 = PREV_INSN (insn); i2; i2 = PREV_INSN (i2))
	{
	  rtx set = single_set (i2);

	  if (set != 0 && SET_DEST (set) == reg)
	    {
	      delete_address_reloads (i2, insn);
	      delete_insn (i2);
	    }
	  if (LABEL_P (i2) || JUMP_P (i2))
	    break;
	}

      /* For the debugging info, say the pseudo lives in this reload reg.  */
      reg_renumber[REGNO (reg)] = REGNO (new_reload_reg);
      if (ira_conflicts_p)
	/* Inform IRA about the change.  */
	ira_mark_allocation_change (REGNO (reg));
      alter_reg (REGNO (reg), -1, false);
    }
  else
    {
      delete_address_reloads (output_reload_insn, insn);
      delete_insn (output_reload_insn);
    }
}

/* We are going to delete DEAD_INSN.  Recursively delete loads of
   reload registers used in DEAD_INSN that are not used till CURRENT_INSN.
   CURRENT_INSN is being reloaded, so we have to check its reloads too.  */
static void
delete_address_reloads (rtx_insn *dead_insn, rtx_insn *current_insn)
{
  rtx set = single_set (dead_insn);
  rtx set2, dst;
  rtx_insn *prev, *next;
  if (set)
    {
      rtx dst = SET_DEST (set);
      if (MEM_P (dst))
	delete_address_reloads_1 (dead_insn, XEXP (dst, 0), current_insn);
    }
  /* If we deleted the store from a reloaded post_{in,de}c expression,
     we can delete the matching adds.  */
  prev = PREV_INSN (dead_insn);
  next = NEXT_INSN (dead_insn);
  if (! prev || ! next)
    return;
  set = single_set (next);
  set2 = single_set (prev);
  if (! set || ! set2
      || GET_CODE (SET_SRC (set)) != PLUS || GET_CODE (SET_SRC (set2)) != PLUS
      || !CONST_INT_P (XEXP (SET_SRC (set), 1))
      || !CONST_INT_P (XEXP (SET_SRC (set2), 1)))
    return;
  dst = SET_DEST (set);
  if (! rtx_equal_p (dst, SET_DEST (set2))
      || ! rtx_equal_p (dst, XEXP (SET_SRC (set), 0))
      || ! rtx_equal_p (dst, XEXP (SET_SRC (set2), 0))
      || (INTVAL (XEXP (SET_SRC (set), 1))
	  != -INTVAL (XEXP (SET_SRC (set2), 1))))
    return;
  delete_related_insns (prev);
  delete_related_insns (next);
}

/* Subfunction of delete_address_reloads: process registers found in X.  */
static void
delete_address_reloads_1 (rtx_insn *dead_insn, rtx x, rtx_insn *current_insn)
{
  rtx_insn *prev, *i2;
  rtx set, dst;
  int i, j;
  enum rtx_code code = GET_CODE (x);

  if (code != REG)
    {
      const char *fmt = GET_RTX_FORMAT (code);
      for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
	{
	  if (fmt[i] == 'e')
	    delete_address_reloads_1 (dead_insn, XEXP (x, i), current_insn);
	  else if (fmt[i] == 'E')
	    {
	      for (j = XVECLEN (x, i) - 1; j >= 0; j--)
		delete_address_reloads_1 (dead_insn, XVECEXP (x, i, j),
					  current_insn);
	    }
	}
      return;
    }

  if (spill_reg_order[REGNO (x)] < 0)
    return;

  /* Scan backwards for the insn that sets x.  This might be a way back due
     to inheritance.  */
  for (prev = PREV_INSN (dead_insn); prev; prev = PREV_INSN (prev))
    {
      code = GET_CODE (prev);
      if (code == CODE_LABEL || code == JUMP_INSN)
	return;
      if (!INSN_P (prev))
	continue;
      if (reg_set_p (x, PATTERN (prev)))
	break;
      if (reg_referenced_p (x, PATTERN (prev)))
	return;
    }
  if (! prev || INSN_UID (prev) < reload_first_uid)
    return;
  /* Check that PREV only sets the reload register.  */
  set = single_set (prev);
  if (! set)
    return;
  dst = SET_DEST (set);
  if (!REG_P (dst)
      || ! rtx_equal_p (dst, x))
    return;
  if (! reg_set_p (dst, PATTERN (dead_insn)))
    {
      /* Check if DST was used in a later insn -
	 it might have been inherited.  */
      for (i2 = NEXT_INSN (dead_insn); i2; i2 = NEXT_INSN (i2))
	{
	  if (LABEL_P (i2))
	    break;
	  if (! INSN_P (i2))
	    continue;
	  if (reg_referenced_p (dst, PATTERN (i2)))
	    {
	      /* If there is a reference to the register in the current insn,
		 it might be loaded in a non-inherited reload.  If no other
		 reload uses it, that means the register is set before
		 referenced.  */
	      if (i2 == current_insn)
		{
		  for (j = n_reloads - 1; j >= 0; 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 (rld[j].in && rld[j].reg_rtx == dst)
		      break;
		  if (j >= 0)
		    break;
		}
	      return;
	    }
	  if (JUMP_P (i2))
	    break;
	  /* If DST is still live at CURRENT_INSN, check if it is used for
	     any reload.  Note that even if CURRENT_INSN sets DST, we still
	     have to check the reloads.  */
	  if (i2 == current_insn)
	    {
	      for (j = n_reloads - 1; j >= 0; 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
		 allocated to a pseudo in this block if no reload in this
		 block needs any of the classes containing DST - see
		 spill_hard_reg.  There is no easy way to tell this, so we
		 have to scan till the end of the basic block.  */
	    }
	  if (reg_set_p (dst, PATTERN (i2)))
	    break;
	}
    }
  delete_address_reloads_1 (prev, SET_SRC (set), current_insn);
  reg_reloaded_contents[REGNO (dst)] = -1;
  delete_insn (prev);
}

/* Output reload-insns to reload VALUE into RELOADREG.
   VALUE is an autoincrement or autodecrement RTX whose operand
   is a register or memory location;
   so reloading involves incrementing that location.
   IN is either identical to VALUE, or some cheaper place to reload from.

   INC_AMOUNT is the number to increment or decrement by (always positive).
   This cannot be deduced from VALUE.  */

static void
inc_for_reload (rtx reloadreg, rtx in, rtx value, poly_int64 inc_amount)
{
  /* REG or MEM to be copied and incremented.  */
  rtx incloc = find_replacement (&XEXP (value, 0));
  /* Nonzero if increment after copying.  */
  int post = (GET_CODE (value) == POST_DEC || GET_CODE (value) == POST_INC
	      || GET_CODE (value) == POST_MODIFY);
  rtx_insn *last;
  rtx inc;
  rtx_insn *add_insn;
  int code;
  rtx real_in = in == value ? incloc : in;

  /* No hard register is equivalent to this register after
     inc/dec operation.  If REG_LAST_RELOAD_REG were nonzero,
     we could inc/dec that register as well (maybe even using it for
     the source), but I'm not sure it's worth worrying about.  */
  if (REG_P (incloc))
    reg_last_reload_reg[REGNO (incloc)] = 0;

  if (GET_CODE (value) == PRE_MODIFY || GET_CODE (value) == POST_MODIFY)
    {
      gcc_assert (GET_CODE (XEXP (value, 1)) == PLUS);
      inc = find_replacement (&XEXP (XEXP (value, 1), 1));
    }
  else
    {
      if (GET_CODE (value) == PRE_DEC || GET_CODE (value) == POST_DEC)
	inc_amount = -inc_amount;

      inc = gen_int_mode (inc_amount, Pmode);
    }

  /* If this is post-increment, first copy the location to the reload reg.  */
  if (post && real_in != reloadreg)
    emit_insn (gen_move_insn (reloadreg, real_in));

  if (in == value)
    {
      /* See if we can directly increment INCLOC.  Use a method similar to
	 that in gen_reload.  */

      last = get_last_insn ();
      add_insn = emit_insn (gen_rtx_SET (incloc,
					 gen_rtx_PLUS (GET_MODE (incloc),
						       incloc, inc)));

      code = recog_memoized (add_insn);
      if (code >= 0)
	{
	  extract_insn (add_insn);
	  if (constrain_operands (1, get_enabled_alternatives (add_insn)))
	    {
	      /* If this is a pre-increment and we have incremented the value
		 where it lives, copy the incremented value to RELOADREG to
		 be used as an address.  */

	      if (! post)
		emit_insn (gen_move_insn (reloadreg, incloc));
	      return;
	    }
	}
      delete_insns_since (last);
    }

  /* If couldn't do the increment directly, must increment in RELOADREG.
     The way we do this depends on whether this is pre- or post-increment.
     For pre-increment, copy INCLOC to the reload register, increment it
     there, then save back.  */

  if (! post)
    {
      if (in != reloadreg)
	emit_insn (gen_move_insn (reloadreg, real_in));
      emit_insn (gen_add2_insn (reloadreg, inc));
      emit_insn (gen_move_insn (incloc, reloadreg));
    }
  else
    {
      /* Postincrement.
	 Because this might be a jump insn or a compare, and because RELOADREG
	 may not be available after the insn in an input reload, we must do
	 the incrementation before the insn being reloaded for.

	 We have already copied IN to RELOADREG.  Increment the copy in
	 RELOADREG, save that back, then decrement RELOADREG so it has
	 the original value.  */

      emit_insn (gen_add2_insn (reloadreg, inc));
      emit_insn (gen_move_insn (incloc, reloadreg));
      if (CONST_INT_P (inc))
	emit_insn (gen_add2_insn (reloadreg,
				  gen_int_mode (-INTVAL (inc),
						GET_MODE (reloadreg))));
      else
	emit_insn (gen_sub2_insn (reloadreg, inc));
    }
}

static void
add_auto_inc_notes (rtx_insn *insn, rtx x)
{
  enum rtx_code code = GET_CODE (x);
  const char *fmt;
  int i, j;

  if (code == MEM && auto_inc_p (XEXP (x, 0)))
    {
      add_reg_note (insn, REG_INC, XEXP (XEXP (x, 0), 0));
      return;
    }

  /* Scan all the operand sub-expressions.  */
  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	add_auto_inc_notes (insn, XEXP (x, i));
      else if (fmt[i] == 'E')
	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	  add_auto_inc_notes (insn, XVECEXP (x, i, j));
    }
}
