/* Register renaming for the GNU compiler.
   Copyright (C) 2000, 2001, 2002, 2003, 2004  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 2, 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 COPYING.  If not, write to the Free
   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.  */

#define REG_OK_STRICT

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "insn-config.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "reload.h"
#include "output.h"
#include "function.h"
#include "recog.h"
#include "flags.h"
#include "toplev.h"
#include "obstack.h"

#ifndef REG_MODE_OK_FOR_BASE_P
#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
#endif

static const char *const reg_class_names[] = REG_CLASS_NAMES;

struct du_chain
{
  struct du_chain *next_chain;
  struct du_chain *next_use;

  rtx insn;
  rtx *loc;
  ENUM_BITFIELD(reg_class) class : 16;
  unsigned int need_caller_save_reg:1;
  unsigned int earlyclobber:1;
};

enum scan_actions
{
  terminate_all_read,
  terminate_overlapping_read,
  terminate_write,
  terminate_dead,
  mark_read,
  mark_write
};

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

static struct obstack rename_obstack;

static void do_replace (struct du_chain *, int);
static void scan_rtx_reg (rtx, rtx *, enum reg_class,
			  enum scan_actions, enum op_type, int);
static void scan_rtx_address (rtx, rtx *, enum reg_class,
			      enum scan_actions, enum machine_mode);
static void scan_rtx (rtx, rtx *, enum reg_class, enum scan_actions,
		      enum op_type, int);
static struct du_chain *build_def_use (basic_block);
static void dump_def_use_chain (struct du_chain *);
static void note_sets (rtx, rtx, void *);
static void clear_dead_regs (HARD_REG_SET *, enum machine_mode, rtx);
static void merge_overlapping_regs (basic_block, HARD_REG_SET *,
				    struct du_chain *);

/* Called through note_stores from update_life.  Find sets of registers, and
   record them in *DATA (which is actually a HARD_REG_SET *).  */

static void
note_sets (rtx x, rtx set ATTRIBUTE_UNUSED, void *data)
{
  HARD_REG_SET *pset = (HARD_REG_SET *) data;
  unsigned int regno;
  int nregs;

  if (GET_CODE (x) == SUBREG)
    x = SUBREG_REG (x);
  if (GET_CODE (x) != REG)
    return;

  regno = REGNO (x);
  nregs = HARD_REGNO_NREGS (regno, GET_MODE (x));

  /* There must not be pseudos at this point.  */
  if (regno + nregs > FIRST_PSEUDO_REGISTER)
    abort ();

  while (nregs-- > 0)
    SET_HARD_REG_BIT (*pset, regno + nregs);
}

/* Clear all registers from *PSET for which a note of kind KIND can be found
   in the list NOTES.  */

static void
clear_dead_regs (HARD_REG_SET *pset, enum machine_mode kind, rtx notes)
{
  rtx note;
  for (note = notes; note; note = XEXP (note, 1))
    if (REG_NOTE_KIND (note) == kind && REG_P (XEXP (note, 0)))
      {
	rtx reg = XEXP (note, 0);
	unsigned int regno = REGNO (reg);
	int nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg));

	/* There must not be pseudos at this point.  */
	if (regno + nregs > FIRST_PSEUDO_REGISTER)
	  abort ();

	while (nregs-- > 0)
	  CLEAR_HARD_REG_BIT (*pset, regno + nregs);
      }
}

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

static void
merge_overlapping_regs (basic_block b, HARD_REG_SET *pset,
			struct du_chain *chain)
{
  struct du_chain *t = chain;
  rtx insn;
  HARD_REG_SET live;

  REG_SET_TO_HARD_REG_SET (live, b->global_live_at_start);
  insn = BB_HEAD (b);
  while (t)
    {
      /* Search forward until the next reference to the register to be
	 renamed.  */
      while (insn != t->insn)
	{
	  if (INSN_P (insn))
	    {
	      clear_dead_regs (&live, REG_DEAD, REG_NOTES (insn));
	      note_stores (PATTERN (insn), note_sets, (void *) &live);
	      /* Only record currently live regs if we are inside the
		 reg's live range.  */
	      if (t != chain)
		IOR_HARD_REG_SET (*pset, live);
	      clear_dead_regs (&live, REG_UNUSED, REG_NOTES (insn));
	    }
	  insn = NEXT_INSN (insn);
	}

      IOR_HARD_REG_SET (*pset, live);

      /* For the last reference, also merge in all registers set in the
	 same insn.
	 @@@ We only have take earlyclobbered sets into account.  */
      if (! t->next_use)
	note_stores (PATTERN (insn), note_sets, (void *) pset);

      t = t->next_use;
    }
}

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

