/* Register renaming for the GNU compiler.
   Copyright (C) 2000-2021 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 "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "insn-config.h"
#include "regs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "addresses.h"
#include "cfganal.h"
#include "tree-pass.h"
#include "function-abi.h"
#include "regrename.h"

/* This file implements the RTL register renaming pass of the compiler.  It is
   a semi-local pass whose goal is to maximize the usage of the register file
   of the processor by substituting registers for others in the solution given
   by the register allocator.  The algorithm is as follows:

     1. Local def/use chains are built: within each basic block, chains are
	opened and closed; if a chain isn't closed at the end of the block,
	it is dropped.  We pre-open chains if we have already examined a
	predecessor block and found chains live at the end which match
	live registers at the start of the new block.

     2. We try to combine the local chains across basic block boundaries by
        comparing chains that were open at the start or end of a block to
	those in successor/predecessor blocks.

     3. For each chain, the set of possible renaming registers is computed.
	This takes into account the renaming of previously processed chains.
	Optionally, a preferred class is computed for the renaming register.

     4. The best renaming register is computed for the chain in the above set,
	using a round-robin allocation.  If a preferred class exists, then the
	round-robin allocation is done within the class first, if possible.
	The round-robin allocation of renaming registers itself is global.

     5. If a renaming register has been found, it is substituted in the chain.

  Targets can parameterize the pass by specifying a preferred class for the
  renaming register for a given (super)class of registers to be renamed.

  DEBUG_INSNs are treated specially, in particular registers occurring inside
  them are treated as requiring ALL_REGS as a class.  */

#if HOST_BITS_PER_WIDE_INT <= MAX_RECOG_OPERANDS
#error "Use a different bitmap implementation for untracked_operands."
#endif

enum scan_actions
{
  terminate_write,
  terminate_dead,
  mark_all_read,
  mark_read,
  mark_write,
  /* mark_access is for marking the destination regs in
     REG_FRAME_RELATED_EXPR notes (as if they were read) so that the
     note is updated properly.  */
  mark_access
};

static const char * const scan_actions_name[] =
{
  "terminate_write",
  "terminate_dead",
  "mark_all_read",
  "mark_read",
  "mark_write",
  "mark_access"
};

/* TICK and THIS_TICK are used to record the last time we saw each
   register.  */
static int tick[FIRST_PSEUDO_REGISTER];
static int this_tick = 0;

static struct obstack rename_obstack;

/* If nonnull, the code calling into the register renamer requested
   information about insn operands, and we store it here.  */
vec<insn_rr_info> insn_rr;

static void scan_rtx (rtx_insn *, rtx *, enum reg_class, enum scan_actions,
		      enum op_type);
static bool build_def_use (basic_block);

/* The id to be given to the next opened chain.  */
static unsigned current_id;

/* A mapping of unique id numbers to chains.  */
static vec<du_head_p> id_to_chain;

/* List of currently open chains.  */
static class du_head *open_chains;

/* Bitmap of open chains.  The bits set always match the list found in
   open_chains.  */
static bitmap_head open_chains_set;

/* Record the registers being tracked in open_chains.  */
static HARD_REG_SET live_in_chains;

/* Record the registers that are live but not tracked.  The intersection
   between this and live_in_chains is empty.  */
static HARD_REG_SET live_hard_regs;

/* Set while scanning RTL if INSN_RR is nonnull, i.e. if the current analysis
   is for a caller that requires operand data.  Used in
   record_operand_use.  */
static operand_rr_info *cur_operand;

/* Set while scanning RTL if a register dies.  Used to tie chains.  */
static class du_head *terminated_this_insn;

/* Return the chain corresponding to id number ID.  Take into account that
   chains may have been merged.  */
du_head_p
regrename_chain_from_id (unsigned int id)
{
  du_head_p first_chain = id_to_chain[id];
  du_head_p chain = first_chain;
  while (chain->id != id)
    {
      id = chain->id;
      chain = id_to_chain[id];
    }
  first_chain->id = id;
  return chain;
}

/* Dump all def/use chains, starting at id FROM.  */

static void
dump_def_use_chain (int from)
{
  du_head_p head;
  int i;
  FOR_EACH_VEC_ELT_FROM (id_to_chain, i, head, from)
    {
      struct du_chain *this_du = head->first;

      fprintf (dump_file, "Register %s (%d):",
	       reg_names[head->regno], head->nregs);
      while (this_du)
	{
	  fprintf (dump_file, " %d [%s]", INSN_UID (this_du->insn),
		   reg_class_names[this_du->cl]);
	  this_du = this_du->next_use;
	}
      fprintf (dump_file, "\n");
      head = head->next_chain;
    }
}

static void
free_chain_data (void)
{
  int i;
  du_head_p ptr;
  for (i = 0; id_to_chain.iterate (i, &ptr); i++)
    bitmap_clear (&ptr->conflicts);

  id_to_chain.release ();
}

/* Walk all chains starting with CHAINS and record that they conflict with
   another chain whose id is ID.  */

static void
mark_conflict (class du_head *chains, unsigned id)
{
  while (chains)
    {
      bitmap_set_bit (&chains->conflicts, id);
      chains = chains->next_chain;
    }
}

/* Examine cur_operand, and if it is nonnull, record information about the
   use THIS_DU which is part of the chain HEAD.  */

static void
record_operand_use (class du_head *head, struct du_chain *this_du)
{
  if (cur_operand == NULL || cur_operand->failed)
    return;
  if (head->cannot_rename)
    {
      cur_operand->failed = true;
      return;
    }
  gcc_assert (cur_operand->n_chains < MAX_REGS_PER_ADDRESS);
  cur_operand->heads[cur_operand->n_chains] = head;
  cur_operand->chains[cur_operand->n_chains++] = this_du;
}

/* Create a new chain for THIS_NREGS registers starting at THIS_REGNO,
   and record its occurrence in *LOC, which is being written to in INSN.
   This access requires a register of class CL.  */

static du_head_p
create_new_chain (unsigned this_regno, unsigned this_nregs, rtx *loc,
		  rtx_insn *insn, enum reg_class cl)
{
  class du_head *head = XOBNEW (&rename_obstack, class du_head);
  struct du_chain *this_du;
  int nregs;

  memset ((void *)head, 0, sizeof *head);
  head->next_chain = open_chains;
  head->regno = this_regno;
  head->nregs = this_nregs;

  id_to_chain.safe_push (head);
  head->id = current_id++;

  bitmap_initialize (&head->conflicts, &bitmap_default_obstack);
  bitmap_copy (&head->conflicts, &open_chains_set);
  mark_conflict (open_chains, head->id);

  /* Since we're tracking this as a chain now, remove it from the
     list of conflicting live hard registers and track it in
     live_in_chains instead.  */
  nregs = head->nregs;
  while (nregs-- > 0)
    {
      SET_HARD_REG_BIT (live_in_chains, head->regno + nregs);
      CLEAR_HARD_REG_BIT (live_hard_regs, head->regno + nregs);
    }

  head->hard_conflicts = live_hard_regs;
  bitmap_set_bit (&open_chains_set, head->id);

  open_chains = head;

  if (dump_file)
    {
      fprintf (dump_file, "Creating chain %s (%d)",
	       reg_names[head->regno], head->id);
      if (insn != NULL_RTX)
	fprintf (dump_file, " at insn %d", INSN_UID (insn));
      fprintf (dump_file, "\n");
    }

  if (insn == NULL_RTX)
    {
      head->first = head->last = NULL;
      return head;
    }

  this_du = XOBNEW (&rename_obstack, struct du_chain);
  head->first = head->last = this_du;

  this_du->next_use = 0;
  this_du->loc = loc;
  this_du->insn = insn;
  this_du->cl = cl;
  record_operand_use (head, this_du);
  return head;
}

/* For a def-use chain HEAD, find which registers overlap its lifetime and
   set the corresponding bits in *PSET.  */