void
regrename_optimize (void)
{
  int tick[FIRST_PSEUDO_REGISTER];
  int this_tick = 0;
  basic_block bb;
  char *first_obj;

  memset (tick, 0, sizeof tick);

  gcc_obstack_init (&rename_obstack);
  first_obj = obstack_alloc (&rename_obstack, 0);

  FOR_EACH_BB (bb)
    {
      struct du_chain *all_chains = 0;
      HARD_REG_SET unavailable;
      HARD_REG_SET regs_seen;

      CLEAR_HARD_REG_SET (unavailable);

      if (rtl_dump_file)
	fprintf (rtl_dump_file, "\nBasic block %d:\n", bb->index);

      all_chains = build_def_use (bb);

      if (rtl_dump_file)
	dump_def_use_chain (all_chains);

      CLEAR_HARD_REG_SET (unavailable);
      /* Don't clobber traceback for noreturn functions.  */
      if (frame_pointer_needed)
	{
	  int i;

	  for (i = HARD_REGNO_NREGS (FRAME_POINTER_REGNUM, Pmode); i--;)
	    SET_HARD_REG_BIT (unavailable, FRAME_POINTER_REGNUM + i);

#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
	  for (i = HARD_REGNO_NREGS (HARD_FRAME_POINTER_REGNUM, Pmode); i--;)
	    SET_HARD_REG_BIT (unavailable, HARD_FRAME_POINTER_REGNUM + i);
#endif
	}

      CLEAR_HARD_REG_SET (regs_seen);
      while (all_chains)
	{
	  int new_reg, best_new_reg;
	  int n_uses;
	  struct du_chain *this = all_chains;
	  struct du_chain *tmp, *last;
	  HARD_REG_SET this_unavailable;
	  int reg = REGNO (*this->loc);
	  int i;

	  all_chains = this->next_chain;

	  best_new_reg = reg;

#if 0 /* This just disables optimization opportunities.  */
	  /* Only rename once we've seen the reg more than once.  */
	  if (! TEST_HARD_REG_BIT (regs_seen, reg))
	    {
	      SET_HARD_REG_BIT (regs_seen, reg);
	      continue;
	    }
#endif

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

	  COPY_HARD_REG_SET (this_unavailable, unavailable);

	  /* Find last entry on chain (which has the need_caller_save bit),
	     count number of uses, and narrow the set of registers we can
	     use for renaming.  */
	  n_uses = 0;
	  for (last = this; last->next_use; last = last->next_use)
	    {
	      n_uses++;
	      IOR_COMPL_HARD_REG_SET (this_unavailable,
				      reg_class_contents[last->class]);
	    }
	  if (n_uses < 1)
	    continue;

	  IOR_COMPL_HARD_REG_SET (this_unavailable,
				  reg_class_contents[last->class]);

	  if (this->need_caller_save_reg)
	    IOR_HARD_REG_SET (this_unavailable, call_used_reg_set);

	  merge_overlapping_regs (bb, &this_unavailable, this);

	  /* Now potential_regs is a reasonable approximation, let's
	     have a closer look at each register still in there.  */
	  for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
	    {
	      int nregs = HARD_REGNO_NREGS (new_reg, GET_MODE (*this->loc));

	      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.  */
		    || (! regs_ever_live[new_reg + i]
			&& ! call_used_regs[new_reg + i])
#ifdef LEAF_REGISTERS
		    /* We can't use a non-leaf register if we're in a
		       leaf function.  */
		    || (current_function_is_leaf
			&& !LEAF_REGISTERS[new_reg + i])
#endif
#ifdef HARD_REGNO_RENAME_OK
		    || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i)
#endif
		    )
		  break;
	      if (i >= 0)
		continue;

	      /* See whether it accepts all modes that occur in
		 definition and uses.  */
	      for (tmp = this; tmp; tmp = tmp->next_use)
		if (! HARD_REGNO_MODE_OK (new_reg, GET_MODE (*tmp->loc))
		    || (tmp->need_caller_save_reg
			&& ! (HARD_REGNO_CALL_PART_CLOBBERED
			      (reg, GET_MODE (*tmp->loc)))
			&& (HARD_REGNO_CALL_PART_CLOBBERED
			    (new_reg, GET_MODE (*tmp->loc)))))
		  break;
	      if (! tmp)
		{
		  if (tick[best_new_reg] > tick[new_reg])
		    best_new_reg = new_reg;
		}
	    }

	  if (rtl_dump_file)
	    {
	      fprintf (rtl_dump_file, "Register %s in insn %d",
		       reg_names[reg], INSN_UID (last->insn));
	      if (last->need_caller_save_reg)
		fprintf (rtl_dump_file, " crosses a call");
	    }

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

	  do_replace (this, best_new_reg);
	  tick[best_new_reg] = ++this_tick;

	  if (rtl_dump_file)
	    fprintf (rtl_dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
	}

      obstack_free (&rename_obstack, first_obj);
    }

  obstack_free (&rename_obstack, NULL);

  if (rtl_dump_file)
    fputc ('\n', rtl_dump_file);

  count_or_remove_death_notes (NULL, 1);
  update_life_info (NULL, UPDATE_LIFE_LOCAL,
		    PROP_REG_INFO | PROP_DEATH_NOTES);
}

static void
do_replace (struct du_chain *chain, int reg)
{
  while (chain)
    {
      unsigned int regno = ORIGINAL_REGNO (*chain->loc);
      struct reg_attrs * attr = REG_ATTRS (*chain->loc);

      *chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg);
      if (regno >= FIRST_PSEUDO_REGISTER)
	ORIGINAL_REGNO (*chain->loc) = regno;
      REG_ATTRS (*chain->loc) = attr;
      chain = chain->next_use;
    }
}


static struct du_chain *open_chains;
static struct du_chain *closed_chains;

static void
scan_rtx_reg (rtx insn, rtx *loc, enum reg_class class,
	      enum scan_actions action, enum op_type type, int earlyclobber)
{
  struct du_chain **p;
  rtx x = *loc;
  enum machine_mode mode = GET_MODE (x);
  int this_regno = REGNO (x);
  int this_nregs = HARD_REGNO_NREGS (this_regno, mode);

  if (action == mark_write)
    {
      if (type == OP_OUT)
	{
	  struct du_chain *this
	    = obstack_alloc (&rename_obstack, sizeof (struct du_chain));
	  this->next_use = 0;
	  this->next_chain = open_chains;
	  this->loc = loc;
	  this->insn = insn;
	  this->class = class;
	  this->need_caller_save_reg = 0;
	  this->earlyclobber = earlyclobber;
	  open_chains = this;
	}
      return;
    }

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