static void
merge_overlapping_regs (HARD_REG_SET *pset, class du_head *head)
{
  bitmap_iterator bi;
  unsigned i;
  *pset |= head->hard_conflicts;
  EXECUTE_IF_SET_IN_BITMAP (&head->conflicts, 0, i, bi)
    {
      du_head_p other = regrename_chain_from_id (i);
      unsigned j = other->nregs;
      gcc_assert (other != head);
      while (j-- > 0)
	SET_HARD_REG_BIT (*pset, other->regno + j);
    }
}

/* Return true if (reg:MODE REGNO) would be clobbered by a call covered
   by THIS_HEAD.  */

static bool
call_clobbered_in_chain_p (du_head *this_head, machine_mode mode,
			   unsigned int regno)
{
  return call_clobbered_in_region_p (this_head->call_abis,
				     this_head->call_clobber_mask,
				     mode, regno);
}

/* Check if NEW_REG can be the candidate register to rename for
   REG in THIS_HEAD chain.  THIS_UNAVAILABLE is a set of unavailable hard
   registers.  */

static bool
check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg,
		 class du_head *this_head, HARD_REG_SET this_unavailable)
{
  machine_mode mode = GET_MODE (*this_head->first->loc);
  int nregs = hard_regno_nregs (new_reg, mode);
  int i;
  struct du_chain *tmp;

  for (i = nregs - 1; i >= 0; --i)
    if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i)
	|| fixed_regs[new_reg + i]
	|| global_regs[new_reg + i]
	/* Can't use regs which aren't saved by the prologue.  */
	|| (! df_regs_ever_live_p (new_reg + i)
	    && ! crtl->abi->clobbers_full_reg_p (new_reg + i))
#ifdef LEAF_REGISTERS
	/* We can't use a non-leaf register if we're in a
	   leaf function.  */
	|| (crtl->is_leaf
	    && !LEAF_REGISTERS[new_reg + i])
#endif
	|| ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i))
      return false;

  /* See whether it accepts all modes that occur in
     definition and uses.  */
  for (tmp = this_head->first; tmp; tmp = tmp->next_use)
    {
      /* Completely ignore DEBUG_INSNs, otherwise we can get
	 -fcompare-debug failures.  */
      if (DEBUG_INSN_P (tmp->insn))
	continue;

      if (!targetm.hard_regno_mode_ok (new_reg, GET_MODE (*tmp->loc))
	  || call_clobbered_in_chain_p (this_head, GET_MODE (*tmp->loc),
					new_reg))
	return false;
    }

  return true;
}

/* For the chain THIS_HEAD, compute and return the best register to
   rename to.  SUPER_CLASS is the superunion of register classes in
   the chain.  UNAVAILABLE is a set of registers that cannot be used.
   OLD_REG is the register currently used for the chain.  BEST_RENAME
   controls whether the register chosen must be better than the
   current one or just respect the given constraint.  */

int
find_rename_reg (du_head_p this_head, enum reg_class super_class,
		 HARD_REG_SET *unavailable, int old_reg, bool best_rename)
{
  bool has_preferred_class;
  enum reg_class preferred_class;
  int pass;
  int best_new_reg = old_reg;

  /* Mark registers that overlap this chain's lifetime as unavailable.  */
  merge_overlapping_regs (unavailable, this_head);

  /* Compute preferred rename class of super union of all the classes
     in the chain.  */
  preferred_class
    = (enum reg_class) targetm.preferred_rename_class (super_class);

  /* Pick and check the register from the tied chain iff the tied chain
     is not renamed.  */
  if (this_head->tied_chain && !this_head->tied_chain->renamed
      && check_new_reg_p (old_reg, this_head->tied_chain->regno,
			  this_head, *unavailable))
    return this_head->tied_chain->regno;

  /* If PREFERRED_CLASS is not NO_REGS, we iterate in the first pass
     over registers that belong to PREFERRED_CLASS and try to find the
     best register within the class.  If that failed, we iterate in
     the second pass over registers that don't belong to the class.
     If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
     ascending order without any preference.  */
  has_preferred_class = (preferred_class != NO_REGS);
  for (pass = (has_preferred_class ? 0 : 1); pass < 2; pass++)
    {
      int new_reg;
      for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
	{
	  if (has_preferred_class
	      && (pass == 0)
	      != TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
				    new_reg))
	    continue;

	  if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable))
	    continue;

	  if (!best_rename)
	    return new_reg;

	  /* In the first pass, we force the renaming of registers that
	     don't belong to PREFERRED_CLASS to registers that do, even
	     though the latters were used not very long ago.  */
	  if ((pass == 0
	      && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
				     best_new_reg))
	      || tick[best_new_reg] > tick[new_reg])
	    best_new_reg = new_reg;
	}
      if (pass == 0 && best_new_reg != old_reg)
	break;
    }
  return best_new_reg;
}

/* Iterate over elements in the chain HEAD in order to:
   1. Count number of uses, storing it in *PN_USES.
   2. Narrow the set of registers we can use for renaming, adding
      unavailable registers to *PUNAVAILABLE, which must be
      initialized by the caller.
   3. Compute the superunion of register classes in this chain
      and return it.  */
reg_class
regrename_find_superclass (du_head_p head, int *pn_uses,
			   HARD_REG_SET *punavailable)
{
  int n_uses = 0;
  reg_class super_class = NO_REGS;
  for (du_chain *tmp = head->first; tmp; tmp = tmp->next_use)
    {
      if (DEBUG_INSN_P (tmp->insn))
	continue;
      n_uses++;
      *punavailable |= ~reg_class_contents[tmp->cl];
      super_class
	= reg_class_superunion[(int) super_class][(int) tmp->cl];
    }
  *pn_uses = n_uses;
  return super_class;
}

/* Perform register renaming on the current function.  */
static void
rename_chains (void)
{
  HARD_REG_SET unavailable;
  du_head_p this_head;
  int i;

  memset (tick, 0, sizeof tick);

  CLEAR_HARD_REG_SET (unavailable);
  /* Don't clobber traceback for noreturn functions.  */
  if (frame_pointer_needed)
    {
      add_to_hard_reg_set (&unavailable, Pmode, FRAME_POINTER_REGNUM);
      if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
	add_to_hard_reg_set (&unavailable, Pmode, HARD_FRAME_POINTER_REGNUM);
    }

  FOR_EACH_VEC_ELT (id_to_chain, i, this_head)
    {
      int best_new_reg;
      int n_uses;
      HARD_REG_SET this_unavailable;
      int reg = this_head->regno;

      if (this_head->cannot_rename)
	continue;

      if (fixed_regs[reg] || global_regs[reg]
	  || (!HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
	      && reg == HARD_FRAME_POINTER_REGNUM)
	  || (HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
	      && reg == FRAME_POINTER_REGNUM))
	continue;

      this_unavailable = unavailable;

      reg_class super_class = regrename_find_superclass (this_head, &n_uses,
							 &this_unavailable);
      if (n_uses < 2)
	continue;

      best_new_reg = find_rename_reg (this_head, super_class,
				      &this_unavailable, reg, true);

      if (dump_file)
	{
	  fprintf (dump_file, "Register %s in insn %d",
		   reg_names[reg], INSN_UID (this_head->first->insn));
	  if (this_head->call_abis)
	    fprintf (dump_file, " crosses a call");
	}

      if (best_new_reg == reg)
	{
	  tick[reg] = ++this_tick;
	  if (dump_file)
	    fprintf (dump_file, "; no available better choice\n");
	  continue;
	}

      if (regrename_do_replace (this_head, best_new_reg))
	{
	  if (dump_file)
	    fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
	  tick[best_new_reg] = ++this_tick;
	  df_set_regs_ever_live (best_new_reg, true);
	}
      else
	{
	  if (dump_file)
	    fprintf (dump_file, ", renaming as %s failed\n",
		     reg_names[best_new_reg]);
	  tick[reg] = ++this_tick;
	}
    }
}

/* A structure to record information for each hard register at the start of
   a basic block.  */