  for (p = &open_chains; *p;)
    {
      struct du_chain *this = *p;

      /* Check if the chain has been terminated if it has then skip to
	 the next chain.

	 This can happen when we've already appended the location to
	 the chain in Step 3, but are trying to hide in-out operands
	 from terminate_write in Step 5.  */

      if (*this->loc == cc0_rtx)
	p = &this->next_chain;
      else
	{
	  int regno = REGNO (*this->loc);
	  int nregs = HARD_REGNO_NREGS (regno, GET_MODE (*this->loc));
	  int exact_match = (regno == this_regno && nregs == this_nregs);

	  if (regno + nregs <= this_regno
	      || this_regno + this_nregs <= regno)
	    {
	      p = &this->next_chain;
	      continue;
	    }

	  if (action == mark_read)
	    {
	      if (! exact_match)
		abort ();

	      /* ??? 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.  Since we know not what this may
		 be replaced with, terminate the chain.  */
	      if (class != NO_REGS)
		{
		  this = obstack_alloc (&rename_obstack, sizeof (struct du_chain));
		  this->next_use = 0;
		  this->next_chain = (*p)->next_chain;
		  this->loc = loc;
		  this->insn = insn;
		  this->class = class;
		  this->need_caller_save_reg = 0;
		  while (*p)
		    p = &(*p)->next_use;
		  *p = this;
		  return;
		}
	    }

	  if (action != terminate_overlapping_read || ! exact_match)
	    {
	      struct du_chain *next = this->next_chain;

	      /* 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)
		  && exact_match)
		{
		  this->next_chain = closed_chains;
		  closed_chains = this;
		  if (rtl_dump_file)
		    fprintf (rtl_dump_file,
			     "Closing chain %s at insn %d (%s)\n",
			     reg_names[REGNO (*this->loc)], INSN_UID (insn),
			     scan_actions_name[(int) action]);
		}
	      else
		{
		  if (rtl_dump_file)
		    fprintf (rtl_dump_file,
			     "Discarding chain %s at insn %d (%s)\n",
			     reg_names[REGNO (*this->loc)], INSN_UID (insn),
			     scan_actions_name[(int) action]);
		}
	      *p = next;
	    }
	  else
	    p = &this->next_chain;
	}
    }
}

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

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

  if (action == mark_write)
    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;

	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);
	  }
	else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
		 || code1 == ZERO_EXTEND || code0 == MEM)
	  {
	    locI = &XEXP (x, 1);
	    locB = &XEXP (x, 0);
	  }
	else if (code0 == CONST_INT || code0 == CONST
		 || code0 == SYMBOL_REF || code0 == LABEL_REF)
	  locB = &XEXP (x, 1);
	else if (code1 == CONST_INT || code1 == CONST
		 || code1 == SYMBOL_REF || code1 == LABEL_REF)
	  locB = &XEXP (x, 0);
	else if (code0 == REG && code1 == REG)
	  {
	    int index_op;

	    if (REG_OK_FOR_INDEX_P (op0)
		&& REG_MODE_OK_FOR_BASE_P (op1, mode))
	      index_op = 0;
	    else if (REG_OK_FOR_INDEX_P (op1)
		     && REG_MODE_OK_FOR_BASE_P (op0, mode))
	      index_op = 1;
	    else if (REG_MODE_OK_FOR_BASE_P (op1, mode))
	      index_op = 0;
	    else if (REG_MODE_OK_FOR_BASE_P (op0, mode))
	      index_op = 1;
	    else if (REG_OK_FOR_INDEX_P (op1))
	      index_op = 1;
	    else
	      index_op = 0;

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

	if (locI)
	  scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode);
	if (locB)
	  scan_rtx_address (insn, locB, MODE_BASE_REG_CLASS (mode), action, mode);
	return;
      }

    case POST_INC:
    case POST_DEC:
    case POST_MODIFY:
    case PRE_INC:
    case PRE_DEC:
    case PRE_MODIFY:
#ifndef AUTO_INC_DEC
      /* If the target doesn't claim to handle autoinc, this must be
	 something special, like a stack push.  Kill this chain.  */
      action = terminate_all_read;
#endif
      break;

    case MEM:
      scan_rtx_address (insn, &XEXP (x, 0),
			MODE_BASE_REG_CLASS (GET_MODE (x)), action,
			GET_MODE (x));
      return;

    case REG:
      scan_rtx_reg (insn, loc, class, action, OP_IN, 0);
      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), class, action, mode);
      else if (fmt[i] == 'E')
	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	  scan_rtx_address (insn, &XVECEXP (x, i, j), class, action, mode);
    }
}

static void
scan_rtx (rtx insn, rtx *loc, enum reg_class class,
	  enum scan_actions action, enum op_type type, int earlyclobber)
{
  const char *fmt;
  rtx x = *loc;
  enum rtx_code code = GET_CODE (x);
  int i, j;

  code = GET_CODE (x);
  switch (code)
    {
    case CONST:
    case CONST_INT:
    case CONST_DOUBLE:
    case CONST_VECTOR:
    case SYMBOL_REF:
    case LABEL_REF:
    case CC0:
    case PC:
      return;

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

    case MEM:
      scan_rtx_address (insn, &XEXP (x, 0),
			MODE_BASE_REG_CLASS (GET_MODE (x)), action,
			GET_MODE (x));
      return;

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

    case STRICT_LOW_PART:
      scan_rtx (insn, &XEXP (x, 0), class, action, OP_INOUT, earlyclobber);
      return;

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

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

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

    case EXPR_LIST:
      scan_rtx (insn, &XEXP (x, 0), class, action, type, 0);
      if (XEXP (x, 1))
	scan_rtx (insn, &XEXP (x, 1), class, action, type, 0);
      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), class, action, type, 0);
      else if (fmt[i] == 'E')
	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	  scan_rtx (insn, &XVECEXP (x, i, j), class, action, type, 0);
    }
}

/* Build def/use chain.  */