struct incoming_reg_info {
  /* Holds the number of registers used in the chain that gave us information
     about this register.  Zero means no information known yet, while a
     negative value is used for something that is part of, but not the first
     register in a multi-register value.  */
  int nregs;
  /* Set to true if we have accesses that conflict in the number of registers
     used.  */
  bool unusable;
};

/* A structure recording information about each basic block.  It is saved
   and restored around basic block boundaries.
   A pointer to such a structure is stored in each basic block's aux field
   during regrename_analyze, except for blocks we know can't be optimized
   (such as entry and exit blocks).  */
class bb_rename_info
{
public:
  /* The basic block corresponding to this structure.  */
  basic_block bb;
  /* Copies of the global information.  */
  bitmap_head open_chains_set;
  bitmap_head incoming_open_chains_set;
  struct incoming_reg_info incoming[FIRST_PSEUDO_REGISTER];
};

/* Initialize a rename_info structure P for basic block BB, which starts a new
   scan.  */
static void
init_rename_info (class bb_rename_info *p, basic_block bb)
{
  int i;
  df_ref def;
  HARD_REG_SET start_chains_set;

  p->bb = bb;
  bitmap_initialize (&p->open_chains_set, &bitmap_default_obstack);
  bitmap_initialize (&p->incoming_open_chains_set, &bitmap_default_obstack);

  open_chains = NULL;
  bitmap_clear (&open_chains_set);

  CLEAR_HARD_REG_SET (live_in_chains);
  REG_SET_TO_HARD_REG_SET (live_hard_regs, df_get_live_in (bb));
  FOR_EACH_ARTIFICIAL_DEF (def, bb->index)
    if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
      SET_HARD_REG_BIT (live_hard_regs, DF_REF_REGNO (def));

  /* Open chains based on information from (at least one) predecessor
     block.  This gives us a chance later on to combine chains across
     basic block boundaries.  Inconsistencies (in access sizes) will
     be caught normally and dealt with conservatively by disabling the
     chain for renaming, and there is no risk of losing optimization
     opportunities by opening chains either: if we did not open the
     chains, we'd have to track the live register as a hard reg, and
     we'd be unable to rename it in any case.  */
  CLEAR_HARD_REG_SET (start_chains_set);
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      struct incoming_reg_info *iri = p->incoming + i;
      if (iri->nregs > 0 && !iri->unusable
	  && range_in_hard_reg_set_p (live_hard_regs, i, iri->nregs))
	{
	  SET_HARD_REG_BIT (start_chains_set, i);
	  remove_range_from_hard_reg_set (&live_hard_regs, i, iri->nregs);
	}
    }
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      struct incoming_reg_info *iri = p->incoming + i;
      if (TEST_HARD_REG_BIT (start_chains_set, i))
	{
	  du_head_p chain;
	  if (dump_file)
	    fprintf (dump_file, "opening incoming chain\n");
	  chain = create_new_chain (i, iri->nregs, NULL, NULL, NO_REGS);
	  bitmap_set_bit (&p->incoming_open_chains_set, chain->id);
	}
    }
}

/* Record in RI that the block corresponding to it has an incoming
   live value, described by CHAIN.  */
static void
set_incoming_from_chain (class bb_rename_info *ri, du_head_p chain)
{
  int i;
  int incoming_nregs = ri->incoming[chain->regno].nregs;
  int nregs;

  /* If we've recorded the same information before, everything is fine.  */
  if (incoming_nregs == chain->nregs)
    {
      if (dump_file)
	fprintf (dump_file, "reg %d/%d already recorded\n",
		 chain->regno, chain->nregs);
      return;
    }

  /* If we have no information for any of the involved registers, update
     the incoming array.  */
  nregs = chain->nregs;
  while (nregs-- > 0)
    if (ri->incoming[chain->regno + nregs].nregs != 0
	|| ri->incoming[chain->regno + nregs].unusable)
      break;
  if (nregs < 0)
    {
      nregs = chain->nregs;
      ri->incoming[chain->regno].nregs = nregs;
      while (nregs-- > 1)
	ri->incoming[chain->regno + nregs].nregs = -nregs;
      if (dump_file)
	fprintf (dump_file, "recorded reg %d/%d\n",
		 chain->regno, chain->nregs);
      return;
    }

  /* There must be some kind of conflict.  Prevent both the old and
     new ranges from being used.  */
  if (incoming_nregs < 0)
    ri->incoming[chain->regno + incoming_nregs].unusable = true;
  for (i = 0; i < chain->nregs; i++)
    ri->incoming[chain->regno + i].unusable = true;
}

/* Merge the two chains C1 and C2 so that all conflict information is
   recorded and C1, and the id of C2 is changed to that of C1.  */
static void
merge_chains (du_head_p c1, du_head_p c2)
{
  if (c1 == c2)
    return;

  if (c2->first != NULL)
    {
      if (c1->first == NULL)
	c1->first = c2->first;
      else
	c1->last->next_use = c2->first;
      c1->last = c2->last;
    }

  c2->first = c2->last = NULL;
  c2->id = c1->id;

  c1->hard_conflicts |= c2->hard_conflicts;
  bitmap_ior_into (&c1->conflicts, &c2->conflicts);

  c1->call_clobber_mask |= c2->call_clobber_mask;
  c1->call_abis |= c2->call_abis;
  c1->cannot_rename |= c2->cannot_rename;
}

/* Analyze the current function and build chains for renaming.
   If INCLUDE_ALL_BLOCKS_P is set to true, process all blocks,
   ignoring BB_DISABLE_SCHEDULE.  The default value is true.  */

void
regrename_analyze (bitmap bb_mask, bool include_all_block_p)
{
  class bb_rename_info *rename_info;
  int i;
  basic_block bb;
  int n_bbs;
  int *inverse_postorder;

  inverse_postorder = XNEWVEC (int, last_basic_block_for_fn (cfun));
  n_bbs = pre_and_rev_post_order_compute (NULL, inverse_postorder, false);

  /* Gather some information about the blocks in this function.  */
  rename_info = XCNEWVEC (class bb_rename_info, n_basic_blocks_for_fn (cfun));
  i = 0;
  FOR_EACH_BB_FN (bb, cfun)
    {
      class bb_rename_info *ri = rename_info + i;
      ri->bb = bb;
      if (bb_mask != NULL && !bitmap_bit_p (bb_mask, bb->index))
	bb->aux = NULL;
      else
	bb->aux = ri;
      i++;
    }

  current_id = 0;
  id_to_chain.create (0);
  bitmap_initialize (&open_chains_set, &bitmap_default_obstack);

  /* The order in which we visit blocks ensures that whenever
     possible, we only process a block after at least one of its
     predecessors, which provides a "seeding" effect to make the logic
     in set_incoming_from_chain and init_rename_info useful.  */

  for (i = 0; i < n_bbs; i++)
    {
      basic_block bb1 = BASIC_BLOCK_FOR_FN (cfun, inverse_postorder[i]);
      class bb_rename_info *this_info;
      bool success;
      edge e;
      edge_iterator ei;
      int old_length = id_to_chain.length ();

      this_info = (class bb_rename_info *) bb1->aux;
      if (this_info == NULL)
	continue;

      if (dump_file)
	fprintf (dump_file, "\nprocessing block %d:\n", bb1->index);

      if (!include_all_block_p && (bb1->flags & BB_DISABLE_SCHEDULE) != 0)
	{
	  if (dump_file)
	    fprintf (dump_file, "avoid disrupting the sms schedule of bb %d\n",
		     bb1->index);
	  continue;
	}

      init_rename_info (this_info, bb1);

      success = build_def_use (bb1);
      if (!success)
	{
	  if (dump_file)
	    fprintf (dump_file, "failed\n");
	  bb1->aux = NULL;
	  id_to_chain.truncate (old_length);
	  current_id = old_length;
	  bitmap_clear (&this_info->incoming_open_chains_set);
	  open_chains = NULL;
	  if (insn_rr.exists ())
	    {
	      rtx_insn *insn;
	      FOR_BB_INSNS (bb1, insn)
		{
		  insn_rr_info *p = &insn_rr[INSN_UID (insn)];
		  p->op_info = NULL;
		}
	    }
	  continue;
	}

      if (dump_file)
	dump_def_use_chain (old_length);
      bitmap_copy (&this_info->open_chains_set, &open_chains_set);

      /* Add successor blocks to the worklist if necessary, and record
	 data about our own open chains at the end of this block, which
	 will be used to pre-open chains when processing the successors.  */
      FOR_EACH_EDGE (e, ei, bb1->succs)
	{
	  class bb_rename_info *dest_ri;
	  class du_head *chain;

	  if (dump_file)
	    fprintf (dump_file, "successor block %d\n", e->dest->index);

	  if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
	    continue;
	  dest_ri = (class bb_rename_info *)e->dest->aux;
	  if (dest_ri == NULL)
	    continue;
	  for (chain = open_chains; chain; chain = chain->next_chain)
	    set_incoming_from_chain (dest_ri, chain);
	}
    }

  free (inverse_postorder);

  /* Now, combine the chains data we have gathered across basic block
     boundaries.

     For every basic block, there may be chains open at the start, or at the
     end.  Rather than exclude them from renaming, we look for open chains
     with matching registers at the other side of the CFG edge.

     For a given chain using register R, open at the start of block B, we
     must find an open chain using R on the other side of every edge leading
     to B, if the register is live across this edge.  In the code below,
     N_PREDS_USED counts the number of edges where the register is live, and
     N_PREDS_JOINED counts those where we found an appropriate chain for
     joining.

     We perform the analysis for both incoming and outgoing edges, but we
     only need to merge once (in the second part, after verifying outgoing
     edges).  */
  FOR_EACH_BB_FN (bb, cfun)
    {
      class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux;
      unsigned j;
      bitmap_iterator bi;

      if (bb_ri == NULL)
	continue;

      if (dump_file)
	fprintf (dump_file, "processing bb %d in edges\n", bb->index);

      EXECUTE_IF_SET_IN_BITMAP (&bb_ri->incoming_open_chains_set, 0, j, bi)
	{
	  edge e;
	  edge_iterator ei;
	  class du_head *chain = regrename_chain_from_id (j);
	  int n_preds_used = 0, n_preds_joined = 0;

	  FOR_EACH_EDGE (e, ei, bb->preds)
	    {
	      class bb_rename_info *src_ri;
	      unsigned k;
	      bitmap_iterator bi2;
	      HARD_REG_SET live;
	      bool success = false;

	      REG_SET_TO_HARD_REG_SET (live, df_get_live_out (e->src));
	      if (!range_overlaps_hard_reg_set_p (live, chain->regno,
						  chain->nregs))
		continue;
	      n_preds_used++;

	      if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
		continue;

	      src_ri = (class bb_rename_info *)e->src->aux;
	      if (src_ri == NULL)
		continue;

	      EXECUTE_IF_SET_IN_BITMAP (&src_ri->open_chains_set,
					0, k, bi2)
		{
		  class du_head *outgoing_chain = regrename_chain_from_id (k);

		  if (outgoing_chain->regno == chain->regno
		      && outgoing_chain->nregs == chain->nregs)
		    {
		      n_preds_joined++;
		      success = true;
		      break;
		    }
		}
	      if (!success && dump_file)
		fprintf (dump_file, "failure to match with pred block %d\n",
			 e->src->index);
	    }
	  if (n_preds_joined < n_preds_used)
	    {
	      if (dump_file)
		fprintf (dump_file, "cannot rename chain %d\n", j);
	      chain->cannot_rename = 1;
	    }
	}
    }
  FOR_EACH_BB_FN (bb, cfun)
    {
      class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux;
      unsigned j;
      bitmap_iterator bi;

      if (bb_ri == NULL)
	continue;

      if (dump_file)
	fprintf (dump_file, "processing bb %d out edges\n", bb->index);

      EXECUTE_IF_SET_IN_BITMAP (&bb_ri->open_chains_set, 0, j, bi)
	{
	  edge e;
	  edge_iterator ei;
	  class du_head *chain = regrename_chain_from_id (j);
	  int n_succs_used = 0, n_succs_joined = 0;

	  FOR_EACH_EDGE (e, ei, bb->succs)
	    {
	      bool printed = false;
	      class bb_rename_info *dest_ri;
	      unsigned k;
	      bitmap_iterator bi2;
	      HARD_REG_SET live;

	      REG_SET_TO_HARD_REG_SET (live, df_get_live_in (e->dest));
	      if (!range_overlaps_hard_reg_set_p (live, chain->regno,
						  chain->nregs))
		continue;
	      
	      n_succs_used++;

	      dest_ri = (class bb_rename_info *)e->dest->aux;
	      if (dest_ri == NULL)
		continue;

	      EXECUTE_IF_SET_IN_BITMAP (&dest_ri->incoming_open_chains_set,
					0, k, bi2)
		{
		  class du_head *incoming_chain = regrename_chain_from_id (k);

		  if (incoming_chain->regno == chain->regno
		      && incoming_chain->nregs == chain->nregs)
		    {
		      if (dump_file)
			{
			  if (!printed)
			    fprintf (dump_file,
				     "merging blocks for edge %d -> %d\n",
				     e->src->index, e->dest->index);
			  printed = true;
			  fprintf (dump_file,
				   "  merging chains %d (->%d) and %d (->%d) [%s]\n",
				   k, incoming_chain->id, j, chain->id, 
				   reg_names[incoming_chain->regno]);
			}

		      merge_chains (chain, incoming_chain);
		      n_succs_joined++;
		      break;
		    }
		}
	    }
	  if (n_succs_joined < n_succs_used)
	    {
	      if (dump_file)
		fprintf (dump_file, "cannot rename chain %d\n",
			 j);
	      chain->cannot_rename = 1;
	    }
	}
    }

  free (rename_info);

  FOR_EACH_BB_FN (bb, cfun)
    bb->aux = NULL;
}

/* Attempt to replace all uses of the register in the chain beginning with
   HEAD with REG.  Returns true on success and false if the replacement is
   rejected because the insns would not validate.  The latter can happen
   e.g. if a match_parallel predicate enforces restrictions on register
   numbering in its subpatterns.  */

bool
regrename_do_replace (class du_head *head, int reg)
{
  struct du_chain *chain;
  unsigned int base_regno = head->regno;
  machine_mode mode;
  rtx last_reg = NULL_RTX, last_repl = NULL_RTX;

  for (chain = head->first; chain; chain = chain->next_use)
    {
      unsigned int regno = ORIGINAL_REGNO (*chain->loc);
      class reg_attrs *attr = REG_ATTRS (*chain->loc);
      int reg_ptr = REG_POINTER (*chain->loc);

      if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) != base_regno)
	validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC (chain->insn)),
			 gen_rtx_UNKNOWN_VAR_LOC (), true);
      else
	{
	  if (*chain->loc != last_reg)
	    {
	      last_repl = gen_raw_REG (GET_MODE (*chain->loc), reg);
	      if (regno >= FIRST_PSEUDO_REGISTER)
		ORIGINAL_REGNO (last_repl) = regno;
	      REG_ATTRS (last_repl) = attr;
	      REG_POINTER (last_repl) = reg_ptr;
	      last_reg = *chain->loc;
	    }
	  validate_change (chain->insn, chain->loc, last_repl, true);
	}
    }

  if (!apply_change_group ())
    return false;

  mode = GET_MODE (*head->first->loc);
  head->renamed = 1;
  head->regno = reg;
  head->nregs = hard_regno_nregs (reg, mode);
  return true;
}


/* True if we found a register with a size mismatch, which means that we
   can't track its lifetime accurately.  If so, we abort the current block
   without renaming.  */
static bool fail_current_block;

/* Return true if OP is a reg for which all bits are set in PSET, false
   if all bits are clear.
   In other cases, set fail_current_block and return false.  */