static struct du_chain *
build_def_use (basic_block bb)
{
  rtx insn;

  open_chains = closed_chains = NULL;

  for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
    {
      if (INSN_P (insn))
	{
	  int n_ops;
	  rtx note;
	  rtx old_operands[MAX_RECOG_OPERANDS];
	  rtx old_dups[MAX_DUP_OPERANDS];
	  int i, icode;
	  int alt;
	  int predicated;

	  /* Process the insn, determining its effect on the def-use
	     chains.  We perform the following steps with the register
	     references in the insn:
	     (1) Any read that overlaps an open chain, but doesn't exactly
	         match, causes that chain to be closed.  We can't deal
	         with overlaps yet.
	     (2) Any read outside an operand causes any chain it overlaps
	         with to be closed, since we can't replace it.
	     (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 write we find, close open chains that overlap it.
	     (6) For any write we find in an operand, make a new chain.
	     (7) For any REG_UNUSED, close any chains we just opened.  */

	  icode = recog_memoized (insn);
	  extract_insn (insn);
	  if (! constrain_operands (1))
	    fatal_insn_not_found (insn);
	  preprocess_constraints ();
	  alt = which_alternative;
	  n_ops = recog_data.n_operands;

	  /* Simplify the code below by rewriting things to reflect
	     matching constraints.  Also promote OP_OUT to OP_INOUT
	     in predicated instructions.  */

	  predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
	  for (i = 0; i < n_ops; ++i)
	    {
	      int matches = recog_op_alt[i][alt].matches;
	      if (matches >= 0)
		recog_op_alt[i][alt].class = recog_op_alt[matches][alt].class;
	      if (matches >= 0 || recog_op_alt[i][alt].matched >= 0
	          || (predicated && recog_data.operand_type[i] == OP_OUT))
		recog_data.operand_type[i] = OP_INOUT;
	    }

	  /* Step 1: Close chains for which we have overlapping reads.  */
	  for (i = 0; i < n_ops; i++)
	    scan_rtx (insn, recog_data.operand_loc[i],
		      NO_REGS, terminate_overlapping_read,
		      recog_data.operand_type[i], 0);

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

	  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;
	      *recog_data.operand_loc[i] = cc0_rtx;
	    }
	  for (i = 0; i < recog_data.n_dups; i++)
	    {
	      int dup_num = recog_data.dup_num[i];

	      old_dups[i] = *recog_data.dup_loc[i];
	      *recog_data.dup_loc[i] = cc0_rtx;

	      /* For match_dup of match_operator or match_parallel, share
		 them, so that we don't miss changes in the dup.  */
	      if (icode >= 0
		  && insn_data[icode].operand[dup_num].eliminable == 0)
		old_dups[i] = recog_data.operand[dup_num];
	    }

	  scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_all_read,
		    OP_IN, 0);

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

	  /* Step 2B: Can't rename function call argument registers.  */
	  if (GET_CODE (insn) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (insn))
	    scan_rtx (insn, &CALL_INSN_FUNCTION_USAGE (insn),
		      NO_REGS, terminate_all_read, OP_IN, 0);

	  /* 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 (GET_CODE (op) == REG
		    && 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, terminate_all_read, OP_IN, 0);
	      }

	  /* 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 class = recog_op_alt[opn][alt].class;
	      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')
		continue;

	      if (recog_op_alt[opn][alt].is_address)
		scan_rtx_address (insn, loc, class, mark_read, VOIDmode);
	      else
		scan_rtx (insn, loc, class, mark_read, type, 0);
	    }

	  /* Step 4: Close chains for registers that die here.
	     Also record updates for REG_INC notes.  */
	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
	    {
	      if (REG_NOTE_KIND (note) == REG_DEAD)
		scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
			  OP_IN, 0);
	      else if (REG_NOTE_KIND (note) == REG_INC)
		scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_read,
			  OP_INOUT, 0);
	    }

	  /* Step 4B: If this is a call, any chain live at this point
	     requires a caller-saved reg.  */
	  if (GET_CODE (insn) == CALL_INSN)
	    {
	      struct du_chain *p;
	      for (p = open_chains; p; p = p->next_chain)
		p->need_caller_save_reg = 1;
	    }

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

	  for (i = 0; i < n_ops; i++)
	    {
	      old_operands[i] = recog_data.operand[i];
	      if (recog_data.operand_type[i] == OP_INOUT)
		*recog_data.operand_loc[i] = cc0_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 (recog_data.operand_type[opn] == OP_INOUT)
		*recog_data.dup_loc[i] = cc0_rtx;
	    }

	  scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_write, OP_IN, 0);

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

	  /* Step 6: Begin new chains for writes inside operands.  */
	  /* ??? Many targets have output constraints on the SET_DEST
	     of a call insn, which is stupid, since these are certainly
	     ABI defined hard registers.  Don't change calls at all.
	     Similarly take special care for asm statement that originally
	     referenced hard registers.  */
	  if (asm_noperands (PATTERN (insn)) > 0)
	    {
	      for (i = 0; i < n_ops; i++)
		if (recog_data.operand_type[i] == OP_OUT)
		  {
		    rtx *loc = recog_data.operand_loc[i];
		    rtx op = *loc;
		    enum reg_class class = recog_op_alt[i][alt].class;

		    if (GET_CODE (op) == REG
			&& REGNO (op) == ORIGINAL_REGNO (op))
		      continue;

		    scan_rtx (insn, loc, class, mark_write, OP_OUT,
			      recog_op_alt[i][alt].earlyclobber);
		  }
	    }
	  else if (GET_CODE (insn) != CALL_INSN)
	    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 class = recog_op_alt[opn][alt].class;

		if (recog_data.operand_type[opn] == OP_OUT)
		  scan_rtx (insn, loc, class, mark_write, OP_OUT,
			    recog_op_alt[opn][alt].earlyclobber);
	      }

	  /* 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)
	      scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
			OP_IN, 0);
	}
      if (insn == BB_END (bb))
	break;
    }

  /* Since we close every chain when we find a REG_DEAD note, anything that
     is still open lives past the basic block, so it can't be renamed.  */
  return closed_chains;
}

/* Dump all def/use chains in CHAINS to RTL_DUMP_FILE.  They are
   printed in reverse order as that's how we build them.  */

static void
dump_def_use_chain (struct du_chain *chains)
{
  while (chains)
    {
      struct du_chain *this = chains;
      int r = REGNO (*this->loc);
      int nregs = HARD_REGNO_NREGS (r, GET_MODE (*this->loc));
      fprintf (rtl_dump_file, "Register %s (%d):", reg_names[r], nregs);
      while (this)
	{
	  fprintf (rtl_dump_file, " %d [%s]", INSN_UID (this->insn),
		   reg_class_names[this->class]);
	  this = this->next_use;
	}
      fprintf (rtl_dump_file, "\n");
      chains = chains->next_chain;
    }
}

/* The following code does forward propagation of hard register copies.
   The object is to eliminate as many dependencies as possible, so that
   we have the most scheduling freedom.  As a side effect, we also clean
   up some silly register allocation decisions made by reload.  This
   code may be obsoleted by a new register allocator.  */

/* For each register, we have a list of registers that contain the same
   value.  The OLDEST_REGNO field points to the head of the list, and
   the NEXT_REGNO field runs through the list.  The MODE field indicates
   what mode the data is known to be in; this field is VOIDmode when the
   register is not known to contain valid data.  */

struct value_data_entry
{
  enum machine_mode mode;
  unsigned int oldest_regno;
  unsigned int next_regno;
};

struct value_data
{
  struct value_data_entry e[FIRST_PSEUDO_REGISTER];
  unsigned int max_value_regs;
};

static void kill_value_regno (unsigned, struct value_data *);
static void kill_value (rtx, struct value_data *);
static void set_value_regno (unsigned, enum machine_mode, struct value_data *);
static void init_value_data (struct value_data *);
static void kill_clobbered_value (rtx, rtx, void *);
static void kill_set_value (rtx, rtx, void *);
static int kill_autoinc_value (rtx *, void *);
static void copy_value (rtx, rtx, struct value_data *);
static bool mode_change_ok (enum machine_mode, enum machine_mode,
			    unsigned int);
static rtx maybe_mode_change (enum machine_mode, enum machine_mode,
			      enum machine_mode, unsigned int, unsigned int);
static rtx find_oldest_value_reg (enum reg_class, rtx, struct value_data *);
static bool replace_oldest_value_reg (rtx *, enum reg_class, rtx,
				      struct value_data *);
static bool replace_oldest_value_addr (rtx *, enum reg_class,
				       enum machine_mode, rtx,
				       struct value_data *);
static bool replace_oldest_value_mem (rtx, rtx, struct value_data *);
static bool copyprop_hardreg_forward_1 (basic_block, struct value_data *);
extern void debug_value_data (struct value_data *);
#ifdef ENABLE_CHECKING
static void validate_value_data (struct value_data *);
#endif

/* Kill register REGNO.  This involves removing it from any value lists,
   and resetting the value mode to VOIDmode.  */

static void
kill_value_regno (unsigned int regno, struct value_data *vd)
{
  unsigned int i, next;

  if (vd->e[regno].oldest_regno != regno)
    {
      for (i = vd->e[regno].oldest_regno;
	   vd->e[i].next_regno != regno;
	   i = vd->e[i].next_regno)
	continue;
      vd->e[i].next_regno = vd->e[regno].next_regno;
    }
  else if ((next = vd->e[regno].next_regno) != INVALID_REGNUM)
    {
      for (i = next; i != INVALID_REGNUM; i = vd->e[i].next_regno)
	vd->e[i].oldest_regno = next;
    }

  vd->e[regno].mode = VOIDmode;
  vd->e[regno].oldest_regno = regno;
  vd->e[regno].next_regno = INVALID_REGNUM;

#ifdef ENABLE_CHECKING
  validate_value_data (vd);
#endif
}

/* Kill X.  This is a convenience function for kill_value_regno
   so that we mind the mode the register is in.  */

static void
kill_value (rtx x, struct value_data *vd)
{
  /* SUBREGS are supposed to have been eliminated by now.  But some
     ports, e.g. i386 sse, use them to smuggle vector type information
     through to instruction selection.  Each such SUBREG should simplify,
     so if we get a NULL  we've done something wrong elsewhere.  */

  if (GET_CODE (x) == SUBREG)
    x = simplify_subreg (GET_MODE (x), SUBREG_REG (x),
			 GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
  if (REG_P (x))
    {
      unsigned int regno = REGNO (x);
      unsigned int n = HARD_REGNO_NREGS (regno, GET_MODE (x));
      unsigned int i, j;

      /* Kill the value we're told to kill.  */
      for (i = 0; i < n; ++i)
	kill_value_regno (regno + i, vd);

      /* Kill everything that overlapped what we're told to kill.  */
      if (regno < vd->max_value_regs)
	j = 0;
      else
	j = regno - vd->max_value_regs;
      for (; j < regno; ++j)
	{
	  if (vd->e[j].mode == VOIDmode)
	    continue;
	  n = HARD_REGNO_NREGS (j, vd->e[j].mode);
	  if (j + n > regno)
	    for (i = 0; i < n; ++i)
	      kill_value_regno (j + i, vd);
	}
    }
}

/* Remember that REGNO is valid in MODE.  */

static void
set_value_regno (unsigned int regno, enum machine_mode mode,
		 struct value_data *vd)
{
  unsigned int nregs;

  vd->e[regno].mode = mode;

  nregs = HARD_REGNO_NREGS (regno, mode);
  if (nregs > vd->max_value_regs)
    vd->max_value_regs = nregs;
}

/* Initialize VD such that there are no known relationships between regs.  */

static void
init_value_data (struct value_data *vd)
{
  int i;
  for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
    {
      vd->e[i].mode = VOIDmode;
      vd->e[i].oldest_regno = i;
      vd->e[i].next_regno = INVALID_REGNUM;
    }
  vd->max_value_regs = 0;
}

/* Called through note_stores.  If X is clobbered, kill its value.  */

static void
kill_clobbered_value (rtx x, rtx set, void *data)
{
  struct value_data *vd = data;
  if (GET_CODE (set) == CLOBBER)
    kill_value (x, vd);
}

/* Called through note_stores.  If X is set, not clobbered, kill its
   current value and install it as the root of its own value list.  */

static void
kill_set_value (rtx x, rtx set, void *data)
{
  struct value_data *vd = data;
  if (GET_CODE (set) != CLOBBER)
    {
      kill_value (x, vd);
      if (REG_P (x))
	set_value_regno (REGNO (x), GET_MODE (x), vd);
    }
}

/* Called through for_each_rtx.  Kill any register used as the base of an
   auto-increment expression, and install that register as the root of its
   own value list.  */

static int
kill_autoinc_value (rtx *px, void *data)
{
  rtx x = *px;
  struct value_data *vd = data;

  if (GET_RTX_CLASS (GET_CODE (x)) == 'a')
    {
      x = XEXP (x, 0);
      kill_value (x, vd);
      set_value_regno (REGNO (x), Pmode, vd);
      return -1;
    }

  return 0;
}

/* Assert that SRC has been copied to DEST.  Adjust the data structures
   to reflect that SRC contains an older copy of the shared value.  */

static void
copy_value (rtx dest, rtx src, struct value_data *vd)
{
  unsigned int dr = REGNO (dest);
  unsigned int sr = REGNO (src);
  unsigned int dn, sn;
  unsigned int i;

  /* ??? At present, it's possible to see noop sets.  It'd be nice if
     this were cleaned up beforehand...  */
  if (sr == dr)
    return;

  /* Do not propagate copies to the stack pointer, as that can leave
     memory accesses with no scheduling dependency on the stack update.  */
  if (dr == STACK_POINTER_REGNUM)
    return;

  /* Likewise with the frame pointer, if we're using one.  */
  if (frame_pointer_needed && dr == HARD_FRAME_POINTER_REGNUM)
    return;

  /* If SRC and DEST overlap, don't record anything.  */
  dn = HARD_REGNO_NREGS (dr, GET_MODE (dest));
  sn = HARD_REGNO_NREGS (sr, GET_MODE (dest));
  if ((dr > sr && dr < sr + sn)
      || (sr > dr && sr < dr + dn))
    return;

  /* If SRC had no assigned mode (i.e. we didn't know it was live)
     assign it now and assume the value came from an input argument
     or somesuch.  */
  if (vd->e[sr].mode == VOIDmode)
    set_value_regno (sr, vd->e[dr].mode, vd);

  /* If we are narrowing the input to a smaller number of hard regs,
     and it is in big endian, we are really extracting a high part.
     Since we generally associate a low part of a value with the value itself,
     we must not do the same for the high part.
     Note we can still get low parts for the same mode combination through
     a two-step copy involving differently sized hard regs.
     Assume hard regs fr* are 32 bits bits each, while r* are 64 bits each:
     (set (reg:DI r0) (reg:DI fr0))
     (set (reg:SI fr2) (reg:SI r0))
     loads the low part of (reg:DI fr0) - i.e. fr1 - into fr2, while:
     (set (reg:SI fr2) (reg:SI fr0))
     loads the high part of (reg:DI fr0) into fr2.

     We can't properly represent the latter case in our tables, so don't
     record anything then.  */
  else if (sn < (unsigned int) HARD_REGNO_NREGS (sr, vd->e[sr].mode)
	   && (GET_MODE_SIZE (vd->e[sr].mode) > UNITS_PER_WORD
	       ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
    return;

  /* If SRC had been assigned a mode narrower than the copy, we can't
     link DEST into the chain, because not all of the pieces of the
     copy came from oldest_regno.  */
  else if (sn > (unsigned int) HARD_REGNO_NREGS (sr, vd->e[sr].mode))
    return;

  /* Link DR at the end of the value chain used by SR.  */

  vd->e[dr].oldest_regno = vd->e[sr].oldest_regno;

  for (i = sr; vd->e[i].next_regno != INVALID_REGNUM; i = vd->e[i].next_regno)
    continue;
  vd->e[i].next_regno = dr;

#ifdef ENABLE_CHECKING
  validate_value_data (vd);
#endif
}

/* Return true if a mode change from ORIG to NEW is allowed for REGNO.  */

static bool
mode_change_ok (enum machine_mode orig_mode, enum machine_mode new_mode,
		unsigned int regno ATTRIBUTE_UNUSED)
{
  if (GET_MODE_SIZE (orig_mode) < GET_MODE_SIZE (new_mode))
    return false;

#ifdef CANNOT_CHANGE_MODE_CLASS
  return !REG_CANNOT_CHANGE_MODE_P (regno, orig_mode, new_mode);
#endif

  return true;
}

/* Register REGNO was originally set in ORIG_MODE.  It - or a copy of it -
   was copied in COPY_MODE to COPY_REGNO, and then COPY_REGNO was accessed
   in NEW_MODE.
   Return a NEW_MODE rtx for REGNO if that's OK, otherwise return NULL_RTX.  */

static rtx
maybe_mode_change (enum machine_mode orig_mode, enum machine_mode copy_mode,
		   enum machine_mode new_mode, unsigned int regno,
		   unsigned int copy_regno ATTRIBUTE_UNUSED)
{
  if (orig_mode == new_mode)
    return gen_rtx_raw_REG (new_mode, regno);
  else if (mode_change_ok (orig_mode, new_mode, regno))
    {
      int copy_nregs = HARD_REGNO_NREGS (copy_regno, copy_mode);
      int use_nregs = HARD_REGNO_NREGS (copy_regno, new_mode);
      int copy_offset
	= GET_MODE_SIZE (copy_mode) / copy_nregs * (copy_nregs - use_nregs);
      int offset
	= GET_MODE_SIZE (orig_mode) - GET_MODE_SIZE (new_mode) - copy_offset;
      int byteoffset = offset % UNITS_PER_WORD;
      int wordoffset = offset - byteoffset;

      offset = ((WORDS_BIG_ENDIAN ? wordoffset : 0)
		+ (BYTES_BIG_ENDIAN ? byteoffset : 0));
      return gen_rtx_raw_REG (new_mode,
			      regno + subreg_regno_offset (regno, orig_mode,
							   offset,
							   new_mode));
    }
  return NULL_RTX;
}

/* Find the oldest copy of the value contained in REGNO that is in
   register class CLASS and has mode MODE.  If found, return an rtx
   of that oldest register, otherwise return NULL.  */

static rtx
find_oldest_value_reg (enum reg_class class, rtx reg, struct value_data *vd)
{
  unsigned int regno = REGNO (reg);
  enum machine_mode mode = GET_MODE (reg);
  unsigned int i;

  /* If we are accessing REG in some mode other that what we set it in,
     make sure that the replacement is valid.  In particular, consider
	(set (reg:DI r11) (...))
	(set (reg:SI r9) (reg:SI r11))
	(set (reg:SI r10) (...))
	(set (...) (reg:DI r9))
     Replacing r9 with r11 is invalid.  */
  if (mode != vd->e[regno].mode)
    {
      if (HARD_REGNO_NREGS (regno, mode)
	  > HARD_REGNO_NREGS (regno, vd->e[regno].mode))
	return NULL_RTX;
    }

  for (i = vd->e[regno].oldest_regno; i != regno; i = vd->e[i].next_regno)
    {
      enum machine_mode oldmode = vd->e[i].mode;
      rtx new;
      unsigned int last;

      for (last = i; last < i + HARD_REGNO_NREGS (i, mode); last++)
	if (!TEST_HARD_REG_BIT (reg_class_contents[class], last))
	  return NULL_RTX;

      new = maybe_mode_change (oldmode, vd->e[regno].mode, mode, i, regno);
      if (new)
	{
	  ORIGINAL_REGNO (new) = ORIGINAL_REGNO (reg);
	  REG_ATTRS (new) = REG_ATTRS (reg);
	  return new;
	}
    }

  return NULL_RTX;
}

/* If possible, replace the register at *LOC with the oldest register
   in register class CLASS.  Return true if successfully replaced.  */

static bool
replace_oldest_value_reg (rtx *loc, enum reg_class class, rtx insn,
			  struct value_data *vd)
{
  rtx new = find_oldest_value_reg (class, *loc, vd);
  if (new)
    {
      if (rtl_dump_file)
	fprintf (rtl_dump_file, "insn %u: replaced reg %u with %u\n",
		 INSN_UID (insn), REGNO (*loc), REGNO (new));

      *loc = new;
      return true;
    }
  return false;
}

/* Similar to replace_oldest_value_reg, but *LOC contains an address.
   Adapted from find_reloads_address_1.  CLASS is INDEX_REG_CLASS or
   BASE_REG_CLASS depending on how the register is being considered.  */

static bool
replace_oldest_value_addr (rtx *loc, enum reg_class class,
			   enum machine_mode mode, rtx insn,
			   struct value_data *vd)
{
  rtx x = *loc;
  RTX_CODE code = GET_CODE (x);
  const char *fmt;
  int i, j;
  bool changed = false;

  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;

	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);
	  }
	else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
		 || code1 == ZERO_EXTEND || code0 == MEM)
	  {
	    locI = &XEXP (x, 1);
	    locB = &XEXP (x, 0);
	  }
	else if (code0 == CONST_INT || code0 == CONST
		 || code0 == SYMBOL_REF || code0 == LABEL_REF)
	  locB = &XEXP (x, 1);
	else if (code1 == CONST_INT || code1 == CONST
		 || code1 == SYMBOL_REF || code1 == LABEL_REF)
	  locB = &XEXP (x, 0);
	else if (code0 == REG && code1 == REG)
	  {
	    int index_op;

	    if (REG_OK_FOR_INDEX_P (op0)
		&& REG_MODE_OK_FOR_BASE_P (op1, mode))
	      index_op = 0;
	    else if (REG_OK_FOR_INDEX_P (op1)
		     && REG_MODE_OK_FOR_BASE_P (op0, mode))
	      index_op = 1;
	    else if (REG_MODE_OK_FOR_BASE_P (op1, mode))
	      index_op = 0;
	    else if (REG_MODE_OK_FOR_BASE_P (op0, mode))
	      index_op = 1;
	    else if (REG_OK_FOR_INDEX_P (op1))
	      index_op = 1;
	    else
	      index_op = 0;

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

	if (locI)
	  changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, mode,
						insn, vd);
	if (locB)
	  changed |= replace_oldest_value_addr (locB,
						MODE_BASE_REG_CLASS (mode),
						mode, insn, vd);
	return changed;
      }

    case POST_INC:
    case POST_DEC:
    case POST_MODIFY:
    case PRE_INC:
    case PRE_DEC:
    case PRE_MODIFY:
      return false;

    case MEM:
      return replace_oldest_value_mem (x, insn, vd);

    case REG:
      return replace_oldest_value_reg (loc, class, insn, vd);

    default:
      break;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	changed |= replace_oldest_value_addr (&XEXP (x, i), class, mode,
					      insn, vd);
      else if (fmt[i] == 'E')
	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	  changed |= replace_oldest_value_addr (&XVECEXP (x, i, j), class,
						mode, insn, vd);
    }

  return changed;
}