static bool
verify_reg_in_set (rtx op, HARD_REG_SET *pset)
{
  unsigned regno, nregs;
  bool all_live, all_dead;
  if (!REG_P (op))
    return false;

  regno = REGNO (op);
  nregs = REG_NREGS (op);
  all_live = all_dead = true;
  while (nregs-- > 0)
    if (TEST_HARD_REG_BIT (*pset, regno + nregs))
      all_dead = false;
    else
      all_live = false;
  if (!all_dead && !all_live)
    {
      fail_current_block = true;
      return false;
    }
  return all_live;
}

/* Return true if OP is a reg that is being tracked already in some form.
   May set fail_current_block if it sees an unhandled case of overlap.  */

static bool
verify_reg_tracked (rtx op)
{
  return (verify_reg_in_set (op, &live_hard_regs)
	  || verify_reg_in_set (op, &live_in_chains));
}

/* Called through note_stores.  DATA points to a rtx_code, either SET or
   CLOBBER, which tells us which kind of rtx to look at.  If we have a
   match, record the set register in live_hard_regs and in the hard_conflicts
   bitmap of open chains.  */

static void
note_sets_clobbers (rtx x, const_rtx set, void *data)
{
  enum rtx_code code = *(enum rtx_code *)data;
  class du_head *chain;

  if (GET_CODE (x) == SUBREG)
    x = SUBREG_REG (x);
  if (!REG_P (x) || GET_CODE (set) != code)
    return;
  /* There must not be pseudos at this point.  */
  gcc_assert (HARD_REGISTER_P (x));
  add_to_hard_reg_set (&live_hard_regs, GET_MODE (x), REGNO (x));
  for (chain = open_chains; chain; chain = chain->next_chain)
    add_to_hard_reg_set (&chain->hard_conflicts, GET_MODE (x), REGNO (x));
}

static void
scan_rtx_reg (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action,
	      enum op_type type)
{
  class du_head **p;
  rtx x = *loc;
  unsigned this_regno = REGNO (x);
  int this_nregs = REG_NREGS (x);

  if (action == mark_write)
    {
      if (type == OP_OUT)
	{
	  du_head_p c;
	  rtx pat = PATTERN (insn);

	  c = create_new_chain (this_regno, this_nregs, loc, insn, cl);

	  /* We try to tie chains in a move instruction for
	     a single output.  */
	  if (recog_data.n_operands == 2
	      && GET_CODE (pat) == SET
	      && GET_CODE (SET_DEST (pat)) == REG
	      && GET_CODE (SET_SRC (pat)) == REG
	      && terminated_this_insn
	      && terminated_this_insn->nregs
		 == REG_NREGS (recog_data.operand[1]))
	    {
	      gcc_assert (terminated_this_insn->regno
			  == REGNO (recog_data.operand[1]));

	      c->tied_chain = terminated_this_insn;
	      terminated_this_insn->tied_chain = c;

	      if (dump_file)
		fprintf (dump_file, "Tying chain %s (%d) with %s (%d)\n",
			 reg_names[c->regno], c->id,
			 reg_names[terminated_this_insn->regno],
			 terminated_this_insn->id);
	    }
	}

      return;
    }

  if ((type == OP_OUT) != (action == terminate_write || action == mark_access))
    return;

  for (p = &open_chains; *p;)
    {
      class du_head *head = *p;
      class du_head *next = head->next_chain;
      int exact_match = (head->regno == this_regno
			 && head->nregs == this_nregs);
      int superset = (this_regno <= head->regno
		      && this_regno + this_nregs >= head->regno + head->nregs);
      int subset = (this_regno >= head->regno
		      && this_regno + this_nregs <= head->regno + head->nregs);

      if (!bitmap_bit_p (&open_chains_set, head->id)
	  || head->regno + head->nregs <= this_regno
	  || this_regno + this_nregs <= head->regno)
	{
	  p = &head->next_chain;
	  continue;
	}

      if (action == mark_read || action == mark_access)
	{
	  /* ??? Class NO_REGS can happen if the md file makes use of
	     EXTRA_CONSTRAINTS to match registers.  Which is arguably
	     wrong, but there we are.  */

	  if (cl == NO_REGS || (!exact_match && !DEBUG_INSN_P (insn)))
	    {
	      if (dump_file)
		fprintf (dump_file,
			 "Cannot rename chain %s (%d) at insn %d (%s)\n",
			 reg_names[head->regno], head->id, INSN_UID (insn),
			 scan_actions_name[(int) action]);
	      head->cannot_rename = 1;
	      if (superset)
		{
		  unsigned nregs = this_nregs;
		  head->regno = this_regno;
		  head->nregs = this_nregs;
		  while (nregs-- > 0)
		    SET_HARD_REG_BIT (live_in_chains, head->regno + nregs);
		  if (dump_file)
		    fprintf (dump_file,
			     "Widening register in chain %s (%d) at insn %d\n",
			     reg_names[head->regno], head->id, INSN_UID (insn));
		}
	      else if (!subset)
		{
		  fail_current_block = true;
		  if (dump_file)
		    fprintf (dump_file,
			     "Failing basic block due to unhandled overlap\n");
		}
	    }
	  else
	    {
	      struct du_chain *this_du;
	      this_du = XOBNEW (&rename_obstack, struct du_chain);
	      this_du->next_use = 0;
	      this_du->loc = loc;
	      this_du->insn = insn;
	      this_du->cl = cl;
	      if (head->first == NULL)
		head->first = this_du;
	      else
		head->last->next_use = this_du;
	      record_operand_use (head, this_du);
	      head->last = this_du;
	    }
	  /* Avoid adding the same location in a DEBUG_INSN multiple times,
	     which could happen with non-exact overlap.  */
	  if (DEBUG_INSN_P (insn))
	    return;
	  /* Otherwise, find any other chains that do not match exactly;
	     ensure they all get marked unrenamable.  */
	  p = &head->next_chain;
	  continue;
	}

      /* Whether the terminated chain can be used for renaming
	 depends on the action and this being an exact match.
	 In either case, we remove this element from open_chains.  */

      if ((action == terminate_dead || action == terminate_write)
	  && (superset || subset))
	{
	  unsigned nregs;

	  if (subset && !superset)
	    head->cannot_rename = 1;
	  bitmap_clear_bit (&open_chains_set, head->id);

	  nregs = head->nregs;
	  while (nregs-- > 0)
	    {
	      CLEAR_HARD_REG_BIT (live_in_chains, head->regno + nregs);
	      if (subset && !superset
		  && (head->regno + nregs < this_regno
		      || head->regno + nregs >= this_regno + this_nregs))
		SET_HARD_REG_BIT (live_hard_regs, head->regno + nregs);
	    }

	  if (action == terminate_dead)
	    terminated_this_insn = *p;
	  *p = next;
	  if (dump_file)
	    fprintf (dump_file,
		     "Closing chain %s (%d) at insn %d (%s%s)\n",
		     reg_names[head->regno], head->id, INSN_UID (insn),
		     scan_actions_name[(int) action],
		     superset ? ", superset" : subset ? ", subset" : "");
	}
      else if (action == terminate_dead || action == terminate_write)
	{
	  /* In this case, tracking liveness gets too hard.  Fail the
	     entire basic block.  */
	  if (dump_file)
	    fprintf (dump_file,
		     "Failing basic block due to unhandled overlap\n");
	  fail_current_block = true;
	  return;
	}
      else
	{
	  head->cannot_rename = 1;
	  if (dump_file)
	    fprintf (dump_file,
		     "Cannot rename chain %s (%d) at insn %d (%s)\n",
		     reg_names[head->regno], head->id, INSN_UID (insn),
		     scan_actions_name[(int) action]);
	  p = &head->next_chain;
	}
    }
}

/* A wrapper around base_reg_class which returns ALL_REGS if INSN is a
   DEBUG_INSN.  The arguments MODE, AS, CODE and INDEX_CODE are as for
   base_reg_class.  */

static reg_class
base_reg_class_for_rename (rtx_insn *insn, machine_mode mode, addr_space_t as,
			   rtx_code code, rtx_code index_code)
{
  if (DEBUG_INSN_P (insn))
    return ALL_REGS;
  return base_reg_class (mode, as, code, index_code);
}

/* Adapted from find_reloads_address_1.  CL is INDEX_REG_CLASS or
   BASE_REG_CLASS depending on how the register is being considered.  */

static void
scan_rtx_address (rtx_insn *insn, rtx *loc, enum reg_class cl,
		  enum scan_actions action, machine_mode mode,
		  addr_space_t as)
{
  rtx x = *loc;
  RTX_CODE code = GET_CODE (x);
  const char *fmt;
  int i, j;

  if (action == mark_write || action == mark_access)
    return;

  switch (code)
    {
    case PLUS:
      {
	rtx orig_op0 = XEXP (x, 0);
	rtx orig_op1 = XEXP (x, 1);
	RTX_CODE code0 = GET_CODE (orig_op0);
	RTX_CODE code1 = GET_CODE (orig_op1);
	rtx op0 = orig_op0;
	rtx op1 = orig_op1;
	rtx *locI = NULL;
	rtx *locB = NULL;
	enum rtx_code index_code = SCRATCH;

	if (GET_CODE (op0) == SUBREG)
	  {
	    op0 = SUBREG_REG (op0);
	    code0 = GET_CODE (op0);
	  }

	if (GET_CODE (op1) == SUBREG)
	  {
	    op1 = SUBREG_REG (op1);
	    code1 = GET_CODE (op1);
	  }

	if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
	    || code0 == ZERO_EXTEND || code1 == MEM)
	  {
	    locI = &XEXP (x, 0);
	    locB = &XEXP (x, 1);
	    index_code = GET_CODE (*locI);
	  }
	else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
		 || code1 == ZERO_EXTEND || code0 == MEM)
	  {
	    locI = &XEXP (x, 1);
	    locB = &XEXP (x, 0);
	    index_code = GET_CODE (*locI);
	  }
	else if (code0 == CONST_INT || code0 == CONST
		 || code0 == SYMBOL_REF || code0 == LABEL_REF)
	  {
	    locB = &XEXP (x, 1);
	    index_code = GET_CODE (XEXP (x, 0));
	  }
	else if (code1 == CONST_INT || code1 == CONST
		 || code1 == SYMBOL_REF || code1 == LABEL_REF)
	  {
	    locB = &XEXP (x, 0);
	    index_code = GET_CODE (XEXP (x, 1));
	  }
	else if (code0 == REG && code1 == REG)
	  {
	    int index_op;
	    unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);

	    if (REGNO_OK_FOR_INDEX_P (regno1)
		&& regno_ok_for_base_p (regno0, mode, as, PLUS, REG))
	      index_op = 1;
	    else if (REGNO_OK_FOR_INDEX_P (regno0)
		     && regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
	      index_op = 0;
	    else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG)
		     || REGNO_OK_FOR_INDEX_P (regno1))
	      index_op = 1;
	    else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
	      index_op = 0;
	    else
	      index_op = 1;

	    locI = &XEXP (x, index_op);
	    locB = &XEXP (x, !index_op);
	    index_code = GET_CODE (*locI);
	  }
	else if (code0 == REG)
	  {
	    locI = &XEXP (x, 0);
	    locB = &XEXP (x, 1);
	    index_code = GET_CODE (*locI);
	  }
	else if (code1 == REG)
	  {
	    locI = &XEXP (x, 1);
	    locB = &XEXP (x, 0);
	    index_code = GET_CODE (*locI);
	  }

	if (locI)
	  {
	    reg_class iclass = DEBUG_INSN_P (insn) ? ALL_REGS : INDEX_REG_CLASS;
	    scan_rtx_address (insn, locI, iclass, action, mode, as);
	  }
	if (locB)
	  {
	    reg_class bclass = base_reg_class_for_rename (insn, mode, as, PLUS,
							  index_code);
	    scan_rtx_address (insn, locB, bclass, action, mode, as);
	  }
	return;
      }

    case POST_INC:
    case POST_DEC:
    case POST_MODIFY:
    case PRE_INC:
    case PRE_DEC:
    case PRE_MODIFY:
      /* If the target doesn't claim to handle autoinc, this must be
	 something special, like a stack push.  Kill this chain.  */
      if (!AUTO_INC_DEC)
	action = mark_all_read;

      break;

    case MEM:
      {
	reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
						      MEM_ADDR_SPACE (x),
						      MEM, SCRATCH);
	scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x),
			  MEM_ADDR_SPACE (x));
      }
      return;

    case REG:
      scan_rtx_reg (insn, loc, cl, action, OP_IN);
      return;

    default:
      break;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	scan_rtx_address (insn, &XEXP (x, i), cl, action, mode, as);
      else if (fmt[i] == 'E')
	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	  scan_rtx_address (insn, &XVECEXP (x, i, j), cl, action, mode, as);
    }
}

static void
scan_rtx (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action,
	  enum op_type type)
{
  const char *fmt;
  rtx x = *loc;
  int i, j;

  enum rtx_code code = GET_CODE (x);
  switch (code)
    {
    case CONST:
    CASE_CONST_ANY:
    case SYMBOL_REF:
    case LABEL_REF:
    case CC0:
    case PC:
      return;

    case REG:
      scan_rtx_reg (insn, loc, cl, action, type);
      return;

    case MEM:
      {
	reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
						      MEM_ADDR_SPACE (x),
						      MEM, SCRATCH);

	scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x),
			  MEM_ADDR_SPACE (x));
      }
      return;

    case SET:
      scan_rtx (insn, &SET_SRC (x), cl, action, OP_IN);
      scan_rtx (insn, &SET_DEST (x), cl, action,
		(GET_CODE (PATTERN (insn)) == COND_EXEC
		 && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT);
      return;

    case STRICT_LOW_PART:
      scan_rtx (insn, &XEXP (x, 0), cl, action,
		verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT);
      return;

    case ZERO_EXTRACT:
    case SIGN_EXTRACT:
      scan_rtx (insn, &XEXP (x, 0), cl, action,
		(type == OP_IN ? OP_IN :
		 verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT));
      scan_rtx (insn, &XEXP (x, 1), cl, action, OP_IN);
      scan_rtx (insn, &XEXP (x, 2), cl, action, OP_IN);
      return;

    case POST_INC:
    case PRE_INC:
    case POST_DEC:
    case PRE_DEC:
    case POST_MODIFY:
    case PRE_MODIFY:
      /* Should only happen inside MEM.  */
      gcc_unreachable ();

    case CLOBBER:
      scan_rtx (insn, &SET_DEST (x), cl, action,
		(GET_CODE (PATTERN (insn)) == COND_EXEC
		 && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT);
      return;

    case EXPR_LIST:
      scan_rtx (insn, &XEXP (x, 0), cl, action, type);
      if (XEXP (x, 1))
	scan_rtx (insn, &XEXP (x, 1), cl, action, type);
      return;

    default:
      break;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	scan_rtx (insn, &XEXP (x, i), cl, action, type);
      else if (fmt[i] == 'E')
	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	  scan_rtx (insn, &XVECEXP (x, i, j), cl, action, type);
    }
}

/* Hide operands of the current insn (of which there are N_OPS) by
   substituting pc for them.
   Previous values are stored in the OLD_OPERANDS and OLD_DUPS.
   For every bit set in DO_NOT_HIDE, we leave the operand alone.
   If INOUT_AND_EC_ONLY is set, we only do this for OP_INOUT type operands
   and earlyclobbers.  */