/* Similar to replace_oldest_value_reg, but X contains a memory.  */

static bool
replace_oldest_value_mem (rtx x, rtx insn, struct value_data *vd)
{
  return replace_oldest_value_addr (&XEXP (x, 0),
				    MODE_BASE_REG_CLASS (GET_MODE (x)),
				    GET_MODE (x), insn, vd);
}

/* Perform the forward copy propagation on basic block BB.  */

static bool
copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
{
  bool changed = false;
  rtx insn;

  for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
    {
      int n_ops, i, alt, predicated;
      bool is_asm;
      rtx set;

      if (! INSN_P (insn))
	{
	  if (insn == BB_END (bb))
	    break;
	  else
	    continue;
	}

      set = single_set (insn);
      extract_insn (insn);
      if (! constrain_operands (1))
	fatal_insn_not_found (insn);
      preprocess_constraints ();
      alt = which_alternative;
      n_ops = recog_data.n_operands;
      is_asm = asm_noperands (PATTERN (insn)) >= 0;

      /* Simplify the code below by rewriting things to reflect
	 matching constraints.  Also promote OP_OUT to OP_INOUT
	 in predicated instructions.  */

      predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
      for (i = 0; i < n_ops; ++i)
	{
	  int matches = recog_op_alt[i][alt].matches;
	  if (matches >= 0)
	    recog_op_alt[i][alt].class = recog_op_alt[matches][alt].class;
	  if (matches >= 0 || recog_op_alt[i][alt].matched >= 0
	      || (predicated && recog_data.operand_type[i] == OP_OUT))
	    recog_data.operand_type[i] = OP_INOUT;
	}

      /* For each earlyclobber operand, zap the value data.  */
      for (i = 0; i < n_ops; i++)
	if (recog_op_alt[i][alt].earlyclobber)
	  kill_value (recog_data.operand[i], vd);

      /* Within asms, a clobber cannot overlap inputs or outputs.
	 I wouldn't think this were true for regular insns, but
	 scan_rtx treats them like that...  */
      note_stores (PATTERN (insn), kill_clobbered_value, vd);

      /* Kill all auto-incremented values.  */
      /* ??? REG_INC is useless, since stack pushes aren't done that way.  */
      for_each_rtx (&PATTERN (insn), kill_autoinc_value, vd);

      /* Kill all early-clobbered operands.  */
      for (i = 0; i < n_ops; i++)
	if (recog_op_alt[i][alt].earlyclobber)
	  kill_value (recog_data.operand[i], vd);

      /* Special-case plain move instructions, since we may well
	 be able to do the move from a different register class.  */
      if (set && REG_P (SET_SRC (set)))
	{
	  rtx src = SET_SRC (set);
	  unsigned int regno = REGNO (src);
	  enum machine_mode mode = GET_MODE (src);
	  unsigned int i;
	  rtx new;

	  /* If we are accessing SRC in some mode other that what we
	     set it in, make sure that the replacement is valid.  */
	  if (mode != vd->e[regno].mode)
	    {
	      if (HARD_REGNO_NREGS (regno, mode)
		  > HARD_REGNO_NREGS (regno, vd->e[regno].mode))
		goto no_move_special_case;
	    }

	  /* If the destination is also a register, try to find a source
	     register in the same class.  */
	  if (REG_P (SET_DEST (set)))
	    {
	      new = find_oldest_value_reg (REGNO_REG_CLASS (regno), src, vd);
	      if (new && validate_change (insn, &SET_SRC (set), new, 0))
		{
		  if (rtl_dump_file)
		    fprintf (rtl_dump_file,
			     "insn %u: replaced reg %u with %u\n",
			     INSN_UID (insn), regno, REGNO (new));
		  changed = true;
		  goto did_replacement;
		}
	    }

	  /* Otherwise, try all valid registers and see if its valid.  */
	  for (i = vd->e[regno].oldest_regno; i != regno;
	       i = vd->e[i].next_regno)
	    {
	      new = maybe_mode_change (vd->e[i].mode, vd->e[regno].mode,
				       mode, i, regno);
	      if (new != NULL_RTX)
		{
		  if (validate_change (insn, &SET_SRC (set), new, 0))
		    {
		      ORIGINAL_REGNO (new) = ORIGINAL_REGNO (src);
		      REG_ATTRS (new) = REG_ATTRS (src);
		      if (rtl_dump_file)
			fprintf (rtl_dump_file,
				 "insn %u: replaced reg %u with %u\n",
				 INSN_UID (insn), regno, REGNO (new));
		      changed = true;
		      goto did_replacement;
		    }
		}
	    }
	}
      no_move_special_case:

      /* For each input operand, replace a hard register with the
	 eldest live copy that's in an appropriate register class.  */
      for (i = 0; i < n_ops; i++)
	{
	  bool replaced = false;

	  /* 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[i][0] == '\0')
	    continue;

	  /* Don't replace in asms intentionally referencing hard regs.  */
	  if (is_asm && GET_CODE (recog_data.operand[i]) == REG
	      && (REGNO (recog_data.operand[i])
		  == ORIGINAL_REGNO (recog_data.operand[i])))
	    continue;

	  if (recog_data.operand_type[i] == OP_IN)
	    {
	      if (recog_op_alt[i][alt].is_address)
		replaced
		  = replace_oldest_value_addr (recog_data.operand_loc[i],
					       recog_op_alt[i][alt].class,
					       VOIDmode, insn, vd);
	      else if (REG_P (recog_data.operand[i]))
		replaced
		  = replace_oldest_value_reg (recog_data.operand_loc[i],
					      recog_op_alt[i][alt].class,
					      insn, vd);
	      else if (GET_CODE (recog_data.operand[i]) == MEM)
		replaced = replace_oldest_value_mem (recog_data.operand[i],
						     insn, vd);
	    }
	  else if (GET_CODE (recog_data.operand[i]) == MEM)
	    replaced = replace_oldest_value_mem (recog_data.operand[i],
						 insn, vd);

	  /* If we performed any replacement, update match_dups.  */
	  if (replaced)
	    {
	      int j;
	      rtx new;

	      changed = true;

	      new = *recog_data.operand_loc[i];
	      recog_data.operand[i] = new;
	      for (j = 0; j < recog_data.n_dups; j++)
		if (recog_data.dup_num[j] == i)
		  *recog_data.dup_loc[j] = new;
	    }
	}

    did_replacement:
      /* Clobber call-clobbered registers.  */
      if (GET_CODE (insn) == CALL_INSN)
	for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	  if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
	    kill_value_regno (i, vd);

      /* Notice stores.  */
      note_stores (PATTERN (insn), kill_set_value, vd);

      /* Notice copies.  */
      if (set && REG_P (SET_DEST (set)) && REG_P (SET_SRC (set)))
	copy_value (SET_DEST (set), SET_SRC (set), vd);

      if (insn == BB_END (bb))
	break;
    }

  return changed;
}