static void
hide_operands (int n_ops, rtx *old_operands, rtx *old_dups,
	       unsigned HOST_WIDE_INT do_not_hide, bool inout_and_ec_only)
{
  int i;
  const operand_alternative *op_alt = which_op_alt ();
  for (i = 0; i < n_ops; i++)
    {
      old_operands[i] = recog_data.operand[i];
      /* Don't squash match_operator or match_parallel here, since
	 we don't know that all of the contained registers are
	 reachable by proper operands.  */
      if (recog_data.constraints[i][0] == '\0')
	continue;
      if (do_not_hide & (1 << i))
	continue;
      if (!inout_and_ec_only || recog_data.operand_type[i] == OP_INOUT
	  || op_alt[i].earlyclobber)
	*recog_data.operand_loc[i] = pc_rtx;
    }
  for (i = 0; i < recog_data.n_dups; i++)
    {
      int opn = recog_data.dup_num[i];
      old_dups[i] = *recog_data.dup_loc[i];
      if (do_not_hide & (1 << opn))
	continue;
      if (!inout_and_ec_only || recog_data.operand_type[opn] == OP_INOUT
	  || op_alt[opn].earlyclobber)
	*recog_data.dup_loc[i] = pc_rtx;
    }
}

/* Undo the substitution performed by hide_operands.  INSN is the insn we
   are processing; the arguments are the same as in hide_operands.  */

static void
restore_operands (rtx_insn *insn, int n_ops, rtx *old_operands, rtx *old_dups)
{
  int i;
  for (i = 0; i < recog_data.n_dups; i++)
    *recog_data.dup_loc[i] = old_dups[i];
  for (i = 0; i < n_ops; i++)
    *recog_data.operand_loc[i] = old_operands[i];
  if (recog_data.n_dups)
    df_insn_rescan (insn);
}

/* For each output operand of INSN, call scan_rtx to create a new
   open chain.  Do this only for normal or earlyclobber outputs,
   depending on EARLYCLOBBER.  If INSN_INFO is nonnull, use it to
   record information about the operands in the insn.  */

static void
record_out_operands (rtx_insn *insn, bool earlyclobber, insn_rr_info *insn_info)
{
  int n_ops = recog_data.n_operands;
  const operand_alternative *op_alt = which_op_alt ();

  int i;

  for (i = 0; i < n_ops + recog_data.n_dups; i++)
    {
      int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
      rtx *loc = (i < n_ops
		  ? recog_data.operand_loc[opn]
		  : recog_data.dup_loc[i - n_ops]);
      rtx op = *loc;
      enum reg_class cl = alternative_class (op_alt, opn);

      class du_head *prev_open;

      if (recog_data.operand_type[opn] != OP_OUT
	  || op_alt[opn].earlyclobber != earlyclobber)
	continue;

      if (insn_info)
	cur_operand = insn_info->op_info + i;

      prev_open = open_chains;
      if (earlyclobber)
	scan_rtx (insn, loc, cl, terminate_write, OP_OUT);
      scan_rtx (insn, loc, cl, mark_write, OP_OUT);

      /* ??? Many targets have output constraints on the SET_DEST
	 of a call insn, which is stupid, since these are certainly
	 ABI defined hard registers.  For these, and for asm operands
	 that originally referenced hard registers, we must record that
	 the chain cannot be renamed.  */
      if (CALL_P (insn)
	  || (asm_noperands (PATTERN (insn)) > 0
	      && REG_P (op)
	      && REGNO (op) == ORIGINAL_REGNO (op)))
	{
	  if (prev_open != open_chains)
	    open_chains->cannot_rename = 1;
	}
    }
  cur_operand = NULL;
}

/* Build def/use chain.  */