/* Main entry point for the forward copy propagation optimization.  */

void
copyprop_hardreg_forward (void)
{
  struct value_data *all_vd;
  bool need_refresh;
  basic_block bb, bbp = 0;

  need_refresh = false;

  all_vd = xmalloc (sizeof (struct value_data) * last_basic_block);

  FOR_EACH_BB (bb)
    {
      /* If a block has a single predecessor, that we've already
	 processed, begin with the value data that was live at
	 the end of the predecessor block.  */
      /* ??? Ought to use more intelligent queuing of blocks.  */
      if (bb->pred)
	for (bbp = bb; bbp && bbp != bb->pred->src; bbp = bbp->prev_bb);
      if (bb->pred
	  && ! bb->pred->pred_next
	  && ! (bb->pred->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
	  && bb->pred->src != ENTRY_BLOCK_PTR
	  && bbp)
	all_vd[bb->index] = all_vd[bb->pred->src->index];
      else
	init_value_data (all_vd + bb->index);

      if (copyprop_hardreg_forward_1 (bb, all_vd + bb->index))
	need_refresh = true;
    }

  if (need_refresh)
    {
      if (rtl_dump_file)
	fputs ("\n\n", rtl_dump_file);

      /* ??? Irritatingly, delete_noop_moves does not take a set of blocks
	 to scan, so we have to do a life update with no initial set of
	 blocks Just In Case.  */
      delete_noop_moves (get_insns ());
      update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
			PROP_DEATH_NOTES
			| PROP_SCAN_DEAD_CODE
			| PROP_KILL_DEAD_CODE);
    }

  free (all_vd);
}