static bool
build_def_use (basic_block bb)
{
  rtx_insn *insn;
  unsigned HOST_WIDE_INT untracked_operands;

  fail_current_block = false;

  for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
    {
      if (NONDEBUG_INSN_P (insn))
	{
	  int n_ops;
	  rtx note;
	  rtx old_operands[MAX_RECOG_OPERANDS];
	  rtx old_dups[MAX_DUP_OPERANDS];
	  int i;
	  int predicated;
	  enum rtx_code set_code = SET;
	  enum rtx_code clobber_code = CLOBBER;
	  insn_rr_info *insn_info = NULL;
	  terminated_this_insn = NULL;

	  /* Process the insn, determining its effect on the def-use
	     chains and live hard registers.  We perform the following
	     steps with the register references in the insn, simulating
	     its effect:
	     (1) Deal with earlyclobber operands and CLOBBERs of non-operands
	         by creating chains and marking hard regs live.
	     (2) Any read outside an operand causes any chain it overlaps
	         with to be marked unrenamable.
	     (3) Any read inside an operand is added if there's already
	         an open chain for it.
	     (4) For any REG_DEAD note we find, close open chains that
	         overlap it.
	     (5) For any non-earlyclobber write we find, close open chains
	         that overlap it.
	     (6) For any non-earlyclobber write we find in an operand, make
	         a new chain or mark the hard register as live.
	     (7) For any REG_UNUSED, close any chains we just opened.
	     (8) For any REG_CFA_RESTORE or REG_CFA_REGISTER, kill any chain
	         containing its dest.

	     We cannot deal with situations where we track a reg in one mode
	     and see a reference in another mode; these will cause the chain
	     to be marked unrenamable or even cause us to abort the entire
	     basic block.  */

	  extract_constrain_insn (insn);
	  preprocess_constraints (insn);
	  const operand_alternative *op_alt = which_op_alt ();
	  n_ops = recog_data.n_operands;
	  untracked_operands = 0;

	  if (insn_rr.exists ())
	    {
	      insn_info = &insn_rr[INSN_UID (insn)];
	      insn_info->op_info = XOBNEWVEC (&rename_obstack, operand_rr_info,
					      recog_data.n_operands);
	      memset (insn_info->op_info, 0,
		      sizeof (operand_rr_info) * recog_data.n_operands);
	    }

	  /* Simplify the code below by promoting OP_OUT to OP_INOUT in
	     predicated instructions, but only for register operands
	     that are already tracked, so that we can create a chain
	     when the first SET makes a register live.  */

	  predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
	  for (i = 0; i < n_ops; ++i)
	    {
	      rtx op = recog_data.operand[i];
	      int matches = op_alt[i].matches;
	      if (matches >= 0 || op_alt[i].matched >= 0
	          || (predicated && recog_data.operand_type[i] == OP_OUT))
		{
		  recog_data.operand_type[i] = OP_INOUT;
		  /* A special case to deal with instruction patterns that
		     have matching operands with different modes.  If we're
		     not already tracking such a reg, we won't start here,
		     and we must instead make sure to make the operand visible
		     to the machinery that tracks hard registers.  */
		  machine_mode i_mode = recog_data.operand_mode[i];
		  if (matches >= 0)
		    {
		      machine_mode matches_mode
			= recog_data.operand_mode[matches];

		      if (maybe_ne (GET_MODE_SIZE (i_mode),
				    GET_MODE_SIZE (matches_mode))
			  && !verify_reg_in_set (op, &live_in_chains))
			{
			  untracked_operands |= 1 << i;
			  untracked_operands |= 1 << matches;
			}
		    }
		}
#ifdef STACK_REGS
	      if (regstack_completed
		  && REG_P (op)
		  && IN_RANGE (REGNO (op), FIRST_STACK_REG, LAST_STACK_REG))
		untracked_operands |= 1 << i;
#endif
	      /* If there's an in-out operand with a register that is not
		 being tracked at all yet, open a chain.  */
	      if (recog_data.operand_type[i] == OP_INOUT
		  && !(untracked_operands & (1 << i))
		  && REG_P (op)
		  && !verify_reg_tracked (op))
		create_new_chain (REGNO (op), REG_NREGS (op), NULL, NULL,
				  NO_REGS);
	    }

	  if (fail_current_block)
	    break;

	  /* Step 1a: Mark hard registers that are clobbered in this insn,
	     outside an operand, as live.  */
	  hide_operands (n_ops, old_operands, old_dups, untracked_operands,
			 false);
	  note_stores (insn, note_sets_clobbers, &clobber_code);
	  restore_operands (insn, n_ops, old_operands, old_dups);

	  /* Step 1b: Begin new chains for earlyclobbered writes inside
	     operands.  */
	  record_out_operands (insn, true, insn_info);

	  /* Step 2: Mark chains for which we have reads outside operands
	     as unrenamable.
	     We do this by munging all operands into PC, and closing
	     everything remaining.  */

	  hide_operands (n_ops, old_operands, old_dups, untracked_operands,
			 false);
	  scan_rtx (insn, &PATTERN (insn), NO_REGS, mark_all_read, OP_IN);
	  restore_operands (insn, n_ops, old_operands, old_dups);

	  /* Step 2B: Can't rename function call argument registers.  */
	  if (CALL_P (insn) && CALL_INSN_FUNCTION_USAGE (insn))
	    scan_rtx (insn, &CALL_INSN_FUNCTION_USAGE (insn),
		      NO_REGS, mark_all_read, OP_IN);

	  /* Step 2C: Can't rename asm operands that were originally
	     hard registers.  */
	  if (asm_noperands (PATTERN (insn)) > 0)
	    for (i = 0; i < n_ops; i++)
	      {
		rtx *loc = recog_data.operand_loc[i];
		rtx op = *loc;

		if (REG_P (op)
		    && REGNO (op) == ORIGINAL_REGNO (op)
		    && (recog_data.operand_type[i] == OP_IN
			|| recog_data.operand_type[i] == OP_INOUT))
		  scan_rtx (insn, loc, NO_REGS, mark_all_read, OP_IN);
	      }

	  /* Step 3: Append to chains for reads inside operands.  */
	  for (i = 0; i < n_ops + recog_data.n_dups; i++)
	    {
	      int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
	      rtx *loc = (i < n_ops
			  ? recog_data.operand_loc[opn]
			  : recog_data.dup_loc[i - n_ops]);
	      enum reg_class cl = alternative_class (op_alt, opn);
	      enum op_type type = recog_data.operand_type[opn];

	      /* Don't scan match_operand here, since we've no reg class
		 information to pass down.  Any operands that we could
		 substitute in will be represented elsewhere.  */
	      if (recog_data.constraints[opn][0] == '\0'
		  || untracked_operands & (1 << opn))
		continue;

	      if (insn_info)
		cur_operand = i == opn ? insn_info->op_info + i : NULL;
	      if (op_alt[opn].is_address)
		scan_rtx_address (insn, loc, cl, mark_read,
				  VOIDmode, ADDR_SPACE_GENERIC);
	      else
		scan_rtx (insn, loc, cl, mark_read, type);
	    }
	  cur_operand = NULL;

	  /* Step 3B: Record updates for regs in REG_INC notes, and
	     source regs in REG_FRAME_RELATED_EXPR notes.  */
	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
	    if (REG_NOTE_KIND (note) == REG_INC
		|| REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
	      scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_read,
			OP_INOUT);

	  /* Step 4: Close chains for registers that die here, unless
	     the register is mentioned in a REG_UNUSED note.  In that
	     case we keep the chain open until step #7 below to ensure
	     it conflicts with other output operands of this insn.
	     See PR 52573.  Arguably the insn should not have both
	     notes; it has proven difficult to fix that without
	     other undesirable side effects.  */
	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
	    if (REG_NOTE_KIND (note) == REG_DEAD
		&& !find_regno_note (insn, REG_UNUSED, REGNO (XEXP (note, 0))))
	      {
		remove_from_hard_reg_set (&live_hard_regs,
					  GET_MODE (XEXP (note, 0)),
					  REGNO (XEXP (note, 0)));
		scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
			  OP_IN);
	      }

	  /* Step 4B: If this is a call, any chain live at this point
	     requires a caller-saved reg.  */
	  if (CALL_P (insn))
	    {
	      function_abi callee_abi = insn_callee_abi (insn);
	      class du_head *p;
	      for (p = open_chains; p; p = p->next_chain)
		{
		  p->call_abis |= (1 << callee_abi.id ());
		  p->call_clobber_mask
		    |= callee_abi.full_and_partial_reg_clobbers ();
		  p->hard_conflicts |= callee_abi.full_reg_clobbers ();
		}
	    }

	  /* Step 5: Close open chains that overlap writes.  Similar to
	     step 2, we hide in-out operands, since we do not want to
	     close these chains.  We also hide earlyclobber operands,
	     since we've opened chains for them in step 1, and earlier
	     chains they would overlap with must have been closed at
	     the previous insn at the latest, as such operands cannot
	     possibly overlap with any input operands.  */

	  hide_operands (n_ops, old_operands, old_dups, untracked_operands,
			 true);
	  scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_write, OP_IN);
	  restore_operands (insn, n_ops, old_operands, old_dups);

	  /* Step 6a: Mark hard registers that are set in this insn,
	     outside an operand, as live.  */
	  hide_operands (n_ops, old_operands, old_dups, untracked_operands,
			 false);
	  note_stores (insn, note_sets_clobbers, &set_code);
	  restore_operands (insn, n_ops, old_operands, old_dups);

	  /* Step 6b: Begin new chains for writes inside operands.  */
	  record_out_operands (insn, false, insn_info);

	  /* Step 6c: Record destination regs in REG_FRAME_RELATED_EXPR
	     notes for update.  */
	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
	    if (REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
	      scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_access,
			OP_INOUT);

	  /* Step 7: Close chains for registers that were never
	     really used here.  */
	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
	    if (REG_NOTE_KIND (note) == REG_UNUSED)
	      {
		remove_from_hard_reg_set (&live_hard_regs,
					  GET_MODE (XEXP (note, 0)),
					  REGNO (XEXP (note, 0)));
		scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
			  OP_IN);
	      }

	  /* Step 8: Kill the chains involving register restores.  Those
	     should restore _that_ register.  Similar for REG_CFA_REGISTER.  */
	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
	    if (REG_NOTE_KIND (note) == REG_CFA_RESTORE
		|| REG_NOTE_KIND (note) == REG_CFA_REGISTER)
	      {
		rtx *x = &XEXP (note, 0);
		if (!*x)
		  x = &PATTERN (insn);
		if (GET_CODE (*x) == PARALLEL)
		  x = &XVECEXP (*x, 0, 0);
		if (GET_CODE (*x) == SET)
		  x = &SET_DEST (*x);
		scan_rtx (insn, x, NO_REGS, mark_all_read, OP_IN);
	      }
	}
      else if (DEBUG_BIND_INSN_P (insn)
	       && !VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)))
	{
	  scan_rtx (insn, &INSN_VAR_LOCATION_LOC (insn),
		    ALL_REGS, mark_read, OP_IN);
	}
      if (insn == BB_END (bb))
	break;
    }

  if (fail_current_block)
    return false;

  return true;
}

/* Initialize the register renamer.  If INSN_INFO is true, ensure that
   insn_rr is nonnull.  */
void
regrename_init (bool insn_info)
{
  gcc_obstack_init (&rename_obstack);
  insn_rr.create (0);
  if (insn_info)
    insn_rr.safe_grow_cleared (get_max_uid (), true);
}

/* Free all global data used by the register renamer.  */
void
regrename_finish (void)
{
  insn_rr.release ();
  free_chain_data ();
  obstack_free (&rename_obstack, NULL);
}

/* Perform register renaming on the current function.  */

static unsigned int
regrename_optimize (void)
{
  df_set_flags (DF_LR_RUN_DCE);
  df_note_add_problem ();
  df_analyze ();
  df_set_flags (DF_DEFER_INSN_RESCAN);

  regrename_init (false);

  regrename_analyze (NULL, false);

  rename_chains ();

  regrename_finish ();

  return 0;
}

namespace {

const pass_data pass_data_regrename =
{
  RTL_PASS, /* type */
  "rnreg", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_RENAME_REGISTERS, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_df_finish, /* todo_flags_finish */
};

class pass_regrename : public rtl_opt_pass
{
public:
  pass_regrename (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_regrename, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *)
    {
      return (optimize > 0 && (flag_rename_registers));
    }

  virtual unsigned int execute (function *) { return regrename_optimize (); }

}; // class pass_regrename

} // anon namespace

rtl_opt_pass *
make_pass_regrename (gcc::context *ctxt)
{
  return new pass_regrename (ctxt);
}