/* Dump the value chain data to stderr.  */

void
debug_value_data (struct value_data *vd)
{
  HARD_REG_SET set;
  unsigned int i, j;

  CLEAR_HARD_REG_SET (set);

  for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
    if (vd->e[i].oldest_regno == i)
      {
	if (vd->e[i].mode == VOIDmode)
	  {
	    if (vd->e[i].next_regno != INVALID_REGNUM)
	      fprintf (stderr, "[%u] Bad next_regno for empty chain (%u)\n",
		       i, vd->e[i].next_regno);
	    continue;
	  }

	SET_HARD_REG_BIT (set, i);
	fprintf (stderr, "[%u %s] ", i, GET_MODE_NAME (vd->e[i].mode));

	for (j = vd->e[i].next_regno;
	     j != INVALID_REGNUM;
	     j = vd->e[j].next_regno)
	  {
	    if (TEST_HARD_REG_BIT (set, j))
	      {
		fprintf (stderr, "[%u] Loop in regno chain\n", j);
		return;
	      }

	    if (vd->e[j].oldest_regno != i)
	      {
		fprintf (stderr, "[%u] Bad oldest_regno (%u)\n",
			 j, vd->e[j].oldest_regno);
		return;
	      }
	    SET_HARD_REG_BIT (set, j);
	    fprintf (stderr, "[%u %s] ", j, GET_MODE_NAME (vd->e[j].mode));
	  }
	fputc ('\n', stderr);
      }

  for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
    if (! TEST_HARD_REG_BIT (set, i)
	&& (vd->e[i].mode != VOIDmode
	    || vd->e[i].oldest_regno != i
	    || vd->e[i].next_regno != INVALID_REGNUM))
      fprintf (stderr, "[%u] Non-empty reg in chain (%s %u %i)\n",
	       i, GET_MODE_NAME (vd->e[i].mode), vd->e[i].oldest_regno,
	       vd->e[i].next_regno);
}

#ifdef ENABLE_CHECKING
static void
validate_value_data (struct value_data *vd)
{
  HARD_REG_SET set;
  unsigned int i, j;

  CLEAR_HARD_REG_SET (set);

  for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
    if (vd->e[i].oldest_regno == i)
      {
	if (vd->e[i].mode == VOIDmode)
	  {
	    if (vd->e[i].next_regno != INVALID_REGNUM)
	      internal_error ("validate_value_data: [%u] Bad next_regno for empty chain (%u)",
			      i, vd->e[i].next_regno);
	    continue;
	  }

	SET_HARD_REG_BIT (set, i);

	for (j = vd->e[i].next_regno;
	     j != INVALID_REGNUM;
	     j = vd->e[j].next_regno)
	  {
	    if (TEST_HARD_REG_BIT (set, j))
	      internal_error ("validate_value_data: Loop in regno chain (%u)",
			      j);
	    if (vd->e[j].oldest_regno != i)
	      internal_error ("validate_value_data: [%u] Bad oldest_regno (%u)",
			      j, vd->e[j].oldest_regno);

	    SET_HARD_REG_BIT (set, j);
	  }
      }

  for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
    if (! TEST_HARD_REG_BIT (set, i)
	&& (vd->e[i].mode != VOIDmode
	    || vd->e[i].oldest_regno != i
	    || vd->e[i].next_regno != INVALID_REGNUM))
      internal_error ("validate_value_data: [%u] Non-empty reg in chain (%s %u %i)",
		      i, GET_MODE_NAME (vd->e[i].mode), vd->e[i].oldest_regno,
		      vd->e[i].next_regno);
}
#endif
