/* Common subexpression elimination for GNU compiler.
   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
   1999, 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.  */

#include "config.h"
/* stdio.h must precede rtl.h for FFS.  */
#include "system.h"
#include "coretypes.h"
#include "tm.h"

#include "rtl.h"
#include "tm_p.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "flags.h"
#include "real.h"
#include "insn-config.h"
#include "recog.h"
#include "function.h"
#include "expr.h"
#include "toplev.h"
#include "output.h"
#include "ggc.h"
#include "timevar.h"
#include "except.h"
#include "target.h"
#include "params.h"

/* The basic idea of common subexpression elimination is to go
   through the code, keeping a record of expressions that would
   have the same value at the current scan point, and replacing
   expressions encountered with the cheapest equivalent expression.

   It is too complicated to keep track of the different possibilities
   when control paths merge in this code; so, at each label, we forget all
   that is known and start fresh.  This can be described as processing each
   extended basic block separately.  We have a separate pass to perform
   global CSE.

   Note CSE can turn a conditional or computed jump into a nop or
   an unconditional jump.  When this occurs we arrange to run the jump
   optimizer after CSE to delete the unreachable code.

   We use two data structures to record the equivalent expressions:
   a hash table for most expressions, and a vector of "quantity
   numbers" to record equivalent (pseudo) registers.

   The use of the special data structure for registers is desirable
   because it is faster.  It is possible because registers references
   contain a fairly small number, the register number, taken from
   a contiguously allocated series, and two register references are
   identical if they have the same number.  General expressions
   do not have any such thing, so the only way to retrieve the
   information recorded on an expression other than a register
   is to keep it in a hash table.

Registers and "quantity numbers":

   At the start of each basic block, all of the (hardware and pseudo)
   registers used in the function are given distinct quantity
   numbers to indicate their contents.  During scan, when the code
   copies one register into another, we copy the quantity number.
   When a register is loaded in any other way, we allocate a new
   quantity number to describe the value generated by this operation.
   `reg_qty' records what quantity a register is currently thought
   of as containing.

   All real quantity numbers are greater than or equal to zero.
   If register N has not been assigned a quantity, reg_qty[N] will
   equal -N - 1, which is always negative.

   Quantity numbers below zero do not exist and none of the `qty_table'
   entries should be referenced with a negative index.

   We also maintain a bidirectional chain of registers for each
   quantity number.  The `qty_table` members `first_reg' and `last_reg',
   and `reg_eqv_table' members `next' and `prev' hold these chains.

   The first register in a chain is the one whose lifespan is least local.
   Among equals, it is the one that was seen first.
   We replace any equivalent register with that one.

   If two registers have the same quantity number, it must be true that
   REG expressions with qty_table `mode' must be in the hash table for both
   registers and must be in the same class.

   The converse is not true.  Since hard registers may be referenced in
   any mode, two REG expressions might be equivalent in the hash table
   but not have the same quantity number if the quantity number of one
   of the registers is not the same mode as those expressions.

Constants and quantity numbers

   When a quantity has a known constant value, that value is stored
   in the appropriate qty_table `const_rtx'.  This is in addition to
   putting the constant in the hash table as is usual for non-regs.

   Whether a reg or a constant is preferred is determined by the configuration
   macro CONST_COSTS and will often depend on the constant value.  In any
   event, expressions containing constants can be simplified, by fold_rtx.

   When a quantity has a known nearly constant value (such as an address
   of a stack slot), that value is stored in the appropriate qty_table
   `const_rtx'.

   Integer constants don't have a machine mode.  However, cse
   determines the intended machine mode from the destination
   of the instruction that moves the constant.  The machine mode
   is recorded in the hash table along with the actual RTL
   constant expression so that different modes are kept separate.

Other expressions:

   To record known equivalences among expressions in general
   we use a hash table called `table'.  It has a fixed number of buckets
   that contain chains of `struct table_elt' elements for expressions.
   These chains connect the elements whose expressions have the same
   hash codes.

   Other chains through the same elements connect the elements which
   currently have equivalent values.

   Register references in an expression are canonicalized before hashing
   the expression.  This is done using `reg_qty' and qty_table `first_reg'.
   The hash code of a register reference is computed using the quantity
   number, not the register number.

   When the value of an expression changes, it is necessary to remove from the
   hash table not just that expression but all expressions whose values
   could be different as a result.

     1. If the value changing is in memory, except in special cases
     ANYTHING referring to memory could be changed.  That is because
     nobody knows where a pointer does not point.
     The function `invalidate_memory' removes what is necessary.

     The special cases are when the address is constant or is
     a constant plus a fixed register such as the frame pointer
     or a static chain pointer.  When such addresses are stored in,
     we can tell exactly which other such addresses must be invalidated
     due to overlap.  `invalidate' does this.
     All expressions that refer to non-constant
     memory addresses are also invalidated.  `invalidate_memory' does this.

     2. If the value changing is a register, all expressions
     containing references to that register, and only those,
     must be removed.

   Because searching the entire hash table for expressions that contain
   a register is very slow, we try to figure out when it isn't necessary.
   Precisely, this is necessary only when expressions have been
   entered in the hash table using this register, and then the value has
   changed, and then another expression wants to be added to refer to
   the register's new value.  This sequence of circumstances is rare
   within any one basic block.

   The vectors `reg_tick' and `reg_in_table' are used to detect this case.
   reg_tick[i] is incremented whenever a value is stored in register i.
   reg_in_table[i] holds -1 if no references to register i have been
   entered in the table; otherwise, it contains the value reg_tick[i] had
   when the references were entered.  If we want to enter a reference
   and reg_in_table[i] != reg_tick[i], we must scan and remove old references.
   Until we want to enter a new entry, the mere fact that the two vectors
   don't match makes the entries be ignored if anyone tries to match them.

   Registers themselves are entered in the hash table as well as in
   the equivalent-register chains.  However, the vectors `reg_tick'
   and `reg_in_table' do not apply to expressions which are simple
   register references.  These expressions are removed from the table
   immediately when they become invalid, and this can be done even if
   we do not immediately search for all the expressions that refer to
   the register.

   A CLOBBER rtx in an instruction invalidates its operand for further
   reuse.  A CLOBBER or SET rtx whose operand is a MEM:BLK
   invalidates everything that resides in memory.

Related expressions:

   Constant expressions that differ only by an additive integer
   are called related.  When a constant expression is put in
   the table, the related expression with no constant term
   is also entered.  These are made to point at each other
   so that it is possible to find out if there exists any
   register equivalent to an expression related to a given expression.  */

/* One plus largest register number used in this function.  */

static int max_reg;

/* One plus largest instruction UID used in this function at time of
   cse_main call.  */

static int max_insn_uid;

/* Length of qty_table vector.  We know in advance we will not need
   a quantity number this big.  */

static int max_qty;

/* Next quantity number to be allocated.
   This is 1 + the largest number needed so far.  */

static int next_qty;

/* Per-qty information tracking.

   `first_reg' and `last_reg' track the head and tail of the
   chain of registers which currently contain this quantity.

   `mode' contains the machine mode of this quantity.

   `const_rtx' holds the rtx of the constant value of this
   quantity, if known.  A summations of the frame/arg pointer
   and a constant can also be entered here.  When this holds
   a known value, `const_insn' is the insn which stored the
   constant value.

   `comparison_{code,const,qty}' are used to track when a
   comparison between a quantity and some constant or register has
   been passed.  In such a case, we know the results of the comparison
   in case we see it again.  These members record a comparison that
   is known to be true.  `comparison_code' holds the rtx code of such
   a comparison, else it is set to UNKNOWN and the other two
   comparison members are undefined.  `comparison_const' holds
   the constant being compared against, or zero if the comparison
   is not against a constant.  `comparison_qty' holds the quantity
   being compared against when the result is known.  If the comparison
   is not with a register, `comparison_qty' is -1.  */

struct qty_table_elem
{
  rtx const_rtx;
  rtx const_insn;
  rtx comparison_const;
  int comparison_qty;
  unsigned int first_reg, last_reg;
  /* The sizes of these fields should match the sizes of the
     code and mode fields of struct rtx_def (see rtl.h).  */
  ENUM_BITFIELD(rtx_code) comparison_code : 16;
  ENUM_BITFIELD(machine_mode) mode : 8;
};

/* The table of all qtys, indexed by qty number.  */
static struct qty_table_elem *qty_table;

#ifdef HAVE_cc0
/* For machines that have a CC0, we do not record its value in the hash
   table since its use is guaranteed to be the insn immediately following
   its definition and any other insn is presumed to invalidate it.

   Instead, we store below the value last assigned to CC0.  If it should
   happen to be a constant, it is stored in preference to the actual
   assigned value.  In case it is a constant, we store the mode in which
   the constant should be interpreted.  */

static rtx prev_insn_cc0;
static enum machine_mode prev_insn_cc0_mode;

/* Previous actual insn.  0 if at first insn of basic block.  */

static rtx prev_insn;
#endif

/* Insn being scanned.  */

static rtx this_insn;

/* Index by register number, gives the number of the next (or
   previous) register in the chain of registers sharing the same
   value.

   Or -1 if this register is at the end of the chain.

   If reg_qty[N] == N, reg_eqv_table[N].next is undefined.  */

/* Per-register equivalence chain.  */
struct reg_eqv_elem
{
  int next, prev;
};

/* The table of all register equivalence chains.  */
static struct reg_eqv_elem *reg_eqv_table;

struct cse_reg_info
{
  /* Next in hash chain.  */
  struct cse_reg_info *hash_next;

  /* The next cse_reg_info structure in the free or used list.  */
  struct cse_reg_info *next;

  /* Search key */
  unsigned int regno;

  /* The quantity number of the register's current contents.  */
  int reg_qty;

  /* The number of times the register has been altered in the current
     basic block.  */
  int reg_tick;

  /* The REG_TICK value at which rtx's containing this register are
     valid in the hash table.  If this does not equal the current
     reg_tick value, such expressions existing in the hash table are
     invalid.  */
  int reg_in_table;

  /* The SUBREG that was set when REG_TICK was last incremented.  Set
     to -1 if the last store was to the whole register, not a subreg.  */
  unsigned int subreg_ticked;
};

/* A free list of cse_reg_info entries.  */
static struct cse_reg_info *cse_reg_info_free_list;

/* A used list of cse_reg_info entries.  */
static struct cse_reg_info *cse_reg_info_used_list;
static struct cse_reg_info *cse_reg_info_used_list_end;

/* A mapping from registers to cse_reg_info data structures.  */
#define REGHASH_SHIFT	7
#define REGHASH_SIZE	(1 << REGHASH_SHIFT)
#define REGHASH_MASK	(REGHASH_SIZE - 1)
static struct cse_reg_info *reg_hash[REGHASH_SIZE];

#define REGHASH_FN(REGNO)	\
	(((REGNO) ^ ((REGNO) >> REGHASH_SHIFT)) & REGHASH_MASK)

/* The last lookup we did into the cse_reg_info_tree.  This allows us
   to cache repeated lookups.  */
static unsigned int cached_regno;
static struct cse_reg_info *cached_cse_reg_info;

/* A HARD_REG_SET containing all the hard registers for which there is
   currently a REG expression in the hash table.  Note the difference
   from the above variables, which indicate if the REG is mentioned in some
   expression in the table.  */

static HARD_REG_SET hard_regs_in_table;

/* CUID of insn that starts the basic block currently being cse-processed.  */

static int cse_basic_block_start;

/* CUID of insn that ends the basic block currently being cse-processed.  */

static int cse_basic_block_end;

/* Vector mapping INSN_UIDs to cuids.
   The cuids are like uids but increase monotonically always.
   We use them to see whether a reg is used outside a given basic block.  */

static int *uid_cuid;

/* Highest UID in UID_CUID.  */
static int max_uid;

/* Get the cuid of an insn.  */

#define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])

/* Nonzero if this pass has made changes, and therefore it's
   worthwhile to run the garbage collector.  */

static int cse_altered;

/* Nonzero if cse has altered conditional jump insns
   in such a way that jump optimization should be redone.  */

static int cse_jumps_altered;

/* Nonzero if we put a LABEL_REF into the hash table for an INSN without a
   REG_LABEL, we have to rerun jump after CSE to put in the note.  */
static int recorded_label_ref;

/* canon_hash stores 1 in do_not_record
   if it notices a reference to CC0, PC, or some other volatile
   subexpression.  */

static int do_not_record;

#ifdef LOAD_EXTEND_OP

/* Scratch rtl used when looking for load-extended copy of a MEM.  */
static rtx memory_extend_rtx;
#endif

/* canon_hash stores 1 in hash_arg_in_memory
   if it notices a reference to memory within the expression being hashed.  */

static int hash_arg_in_memory;

/* The hash table contains buckets which are chains of `struct table_elt's,
   each recording one expression's information.
   That expression is in the `exp' field.

   The canon_exp field contains a canonical (from the point of view of
   alias analysis) version of the `exp' field.

   Those elements with the same hash code are chained in both directions
   through the `next_same_hash' and `prev_same_hash' fields.

   Each set of expressions with equivalent values
   are on a two-way chain through the `next_same_value'
   and `prev_same_value' fields, and all point with
   the `first_same_value' field at the first element in
   that chain.  The chain is in order of increasing cost.
   Each element's cost value is in its `cost' field.

   The `in_memory' field is nonzero for elements that
   involve any reference to memory.  These elements are removed
   whenever a write is done to an unidentified location in memory.
   To be safe, we assume that a memory address is unidentified unless
   the address is either a symbol constant or a constant plus
   the frame pointer or argument pointer.

   The `related_value' field is used to connect related expressions
   (that differ by adding an integer).
   The related expressions are chained in a circular fashion.
   `related_value' is zero for expressions for which this
   chain is not useful.

   The `cost' field stores the cost of this element's expression.
   The `regcost' field stores the value returned by approx_reg_cost for
   this element's expression.

   The `is_const' flag is set if the element is a constant (including
   a fixed address).

   The `flag' field is used as a temporary during some search routines.

   The `mode' field is usually the same as GET_MODE (`exp'), but
   if `exp' is a CONST_INT and has no machine mode then the `mode'
   field is the mode it was being used as.  Each constant is
   recorded separately for each mode it is used with.  */

struct table_elt
{
  rtx exp;
  rtx canon_exp;
  struct table_elt *next_same_hash;
  struct table_elt *prev_same_hash;
  struct table_elt *next_same_value;
  struct table_elt *prev_same_value;
  struct table_elt *first_same_value;
  struct table_elt *related_value;
  int cost;
  int regcost;
  /* The size of this field should match the size
     of the mode field of struct rtx_def (see rtl.h).  */
  ENUM_BITFIELD(machine_mode) mode : 8;
  char in_memory;
  char is_const;
  char flag;
};

/* We don't want a lot of buckets, because we rarely have very many
   things stored in the hash table, and a lot of buckets slows
   down a lot of loops that happen frequently.  */
#define HASH_SHIFT	5
#define HASH_SIZE	(1 << HASH_SHIFT)
#define HASH_MASK	(HASH_SIZE - 1)

/* Compute hash code of X in mode M.  Special-case case where X is a pseudo
   register (hard registers may require `do_not_record' to be set).  */

#define HASH(X, M)	\
 ((GET_CODE (X) == REG && REGNO (X) >= FIRST_PSEUDO_REGISTER	\
  ? (((unsigned) REG << 7) + (unsigned) REG_QTY (REGNO (X)))	\
  : canon_hash (X, M)) & HASH_MASK)

/* Determine whether register number N is considered a fixed register for the
   purpose of approximating register costs.
   It is desirable to replace other regs with fixed regs, to reduce need for
   non-fixed hard regs.
   A reg wins if it is either the frame pointer or designated as fixed.  */
#define FIXED_REGNO_P(N)  \
  ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \
   || fixed_regs[N] || global_regs[N])

/* Compute cost of X, as stored in the `cost' field of a table_elt.  Fixed
   hard registers and pointers into the frame are the cheapest with a cost
   of 0.  Next come pseudos with a cost of one and other hard registers with
   a cost of 2.  Aside from these special cases, call `rtx_cost'.  */

#define CHEAP_REGNO(N) \
  ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM	\
   || (N) == STACK_POINTER_REGNUM || (N) == ARG_POINTER_REGNUM		\
   || ((N) >= FIRST_VIRTUAL_REGISTER && (N) <= LAST_VIRTUAL_REGISTER)	\
   || ((N) < FIRST_PSEUDO_REGISTER					\
       && FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS))

#define COST(X) (GET_CODE (X) == REG ? 0 : notreg_cost (X, SET))
#define COST_IN(X,OUTER) (GET_CODE (X) == REG ? 0 : notreg_cost (X, OUTER))

/* Get the info associated with register N.  */

#define GET_CSE_REG_INFO(N)			\
  (((N) == cached_regno && cached_cse_reg_info)	\
   ? cached_cse_reg_info : get_cse_reg_info ((N)))

/* Get the number of times this register has been updated in this
   basic block.  */

#define REG_TICK(N) ((GET_CSE_REG_INFO (N))->reg_tick)

/* Get the point at which REG was recorded in the table.  */

#define REG_IN_TABLE(N) ((GET_CSE_REG_INFO (N))->reg_in_table)

/* Get the SUBREG set at the last increment to REG_TICK (-1 if not a
   SUBREG).  */

#define SUBREG_TICKED(N) ((GET_CSE_REG_INFO (N))->subreg_ticked)

/* Get the quantity number for REG.  */

#define REG_QTY(N) ((GET_CSE_REG_INFO (N))->reg_qty)

/* Determine if the quantity number for register X represents a valid index
   into the qty_table.  */

#define REGNO_QTY_VALID_P(N) (REG_QTY (N) >= 0)

static struct table_elt *table[HASH_SIZE];

/* Chain of `struct table_elt's made so far for this function
   but currently removed from the table.  */

static struct table_elt *free_element_chain;

/* Number of `struct table_elt' structures made so far for this function.  */

static int n_elements_made;

/* Maximum value `n_elements_made' has had so far in this compilation
   for functions previously processed.  */

static int max_elements_made;

/* Surviving equivalence class when two equivalence classes are merged
   by recording the effects of a jump in the last insn.  Zero if the
   last insn was not a conditional jump.  */

static struct table_elt *last_jump_equiv_class;

/* Set to the cost of a constant pool reference if one was found for a
   symbolic constant.  If this was found, it means we should try to
   convert constants into constant pool entries if they don't fit in
   the insn.  */

static int constant_pool_entries_cost;
static int constant_pool_entries_regcost;

/* This data describes a block that will be processed by cse_basic_block.  */

struct cse_basic_block_data
{
  /* Lowest CUID value of insns in block.  */
  int low_cuid;
  /* Highest CUID value of insns in block.  */
  int high_cuid;
  /* Total number of SETs in block.  */
  int nsets;
  /* Last insn in the block.  */
  rtx last;
  /* Size of current branch path, if any.  */
  int path_size;
  /* Current branch path, indicating which branches will be taken.  */
  struct branch_path
    {
      /* The branch insn.  */
      rtx branch;
      /* Whether it should be taken or not.  AROUND is the same as taken
	 except that it is used when the destination label is not preceded
       by a BARRIER.  */
      enum taken {TAKEN, NOT_TAKEN, AROUND} status;
    } *path;
};

static bool fixed_base_plus_p (rtx x);
static int notreg_cost (rtx, enum rtx_code);
static int approx_reg_cost_1 (rtx *, void *);
static int approx_reg_cost (rtx);
static int preferrable (int, int, int, int);
static void new_basic_block (void);
static void make_new_qty (unsigned int, enum machine_mode);
static void make_regs_eqv (unsigned int, unsigned int);
static void delete_reg_equiv (unsigned int);
static int mention_regs (rtx);
static int insert_regs (rtx, struct table_elt *, int);
static void remove_from_table (struct table_elt *, unsigned);
static struct table_elt *lookup	(rtx, unsigned, enum machine_mode);
static struct table_elt *lookup_for_remove (rtx, unsigned, enum machine_mode);
static rtx lookup_as_function (rtx, enum rtx_code);
static struct table_elt *insert (rtx, struct table_elt *, unsigned,
				 enum machine_mode);
static void merge_equiv_classes (struct table_elt *, struct table_elt *);
static void invalidate (rtx, enum machine_mode);
static int cse_rtx_varies_p (rtx, int);
static void remove_invalid_refs (unsigned int);
static void remove_invalid_subreg_refs (unsigned int, unsigned int,
					enum machine_mode);
static void rehash_using_reg (rtx);
static void invalidate_memory (void);
static void invalidate_for_call (void);
static rtx use_related_value (rtx, struct table_elt *);
static unsigned canon_hash (rtx, enum machine_mode);
static unsigned canon_hash_string (const char *);
static unsigned safe_hash (rtx, enum machine_mode);
static int exp_equiv_p (rtx, rtx, int, int);
static rtx canon_reg (rtx, rtx);
static void find_best_addr (rtx, rtx *, enum machine_mode);
static enum rtx_code find_comparison_args (enum rtx_code, rtx *, rtx *,
					   enum machine_mode *,
					   enum machine_mode *);
static rtx fold_rtx (rtx, rtx);
static rtx equiv_constant (rtx);
static void record_jump_equiv (rtx, int);
static void record_jump_cond (enum rtx_code, enum machine_mode, rtx, rtx,
			      int);
static void cse_insn (rtx, rtx);
static int addr_affects_sp_p (rtx);
static void invalidate_from_clobbers (rtx);
static rtx cse_process_notes (rtx, rtx);
static void cse_around_loop (rtx);
static void invalidate_skipped_set (rtx, rtx, void *);
static void invalidate_skipped_block (rtx);
static void cse_check_loop_start (rtx, rtx, void *);
static void cse_set_around_loop (rtx, rtx, rtx);
static rtx cse_basic_block (rtx, rtx, struct branch_path *, int);
static void count_reg_usage (rtx, int *, int);
static int check_for_label_ref (rtx *, void *);
extern void dump_class (struct table_elt*);
static struct cse_reg_info * get_cse_reg_info (unsigned int);
static int check_dependence (rtx *, void *);

static void flush_hash_table (void);
static bool insn_live_p (rtx, int *);
static bool set_live_p (rtx, rtx, int *);
static bool dead_libcall_p (rtx, int *);
static int cse_change_cc_mode (rtx *, void *);
static void cse_change_cc_mode_insns (rtx, rtx, rtx);
static enum machine_mode cse_cc_succs (basic_block, rtx, rtx, bool);

/* Nonzero if X has the form (PLUS frame-pointer integer).  We check for
   virtual regs here because the simplify_*_operation routines are called
   by integrate.c, which is called before virtual register instantiation.  */

static bool
fixed_base_plus_p (rtx x)
{
  switch (GET_CODE (x))
    {
    case REG:
      if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx)
	return true;
      if (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM])
	return true;
      if (REGNO (x) >= FIRST_VIRTUAL_REGISTER
	  && REGNO (x) <= LAST_VIRTUAL_REGISTER)
	return true;
      return false;

    case PLUS:
      if (GET_CODE (XEXP (x, 1)) != CONST_INT)
	return false;
      return fixed_base_plus_p (XEXP (x, 0));

    case ADDRESSOF:
      return true;

    default:
      return false;
    }
}

/* Dump the expressions in the equivalence class indicated by CLASSP.
   This function is used only for debugging.  */
void
dump_class (struct table_elt *classp)
{
  struct table_elt *elt;

  fprintf (stderr, "Equivalence chain for ");
  print_rtl (stderr, classp->exp);
  fprintf (stderr, ": \n");

  for (elt = classp->first_same_value; elt; elt = elt->next_same_value)
    {
      print_rtl (stderr, elt->exp);
      fprintf (stderr, "\n");
    }
}

/* Subroutine of approx_reg_cost; called through for_each_rtx.  */

static int
approx_reg_cost_1 (rtx *xp, void *data)
{
  rtx x = *xp;
  int *cost_p = data;

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

      if (! CHEAP_REGNO (regno))
	{
	  if (regno < FIRST_PSEUDO_REGISTER)
	    {
	      if (SMALL_REGISTER_CLASSES)
		return 1;
	      *cost_p += 2;
	    }
	  else
	    *cost_p += 1;
	}
    }

  return 0;
}

/* Return an estimate of the cost of the registers used in an rtx.
   This is mostly the number of different REG expressions in the rtx;
   however for some exceptions like fixed registers we use a cost of
   0.  If any other hard register reference occurs, return MAX_COST.  */

static int
approx_reg_cost (rtx x)
{
  int cost = 0;

  if (for_each_rtx (&x, approx_reg_cost_1, (void *) &cost))
    return MAX_COST;

  return cost;
}

/* Return a negative value if an rtx A, whose costs are given by COST_A
   and REGCOST_A, is more desirable than an rtx B.
   Return a positive value if A is less desirable, or 0 if the two are
   equally good.  */
static int
preferrable (int cost_a, int regcost_a, int cost_b, int regcost_b)
{
  /* First, get rid of cases involving expressions that are entirely
     unwanted.  */
  if (cost_a != cost_b)
    {
      if (cost_a == MAX_COST)
	return 1;
      if (cost_b == MAX_COST)
	return -1;
    }

  /* Avoid extending lifetimes of hardregs.  */
  if (regcost_a != regcost_b)
    {
      if (regcost_a == MAX_COST)
	return 1;
      if (regcost_b == MAX_COST)
	return -1;
    }

  /* Normal operation costs take precedence.  */
  if (cost_a != cost_b)
    return cost_a - cost_b;
  /* Only if these are identical consider effects on register pressure.  */
  if (regcost_a != regcost_b)
    return regcost_a - regcost_b;
  return 0;
}

/* Internal function, to compute cost when X is not a register; called
   from COST macro to keep it simple.  */

static int
notreg_cost (rtx x, enum rtx_code outer)
{
  return ((GET_CODE (x) == SUBREG
	   && GET_CODE (SUBREG_REG (x)) == REG
	   && GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
	   && GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_INT
	   && (GET_MODE_SIZE (GET_MODE (x))
	       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
	   && subreg_lowpart_p (x)
	   && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (x)),
				     GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))))
	  ? 0
	  : rtx_cost (x, outer) * 2);
}

/* Return an estimate of the cost of computing rtx X.
   One use is in cse, to decide which expression to keep in the hash table.
   Another is in rtl generation, to pick the cheapest way to multiply.
   Other uses like the latter are expected in the future.  */

int
rtx_cost (rtx x, enum rtx_code outer_code ATTRIBUTE_UNUSED)
{
  int i, j;
  enum rtx_code code;
  const char *fmt;
  int total;

  if (x == 0)
    return 0;

  /* Compute the default costs of certain things.
     Note that targetm.rtx_costs can override the defaults.  */

  code = GET_CODE (x);
  switch (code)
    {
    case MULT:
      total = COSTS_N_INSNS (5);
      break;
    case DIV:
    case UDIV:
    case MOD:
    case UMOD:
      total = COSTS_N_INSNS (7);
      break;
    case USE:
      /* Used in loop.c and combine.c as a marker.  */
      total = 0;
      break;
    default:
      total = COSTS_N_INSNS (1);
    }

  switch (code)
    {
    case REG:
      return 0;

    case SUBREG:
      /* If we can't tie these modes, make this expensive.  The larger
	 the mode, the more expensive it is.  */
      if (! MODES_TIEABLE_P (GET_MODE (x), GET_MODE (SUBREG_REG (x))))
	return COSTS_N_INSNS (2
			      + GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD);
      break;

    default:
      if ((*targetm.rtx_costs) (x, code, outer_code, &total))
	return total;
      break;
    }

  /* Sum the costs of the sub-rtx's, plus cost of this operation,
     which is already in total.  */

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    if (fmt[i] == 'e')
      total += rtx_cost (XEXP (x, i), code);
    else if (fmt[i] == 'E')
      for (j = 0; j < XVECLEN (x, i); j++)
	total += rtx_cost (XVECEXP (x, i, j), code);

  return total;
}

/* Return cost of address expression X.
   Expect that X is properly formed address reference.  */

int
address_cost (rtx x, enum machine_mode mode)
{
  /* The address_cost target hook does not deal with ADDRESSOF nodes.  But,
     during CSE, such nodes are present.  Using an ADDRESSOF node which
     refers to the address of a REG is a good thing because we can then
     turn (MEM (ADDRESSSOF (REG))) into just plain REG.  */

  if (GET_CODE (x) == ADDRESSOF && REG_P (XEXP ((x), 0)))
    return -1;

  /* We may be asked for cost of various unusual addresses, such as operands
     of push instruction.  It is not worthwhile to complicate writing
     of the target hook by such cases.  */

  if (!memory_address_p (mode, x))
    return 1000;

  return (*targetm.address_cost) (x);
}

/* If the target doesn't override, compute the cost as with arithmetic.  */

int
default_address_cost (rtx x)
{
  return rtx_cost (x, MEM);
}

static struct cse_reg_info *
get_cse_reg_info (unsigned int regno)
{
  struct cse_reg_info **hash_head = &reg_hash[REGHASH_FN (regno)];
  struct cse_reg_info *p;

  for (p = *hash_head; p != NULL; p = p->hash_next)
    if (p->regno == regno)
      break;

  if (p == NULL)
    {
      /* Get a new cse_reg_info structure.  */
      if (cse_reg_info_free_list)
	{
	  p = cse_reg_info_free_list;
	  cse_reg_info_free_list = p->next;
	}
      else
	p = xmalloc (sizeof (struct cse_reg_info));

      /* Insert into hash table.  */
      p->hash_next = *hash_head;
      *hash_head = p;

      /* Initialize it.  */
      p->reg_tick = 1;
      p->reg_in_table = -1;
      p->subreg_ticked = -1;
      p->reg_qty = -regno - 1;
      p->regno = regno;
      p->next = cse_reg_info_used_list;
      cse_reg_info_used_list = p;
      if (!cse_reg_info_used_list_end)
	cse_reg_info_used_list_end = p;
    }

  /* Cache this lookup; we tend to be looking up information about the
     same register several times in a row.  */
  cached_regno = regno;
  cached_cse_reg_info = p;

  return p;
}

/* Clear the hash table and initialize each register with its own quantity,
   for a new basic block.  */

static void
new_basic_block (void)
{
  int i;

  next_qty = 0;

  /* Clear out hash table state for this pass.  */

  memset (reg_hash, 0, sizeof reg_hash);

  if (cse_reg_info_used_list)
    {
      cse_reg_info_used_list_end->next = cse_reg_info_free_list;
      cse_reg_info_free_list = cse_reg_info_used_list;
      cse_reg_info_used_list = cse_reg_info_used_list_end = 0;
    }
  cached_cse_reg_info = 0;

  CLEAR_HARD_REG_SET (hard_regs_in_table);

  /* The per-quantity values used to be initialized here, but it is
     much faster to initialize each as it is made in `make_new_qty'.  */

  for (i = 0; i < HASH_SIZE; i++)
    {
      struct table_elt *first;

      first = table[i];
      if (first != NULL)
	{
	  struct table_elt *last = first;

	  table[i] = NULL;

	  while (last->next_same_hash != NULL)
	    last = last->next_same_hash;

	  /* Now relink this hash entire chain into
	     the free element list.  */

	  last->next_same_hash = free_element_chain;
	  free_element_chain = first;
	}
    }

#ifdef HAVE_cc0
  prev_insn = 0;
  prev_insn_cc0 = 0;
#endif
}

/* Say that register REG contains a quantity in mode MODE not in any
   register before and initialize that quantity.  */

static void
make_new_qty (unsigned int reg, enum machine_mode mode)
{
  int q;
  struct qty_table_elem *ent;
  struct reg_eqv_elem *eqv;

  if (next_qty >= max_qty)
    abort ();

  q = REG_QTY (reg) = next_qty++;
  ent = &qty_table[q];
  ent->first_reg = reg;
  ent->last_reg = reg;
  ent->mode = mode;
  ent->const_rtx = ent->const_insn = NULL_RTX;
  ent->comparison_code = UNKNOWN;

  eqv = &reg_eqv_table[reg];
  eqv->next = eqv->prev = -1;
}

/* Make reg NEW equivalent to reg OLD.
   OLD is not changing; NEW is.  */

static void
make_regs_eqv (unsigned int new, unsigned int old)
{
  unsigned int lastr, firstr;
  int q = REG_QTY (old);
  struct qty_table_elem *ent;

  ent = &qty_table[q];

  /* Nothing should become eqv until it has a "non-invalid" qty number.  */
  if (! REGNO_QTY_VALID_P (old))
    abort ();

  REG_QTY (new) = q;
  firstr = ent->first_reg;
  lastr = ent->last_reg;

  /* Prefer fixed hard registers to anything.  Prefer pseudo regs to other
     hard regs.  Among pseudos, if NEW will live longer than any other reg
     of the same qty, and that is beyond the current basic block,
     make it the new canonical replacement for this qty.  */
  if (! (firstr < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (firstr))
      /* Certain fixed registers might be of the class NO_REGS.  This means
	 that not only can they not be allocated by the compiler, but
	 they cannot be used in substitutions or canonicalizations
	 either.  */
      && (new >= FIRST_PSEUDO_REGISTER || REGNO_REG_CLASS (new) != NO_REGS)
      && ((new < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (new))
	  || (new >= FIRST_PSEUDO_REGISTER
	      && (firstr < FIRST_PSEUDO_REGISTER
		  || ((uid_cuid[REGNO_LAST_UID (new)] > cse_basic_block_end
		       || (uid_cuid[REGNO_FIRST_UID (new)]
			   < cse_basic_block_start))
		      && (uid_cuid[REGNO_LAST_UID (new)]
			  > uid_cuid[REGNO_LAST_UID (firstr)]))))))
    {
      reg_eqv_table[firstr].prev = new;
      reg_eqv_table[new].next = firstr;
      reg_eqv_table[new].prev = -1;
      ent->first_reg = new;
    }
  else
    {
      /* If NEW is a hard reg (known to be non-fixed), insert at end.
	 Otherwise, insert before any non-fixed hard regs that are at the
	 end.  Registers of class NO_REGS cannot be used as an
	 equivalent for anything.  */
      while (lastr < FIRST_PSEUDO_REGISTER && reg_eqv_table[lastr].prev >= 0
	     && (REGNO_REG_CLASS (lastr) == NO_REGS || ! FIXED_REGNO_P (lastr))
	     && new >= FIRST_PSEUDO_REGISTER)
	lastr = reg_eqv_table[lastr].prev;
      reg_eqv_table[new].next = reg_eqv_table[lastr].next;
      if (reg_eqv_table[lastr].next >= 0)
	reg_eqv_table[reg_eqv_table[lastr].next].prev = new;
      else
	qty_table[q].last_reg = new;
      reg_eqv_table[lastr].next = new;
      reg_eqv_table[new].prev = lastr;
    }
}

/* Remove REG from its equivalence class.  */

static void
delete_reg_equiv (unsigned int reg)
{
  struct qty_table_elem *ent;
  int q = REG_QTY (reg);
  int p, n;

  /* If invalid, do nothing.  */
  if (! REGNO_QTY_VALID_P (reg))
    return;

  ent = &qty_table[q];

  p = reg_eqv_table[reg].prev;
  n = reg_eqv_table[reg].next;

  if (n != -1)
    reg_eqv_table[n].prev = p;
  else
    ent->last_reg = p;
  if (p != -1)
    reg_eqv_table[p].next = n;
  else
    ent->first_reg = n;

  REG_QTY (reg) = -reg - 1;
}

/* Remove any invalid expressions from the hash table
   that refer to any of the registers contained in expression X.

   Make sure that newly inserted references to those registers
   as subexpressions will be considered valid.

   mention_regs is not called when a register itself
   is being stored in the table.

   Return 1 if we have done something that may have changed the hash code
   of X.  */

static int
mention_regs (rtx x)
{
  enum rtx_code code;
  int i, j;
  const char *fmt;
  int changed = 0;

  if (x == 0)
    return 0;

  code = GET_CODE (x);
  if (code == REG)
    {
      unsigned int regno = REGNO (x);
      unsigned int endregno
	= regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
		   : HARD_REGNO_NREGS (regno, GET_MODE (x)));
      unsigned int i;

      for (i = regno; i < endregno; i++)
	{
	  if (REG_IN_TABLE (i) >= 0 && REG_IN_TABLE (i) != REG_TICK (i))
	    remove_invalid_refs (i);

	  REG_IN_TABLE (i) = REG_TICK (i);
	  SUBREG_TICKED (i) = -1;
	}

      return 0;
    }

  /* If this is a SUBREG, we don't want to discard other SUBREGs of the same
     pseudo if they don't use overlapping words.  We handle only pseudos
     here for simplicity.  */
  if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG
      && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
    {
      unsigned int i = REGNO (SUBREG_REG (x));

      if (REG_IN_TABLE (i) >= 0 && REG_IN_TABLE (i) != REG_TICK (i))
	{
	  /* If REG_IN_TABLE (i) differs from REG_TICK (i) by one, and
	     the last store to this register really stored into this
	     subreg, then remove the memory of this subreg.
	     Otherwise, remove any memory of the entire register and
	     all its subregs from the table.  */
	  if (REG_TICK (i) - REG_IN_TABLE (i) > 1
	      || SUBREG_TICKED (i) != REGNO (SUBREG_REG (x)))
	    remove_invalid_refs (i);
	  else
	    remove_invalid_subreg_refs (i, SUBREG_BYTE (x), GET_MODE (x));
	}

      REG_IN_TABLE (i) = REG_TICK (i);
      SUBREG_TICKED (i) = REGNO (SUBREG_REG (x));
      return 0;
    }

  /* If X is a comparison or a COMPARE and either operand is a register
     that does not have a quantity, give it one.  This is so that a later
     call to record_jump_equiv won't cause X to be assigned a different
     hash code and not found in the table after that call.

     It is not necessary to do this here, since rehash_using_reg can
     fix up the table later, but doing this here eliminates the need to
     call that expensive function in the most common case where the only
     use of the register is in the comparison.  */

  if (code == COMPARE || GET_RTX_CLASS (code) == '<')
    {
      if (GET_CODE (XEXP (x, 0)) == REG
	  && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))))
	if (insert_regs (XEXP (x, 0), NULL, 0))
	  {
	    rehash_using_reg (XEXP (x, 0));
	    changed = 1;
	  }

      if (GET_CODE (XEXP (x, 1)) == REG
	  && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))))
	if (insert_regs (XEXP (x, 1), NULL, 0))
	  {
	    rehash_using_reg (XEXP (x, 1));
	    changed = 1;
	  }
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    if (fmt[i] == 'e')
      changed |= mention_regs (XEXP (x, i));
    else if (fmt[i] == 'E')
      for (j = 0; j < XVECLEN (x, i); j++)
	changed |= mention_regs (XVECEXP (x, i, j));

  return changed;
}

/* Update the register quantities for inserting X into the hash table
   with a value equivalent to CLASSP.
   (If the class does not contain a REG, it is irrelevant.)
   If MODIFIED is nonzero, X is a destination; it is being modified.
   Note that delete_reg_equiv should be called on a register
   before insert_regs is done on that register with MODIFIED != 0.

   Nonzero value means that elements of reg_qty have changed
   so X's hash code may be different.  */

static int
insert_regs (rtx x, struct table_elt *classp, int modified)
{
  if (GET_CODE (x) == REG)
    {
      unsigned int regno = REGNO (x);
      int qty_valid;

      /* If REGNO is in the equivalence table already but is of the
	 wrong mode for that equivalence, don't do anything here.  */

      qty_valid = REGNO_QTY_VALID_P (regno);
      if (qty_valid)
	{
	  struct qty_table_elem *ent = &qty_table[REG_QTY (regno)];

	  if (ent->mode != GET_MODE (x))
	    return 0;
	}

      if (modified || ! qty_valid)
	{
	  if (classp)
	    for (classp = classp->first_same_value;
		 classp != 0;
		 classp = classp->next_same_value)
	      if (GET_CODE (classp->exp) == REG
		  && GET_MODE (classp->exp) == GET_MODE (x))
		{
		  make_regs_eqv (regno, REGNO (classp->exp));
		  return 1;
		}

	  /* Mention_regs for a SUBREG checks if REG_TICK is exactly one larger
	     than REG_IN_TABLE to find out if there was only a single preceding
	     invalidation - for the SUBREG - or another one, which would be
	     for the full register.  However, if we find here that REG_TICK
	     indicates that the register is invalid, it means that it has
	     been invalidated in a separate operation.  The SUBREG might be used
	     now (then this is a recursive call), or we might use the full REG
	     now and a SUBREG of it later.  So bump up REG_TICK so that
	     mention_regs will do the right thing.  */
	  if (! modified
	      && REG_IN_TABLE (regno) >= 0
	      && REG_TICK (regno) == REG_IN_TABLE (regno) + 1)
	    REG_TICK (regno)++;
	  make_new_qty (regno, GET_MODE (x));
	  return 1;
	}

      return 0;
    }

  /* If X is a SUBREG, we will likely be inserting the inner register in the
     table.  If that register doesn't have an assigned quantity number at
     this point but does later, the insertion that we will be doing now will
     not be accessible because its hash code will have changed.  So assign
     a quantity number now.  */

  else if (GET_CODE (x) == SUBREG && GET_CODE (SUBREG_REG (x)) == REG
	   && ! REGNO_QTY_VALID_P (REGNO (SUBREG_REG (x))))
    {
      insert_regs (SUBREG_REG (x), NULL, 0);
      mention_regs (x);
      return 1;
    }
  else
    return mention_regs (x);
}

/* Look in or update the hash table.  */

/* Remove table element ELT from use in the table.
   HASH is its hash code, made using the HASH macro.
   It's an argument because often that is known in advance
   and we save much time not recomputing it.  */

static void
remove_from_table (struct table_elt *elt, unsigned int hash)
{
  if (elt == 0)
    return;

  /* Mark this element as removed.  See cse_insn.  */
  elt->first_same_value = 0;

  /* Remove the table element from its equivalence class.  */

  {
    struct table_elt *prev = elt->prev_same_value;
    struct table_elt *next = elt->next_same_value;

    if (next)
      next->prev_same_value = prev;

    if (prev)
      prev->next_same_value = next;
    else
      {
	struct table_elt *newfirst = next;
	while (next)
	  {
	    next->first_same_value = newfirst;
	    next = next->next_same_value;
	  }
      }
  }

  /* Remove the table element from its hash bucket.  */

  {
    struct table_elt *prev = elt->prev_same_hash;
    struct table_elt *next = elt->next_same_hash;

    if (next)
      next->prev_same_hash = prev;

    if (prev)
      prev->next_same_hash = next;
    else if (table[hash] == elt)
      table[hash] = next;
    else
      {
	/* This entry is not in the proper hash bucket.  This can happen
	   when two classes were merged by `merge_equiv_classes'.  Search
	   for the hash bucket that it heads.  This happens only very
	   rarely, so the cost is acceptable.  */
	for (hash = 0; hash < HASH_SIZE; hash++)
	  if (table[hash] == elt)
	    table[hash] = next;
      }
  }

  /* Remove the table element from its related-value circular chain.  */

  if (elt->related_value != 0 && elt->related_value != elt)
    {
      struct table_elt *p = elt->related_value;

      while (p->related_value != elt)
	p = p->related_value;
      p->related_value = elt->related_value;
      if (p->related_value == p)
	p->related_value = 0;
    }

  /* Now add it to the free element chain.  */
  elt->next_same_hash = free_element_chain;
  free_element_chain = elt;
}

/* Look up X in the hash table and return its table element,
   or 0 if X is not in the table.

   MODE is the machine-mode of X, or if X is an integer constant
   with VOIDmode then MODE is the mode with which X will be used.

   Here we are satisfied to find an expression whose tree structure
   looks like X.  */

static struct table_elt *
lookup (rtx x, unsigned int hash, enum machine_mode mode)
{
  struct table_elt *p;

  for (p = table[hash]; p; p = p->next_same_hash)
    if (mode == p->mode && ((x == p->exp && GET_CODE (x) == REG)
			    || exp_equiv_p (x, p->exp, GET_CODE (x) != REG, 0)))
      return p;

  return 0;
}

/* Like `lookup' but don't care whether the table element uses invalid regs.
   Also ignore discrepancies in the machine mode of a register.  */

static struct table_elt *
lookup_for_remove (rtx x, unsigned int hash, enum machine_mode mode)
{
  struct table_elt *p;

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

      /* Don't check the machine mode when comparing registers;
	 invalidating (REG:SI 0) also invalidates (REG:DF 0).  */
      for (p = table[hash]; p; p = p->next_same_hash)
	if (GET_CODE (p->exp) == REG
	    && REGNO (p->exp) == regno)
	  return p;
    }
  else
    {
      for (p = table[hash]; p; p = p->next_same_hash)
	if (mode == p->mode && (x == p->exp || exp_equiv_p (x, p->exp, 0, 0)))
	  return p;
    }

  return 0;
}

/* Look for an expression equivalent to X and with code CODE.
   If one is found, return that expression.  */

static rtx
lookup_as_function (rtx x, enum rtx_code code)
{
  struct table_elt *p
    = lookup (x, safe_hash (x, VOIDmode) & HASH_MASK, GET_MODE (x));

  /* If we are looking for a CONST_INT, the mode doesn't really matter, as
     long as we are narrowing.  So if we looked in vain for a mode narrower
     than word_mode before, look for word_mode now.  */
  if (p == 0 && code == CONST_INT
      && GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (word_mode))
    {
      x = copy_rtx (x);
      PUT_MODE (x, word_mode);
      p = lookup (x, safe_hash (x, VOIDmode) & HASH_MASK, word_mode);
    }

  if (p == 0)
    return 0;

  for (p = p->first_same_value; p; p = p->next_same_value)
    if (GET_CODE (p->exp) == code
	/* Make sure this is a valid entry in the table.  */
	&& exp_equiv_p (p->exp, p->exp, 1, 0))
      return p->exp;

  return 0;
}

/* Insert X in the hash table, assuming HASH is its hash code
   and CLASSP is an element of the class it should go in
   (or 0 if a new class should be made).
   It is inserted at the proper position to keep the class in
   the order cheapest first.

   MODE is the machine-mode of X, or if X is an integer constant
   with VOIDmode then MODE is the mode with which X will be used.

   For elements of equal cheapness, the most recent one
   goes in front, except that the first element in the list
   remains first unless a cheaper element is added.  The order of
   pseudo-registers does not matter, as canon_reg will be called to
   find the cheapest when a register is retrieved from the table.

   The in_memory field in the hash table element is set to 0.
   The caller must set it nonzero if appropriate.

   You should call insert_regs (X, CLASSP, MODIFY) before calling here,
   and if insert_regs returns a nonzero value
   you must then recompute its hash code before calling here.

   If necessary, update table showing constant values of quantities.  */

#define CHEAPER(X, Y) \
 (preferrable ((X)->cost, (X)->regcost, (Y)->cost, (Y)->regcost) < 0)

static struct table_elt *
insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mode)
{
  struct table_elt *elt;

  /* If X is a register and we haven't made a quantity for it,
     something is wrong.  */
  if (GET_CODE (x) == REG && ! REGNO_QTY_VALID_P (REGNO (x)))
    abort ();

  /* If X is a hard register, show it is being put in the table.  */
  if (GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
    {
      unsigned int regno = REGNO (x);
      unsigned int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
      unsigned int i;

      for (i = regno; i < endregno; i++)
	SET_HARD_REG_BIT (hard_regs_in_table, i);
    }

  /* Put an element for X into the right hash bucket.  */

  elt = free_element_chain;
  if (elt)
    free_element_chain = elt->next_same_hash;
  else
    {
      n_elements_made++;
      elt = xmalloc (sizeof (struct table_elt));
    }

  elt->exp = x;
  elt->canon_exp = NULL_RTX;
  elt->cost = COST (x);
  elt->regcost = approx_reg_cost (x);
  elt->next_same_value = 0;
  elt->prev_same_value = 0;
  elt->next_same_hash = table[hash];
  elt->prev_same_hash = 0;
  elt->related_value = 0;
  elt->in_memory = 0;
  elt->mode = mode;
  elt->is_const = (CONSTANT_P (x)
		   /* GNU C++ takes advantage of this for `this'
		      (and other const values).  */
		   || (GET_CODE (x) == REG
		       && RTX_UNCHANGING_P (x)
		       && REGNO (x) >= FIRST_PSEUDO_REGISTER)
		   || fixed_base_plus_p (x));

  if (table[hash])
    table[hash]->prev_same_hash = elt;
  table[hash] = elt;

  /* Put it into the proper value-class.  */
  if (classp)
    {
      classp = classp->first_same_value;
      if (CHEAPER (elt, classp))
	/* Insert at the head of the class.  */
	{
	  struct table_elt *p;
	  elt->next_same_value = classp;
	  classp->prev_same_value = elt;
	  elt->first_same_value = elt;

	  for (p = classp; p; p = p->next_same_value)
	    p->first_same_value = elt;
	}
      else
	{
	  /* Insert not at head of the class.  */
	  /* Put it after the last element cheaper than X.  */
	  struct table_elt *p, *next;

	  for (p = classp; (next = p->next_same_value) && CHEAPER (next, elt);
	       p = next);

	  /* Put it after P and before NEXT.  */
	  elt->next_same_value = next;
	  if (next)
	    next->prev_same_value = elt;

	  elt->prev_same_value = p;
	  p->next_same_value = elt;
	  elt->first_same_value = classp;
	}
    }
  else
    elt->first_same_value = elt;

  /* If this is a constant being set equivalent to a register or a register
     being set equivalent to a constant, note the constant equivalence.

     If this is a constant, it cannot be equivalent to a different constant,
     and a constant is the only thing that can be cheaper than a register.  So
     we know the register is the head of the class (before the constant was
     inserted).

     If this is a register that is not already known equivalent to a
     constant, we must check the entire class.

     If this is a register that is already known equivalent to an insn,
     update the qtys `const_insn' to show that `this_insn' is the latest
     insn making that quantity equivalent to the constant.  */

  if (elt->is_const && classp && GET_CODE (classp->exp) == REG
      && GET_CODE (x) != REG)
    {
      int exp_q = REG_QTY (REGNO (classp->exp));
      struct qty_table_elem *exp_ent = &qty_table[exp_q];

      exp_ent->const_rtx = gen_lowpart_if_possible (exp_ent->mode, x);
      exp_ent->const_insn = this_insn;
    }

  else if (GET_CODE (x) == REG
	   && classp
	   && ! qty_table[REG_QTY (REGNO (x))].const_rtx
	   && ! elt->is_const)
    {
      struct table_elt *p;

      for (p = classp; p != 0; p = p->next_same_value)
	{
	  if (p->is_const && GET_CODE (p->exp) != REG)
	    {
	      int x_q = REG_QTY (REGNO (x));
	      struct qty_table_elem *x_ent = &qty_table[x_q];

	      x_ent->const_rtx
		= gen_lowpart_if_possible (GET_MODE (x), p->exp);
	      x_ent->const_insn = this_insn;
	      break;
	    }
	}
    }

  else if (GET_CODE (x) == REG
	   && qty_table[REG_QTY (REGNO (x))].const_rtx
	   && GET_MODE (x) == qty_table[REG_QTY (REGNO (x))].mode)
    qty_table[REG_QTY (REGNO (x))].const_insn = this_insn;

  /* If this is a constant with symbolic value,
     and it has a term with an explicit integer value,
     link it up with related expressions.  */
  if (GET_CODE (x) == CONST)
    {
      rtx subexp = get_related_value (x);
      unsigned subhash;
      struct table_elt *subelt, *subelt_prev;

      if (subexp != 0)
	{
	  /* Get the integer-free subexpression in the hash table.  */
	  subhash = safe_hash (subexp, mode) & HASH_MASK;
	  subelt = lookup (subexp, subhash, mode);
	  if (subelt == 0)
	    subelt = insert (subexp, NULL, subhash, mode);
	  /* Initialize SUBELT's circular chain if it has none.  */
	  if (subelt->related_value == 0)
	    subelt->related_value = subelt;
	  /* Find the element in the circular chain that precedes SUBELT.  */
	  subelt_prev = subelt;
	  while (subelt_prev->related_value != subelt)
	    subelt_prev = subelt_prev->related_value;
	  /* Put new ELT into SUBELT's circular chain just before SUBELT.
	     This way the element that follows SUBELT is the oldest one.  */
	  elt->related_value = subelt_prev->related_value;
	  subelt_prev->related_value = elt;
	}
    }

  return elt;
}

/* Given two equivalence classes, CLASS1 and CLASS2, put all the entries from
   CLASS2 into CLASS1.  This is done when we have reached an insn which makes
   the two classes equivalent.

   CLASS1 will be the surviving class; CLASS2 should not be used after this
   call.

   Any invalid entries in CLASS2 will not be copied.  */

static void
merge_equiv_classes (struct table_elt *class1, struct table_elt *class2)
{
  struct table_elt *elt, *next, *new;

  /* Ensure we start with the head of the classes.  */
  class1 = class1->first_same_value;
  class2 = class2->first_same_value;

  /* If they were already equal, forget it.  */
  if (class1 == class2)
    return;

  for (elt = class2; elt; elt = next)
    {
      unsigned int hash;
      rtx exp = elt->exp;
      enum machine_mode mode = elt->mode;

      next = elt->next_same_value;

      /* Remove old entry, make a new one in CLASS1's class.
	 Don't do this for invalid entries as we cannot find their
	 hash code (it also isn't necessary).  */
      if (GET_CODE (exp) == REG || exp_equiv_p (exp, exp, 1, 0))
	{
	  bool need_rehash = false;

	  hash_arg_in_memory = 0;
	  hash = HASH (exp, mode);

	  if (GET_CODE (exp) == REG)
	    {
	      need_rehash = REGNO_QTY_VALID_P (REGNO (exp));
	      delete_reg_equiv (REGNO (exp));
	    }

	  remove_from_table (elt, hash);

	  if (insert_regs (exp, class1, 0) || need_rehash)
	    {
	      rehash_using_reg (exp);
	      hash = HASH (exp, mode);
	    }
	  new = insert (exp, class1, hash, mode);
	  new->in_memory = hash_arg_in_memory;
	}
    }
}

/* Flush the entire hash table.  */

static void
flush_hash_table (void)
{
  int i;
  struct table_elt *p;

  for (i = 0; i < HASH_SIZE; i++)
    for (p = table[i]; p; p = table[i])
      {
	/* Note that invalidate can remove elements
	   after P in the current hash chain.  */
	if (GET_CODE (p->exp) == REG)
	  invalidate (p->exp, p->mode);
	else
	  remove_from_table (p, i);
      }
}

/* Function called for each rtx to check whether true dependence exist.  */
struct check_dependence_data
{
  enum machine_mode mode;
  rtx exp;
  rtx addr;
};

static int
check_dependence (rtx *x, void *data)
{
  struct check_dependence_data *d = (struct check_dependence_data *) data;
  if (*x && GET_CODE (*x) == MEM)
    return canon_true_dependence (d->exp, d->mode, d->addr, *x,
		    		  cse_rtx_varies_p);
  else
    return 0;
}

/* Remove from the hash table, or mark as invalid, all expressions whose
   values could be altered by storing in X.  X is a register, a subreg, or
   a memory reference with nonvarying address (because, when a memory
   reference with a varying address is stored in, all memory references are
   removed by invalidate_memory so specific invalidation is superfluous).
   FULL_MODE, if not VOIDmode, indicates that this much should be
   invalidated instead of just the amount indicated by the mode of X.  This
   is only used for bitfield stores into memory.

   A nonvarying address may be just a register or just a symbol reference,
   or it may be either of those plus a numeric offset.  */

static void
invalidate (rtx x, enum machine_mode full_mode)
{
  int i;
  struct table_elt *p;
  rtx addr;

  switch (GET_CODE (x))
    {
    case REG:
      {
	/* If X is a register, dependencies on its contents are recorded
	   through the qty number mechanism.  Just change the qty number of
	   the register, mark it as invalid for expressions that refer to it,
	   and remove it itself.  */
	unsigned int regno = REGNO (x);
	unsigned int hash = HASH (x, GET_MODE (x));

	/* Remove REGNO from any quantity list it might be on and indicate
	   that its value might have changed.  If it is a pseudo, remove its
	   entry from the hash table.

	   For a hard register, we do the first two actions above for any
	   additional hard registers corresponding to X.  Then, if any of these
	   registers are in the table, we must remove any REG entries that
	   overlap these registers.  */

	delete_reg_equiv (regno);
	REG_TICK (regno)++;
	SUBREG_TICKED (regno) = -1;

	if (regno >= FIRST_PSEUDO_REGISTER)
	  {
	    /* Because a register can be referenced in more than one mode,
	       we might have to remove more than one table entry.  */
	    struct table_elt *elt;

	    while ((elt = lookup_for_remove (x, hash, GET_MODE (x))))
	      remove_from_table (elt, hash);
	  }
	else
	  {
	    HOST_WIDE_INT in_table
	      = TEST_HARD_REG_BIT (hard_regs_in_table, regno);
	    unsigned int endregno
	      = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
	    unsigned int tregno, tendregno, rn;
	    struct table_elt *p, *next;

	    CLEAR_HARD_REG_BIT (hard_regs_in_table, regno);

	    for (rn = regno + 1; rn < endregno; rn++)
	      {
		in_table |= TEST_HARD_REG_BIT (hard_regs_in_table, rn);
		CLEAR_HARD_REG_BIT (hard_regs_in_table, rn);
		delete_reg_equiv (rn);
		REG_TICK (rn)++;
		SUBREG_TICKED (rn) = -1;
	      }

	    if (in_table)
	      for (hash = 0; hash < HASH_SIZE; hash++)
		for (p = table[hash]; p; p = next)
		  {
		    next = p->next_same_hash;

		    if (GET_CODE (p->exp) != REG
			|| REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
		      continue;

		    tregno = REGNO (p->exp);
		    tendregno
		      = tregno + HARD_REGNO_NREGS (tregno, GET_MODE (p->exp));
		    if (tendregno > regno && tregno < endregno)
		      remove_from_table (p, hash);
		  }
	  }
      }
      return;

    case SUBREG:
      invalidate (SUBREG_REG (x), VOIDmode);
      return;

    case PARALLEL:
      for (i = XVECLEN (x, 0) - 1; i >= 0; --i)
	invalidate (XVECEXP (x, 0, i), VOIDmode);
      return;

    case EXPR_LIST:
      /* This is part of a disjoint return value; extract the location in
	 question ignoring the offset.  */
      invalidate (XEXP (x, 0), VOIDmode);
      return;

    case MEM:
      addr = canon_rtx (get_addr (XEXP (x, 0)));
      /* Calculate the canonical version of X here so that
	 true_dependence doesn't generate new RTL for X on each call.  */
      x = canon_rtx (x);

      /* Remove all hash table elements that refer to overlapping pieces of
	 memory.  */
      if (full_mode == VOIDmode)
	full_mode = GET_MODE (x);

      for (i = 0; i < HASH_SIZE; i++)
	{
	  struct table_elt *next;

	  for (p = table[i]; p; p = next)
	    {
	      next = p->next_same_hash;
	      if (p->in_memory)
		{
		  struct check_dependence_data d;

		  /* Just canonicalize the expression once;
		     otherwise each time we call invalidate
		     true_dependence will canonicalize the
		     expression again.  */
		  if (!p->canon_exp)
		    p->canon_exp = canon_rtx (p->exp);
		  d.exp = x;
		  d.addr = addr;
		  d.mode = full_mode;
		  if (for_each_rtx (&p->canon_exp, check_dependence, &d))
		    remove_from_table (p, i);
		}
	    }
	}
      return;

    default:
      abort ();
    }
}

/* Remove all expressions that refer to register REGNO,
   since they are already invalid, and we are about to
   mark that register valid again and don't want the old
   expressions to reappear as valid.  */

static void
remove_invalid_refs (unsigned int regno)
{
  unsigned int i;
  struct table_elt *p, *next;

  for (i = 0; i < HASH_SIZE; i++)
    for (p = table[i]; p; p = next)
      {
	next = p->next_same_hash;
	if (GET_CODE (p->exp) != REG
	    && refers_to_regno_p (regno, regno + 1, p->exp, (rtx *) 0))
	  remove_from_table (p, i);
      }
}

/* Likewise for a subreg with subreg_reg REGNO, subreg_byte OFFSET,
   and mode MODE.  */
static void
remove_invalid_subreg_refs (unsigned int regno, unsigned int offset,
			    enum machine_mode mode)
{
  unsigned int i;
  struct table_elt *p, *next;
  unsigned int end = offset + (GET_MODE_SIZE (mode) - 1);

  for (i = 0; i < HASH_SIZE; i++)
    for (p = table[i]; p; p = next)
      {
	rtx exp = p->exp;
	next = p->next_same_hash;

	if (GET_CODE (exp) != REG
	    && (GET_CODE (exp) != SUBREG
		|| GET_CODE (SUBREG_REG (exp)) != REG
		|| REGNO (SUBREG_REG (exp)) != regno
		|| (((SUBREG_BYTE (exp)
		      + (GET_MODE_SIZE (GET_MODE (exp)) - 1)) >= offset)
		    && SUBREG_BYTE (exp) <= end))
	    && refers_to_regno_p (regno, regno + 1, p->exp, (rtx *) 0))
	  remove_from_table (p, i);
      }
}

/* Recompute the hash codes of any valid entries in the hash table that
   reference X, if X is a register, or SUBREG_REG (X) if X is a SUBREG.

   This is called when we make a jump equivalence.  */

static void
rehash_using_reg (rtx x)
{
  unsigned int i;
  struct table_elt *p, *next;
  unsigned hash;

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

  /* If X is not a register or if the register is known not to be in any
     valid entries in the table, we have no work to do.  */

  if (GET_CODE (x) != REG
      || REG_IN_TABLE (REGNO (x)) < 0
      || REG_IN_TABLE (REGNO (x)) != REG_TICK (REGNO (x)))
    return;

  /* Scan all hash chains looking for valid entries that mention X.
     If we find one and it is in the wrong hash chain, move it.  */

  for (i = 0; i < HASH_SIZE; i++)
    for (p = table[i]; p; p = next)
      {
	next = p->next_same_hash;
	if (reg_mentioned_p (x, p->exp)
	    && exp_equiv_p (p->exp, p->exp, 1, 0)
	    && i != (hash = safe_hash (p->exp, p->mode) & HASH_MASK))
	  {
	    if (p->next_same_hash)
	      p->next_same_hash->prev_same_hash = p->prev_same_hash;

	    if (p->prev_same_hash)
	      p->prev_same_hash->next_same_hash = p->next_same_hash;
	    else
	      table[i] = p->next_same_hash;

	    p->next_same_hash = table[hash];
	    p->prev_same_hash = 0;
	    if (table[hash])
	      table[hash]->prev_same_hash = p;
	    table[hash] = p;
	  }
      }
}

/* Remove from the hash table any expression that is a call-clobbered
   register.  Also update their TICK values.  */

static void
invalidate_for_call (void)
{
  unsigned int regno, endregno;
  unsigned int i;
  unsigned hash;
  struct table_elt *p, *next;
  int in_table = 0;

  /* Go through all the hard registers.  For each that is clobbered in
     a CALL_INSN, remove the register from quantity chains and update
     reg_tick if defined.  Also see if any of these registers is currently
     in the table.  */

  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
      {
	delete_reg_equiv (regno);
	if (REG_TICK (regno) >= 0)
	  {
	    REG_TICK (regno)++;
	    SUBREG_TICKED (regno) = -1;
	  }

	in_table |= (TEST_HARD_REG_BIT (hard_regs_in_table, regno) != 0);
      }

  /* In the case where we have no call-clobbered hard registers in the
     table, we are done.  Otherwise, scan the table and remove any
     entry that overlaps a call-clobbered register.  */

  if (in_table)
    for (hash = 0; hash < HASH_SIZE; hash++)
      for (p = table[hash]; p; p = next)
	{
	  next = p->next_same_hash;

	  if (GET_CODE (p->exp) != REG
	      || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
	    continue;

	  regno = REGNO (p->exp);
	  endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (p->exp));

	  for (i = regno; i < endregno; i++)
	    if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
	      {
		remove_from_table (p, hash);
		break;
	      }
	}
}

/* Given an expression X of type CONST,
   and ELT which is its table entry (or 0 if it
   is not in the hash table),
   return an alternate expression for X as a register plus integer.
   If none can be found, return 0.  */

static rtx
use_related_value (rtx x, struct table_elt *elt)
{
  struct table_elt *relt = 0;
  struct table_elt *p, *q;
  HOST_WIDE_INT offset;

  /* First, is there anything related known?
     If we have a table element, we can tell from that.
     Otherwise, must look it up.  */

  if (elt != 0 && elt->related_value != 0)
    relt = elt;
  else if (elt == 0 && GET_CODE (x) == CONST)
    {
      rtx subexp = get_related_value (x);
      if (subexp != 0)
	relt = lookup (subexp,
		       safe_hash (subexp, GET_MODE (subexp)) & HASH_MASK,
		       GET_MODE (subexp));
    }

  if (relt == 0)
    return 0;

  /* Search all related table entries for one that has an
     equivalent register.  */

  p = relt;
  while (1)
    {
      /* This loop is strange in that it is executed in two different cases.
	 The first is when X is already in the table.  Then it is searching
	 the RELATED_VALUE list of X's class (RELT).  The second case is when
	 X is not in the table.  Then RELT points to a class for the related
	 value.

	 Ensure that, whatever case we are in, that we ignore classes that have
	 the same value as X.  */

      if (rtx_equal_p (x, p->exp))
	q = 0;
      else
	for (q = p->first_same_value; q; q = q->next_same_value)
	  if (GET_CODE (q->exp) == REG)
	    break;

      if (q)
	break;

      p = p->related_value;

      /* We went all the way around, so there is nothing to be found.
	 Alternatively, perhaps RELT was in the table for some other reason
	 and it has no related values recorded.  */
      if (p == relt || p == 0)
	break;
    }

  if (q == 0)
    return 0;

  offset = (get_integer_term (x) - get_integer_term (p->exp));
  /* Note: OFFSET may be 0 if P->xexp and X are related by commutativity.  */
  return plus_constant (q->exp, offset);
}

/* Hash a string.  Just add its bytes up.  */
static inline unsigned
canon_hash_string (const char *ps)
{
  unsigned hash = 0;
  const unsigned char *p = (const unsigned char *) ps;

  if (p)
    while (*p)
      hash += *p++;

  return hash;
}

/* Hash an rtx.  We are careful to make sure the value is never negative.
   Equivalent registers hash identically.
   MODE is used in hashing for CONST_INTs only;
   otherwise the mode of X is used.

   Store 1 in do_not_record if any subexpression is volatile.

   Store 1 in hash_arg_in_memory if X contains a MEM rtx
   which does not have the RTX_UNCHANGING_P bit set.

   Note that cse_insn knows that the hash code of a MEM expression
   is just (int) MEM plus the hash code of the address.  */

static unsigned
canon_hash (rtx x, enum machine_mode mode)
{
  int i, j;
  unsigned hash = 0;
  enum rtx_code code;
  const char *fmt;

  /* repeat is used to turn tail-recursion into iteration.  */
 repeat:
  if (x == 0)
    return hash;

  code = GET_CODE (x);
  switch (code)
    {
    case REG:
      {
	unsigned int regno = REGNO (x);
	bool record;

	/* On some machines, we can't record any non-fixed hard register,
	   because extending its life will cause reload problems.  We
	   consider ap, fp, sp, gp to be fixed for this purpose.

	   We also consider CCmode registers to be fixed for this purpose;
	   failure to do so leads to failure to simplify 0<100 type of
	   conditionals.

	   On all machines, we can't record any global registers.
	   Nor should we record any register that is in a small
	   class, as defined by CLASS_LIKELY_SPILLED_P.  */

	if (regno >= FIRST_PSEUDO_REGISTER)
	  record = true;
	else if (x == frame_pointer_rtx
		 || x == hard_frame_pointer_rtx
		 || x == arg_pointer_rtx
		 || x == stack_pointer_rtx
		 || x == pic_offset_table_rtx)
	  record = true;
	else if (global_regs[regno])
	  record = false;
	else if (fixed_regs[regno])
	  record = true;
	else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC)
	  record = true;
	else if (SMALL_REGISTER_CLASSES)
	  record = false;
	else if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno)))
	  record = false;
	else
	  record = true;

	if (!record)
	  {
	    do_not_record = 1;
	    return 0;
	  }

	hash += ((unsigned) REG << 7) + (unsigned) REG_QTY (regno);
	return hash;
      }

    /* We handle SUBREG of a REG specially because the underlying
       reg changes its hash value with every value change; we don't
       want to have to forget unrelated subregs when one subreg changes.  */
    case SUBREG:
      {
	if (GET_CODE (SUBREG_REG (x)) == REG)
	  {
	    hash += (((unsigned) SUBREG << 7)
		     + REGNO (SUBREG_REG (x))
		     + (SUBREG_BYTE (x) / UNITS_PER_WORD));
	    return hash;
	  }
	break;
      }

    case CONST_INT:
      {
	unsigned HOST_WIDE_INT tem = INTVAL (x);
	hash += ((unsigned) CONST_INT << 7) + (unsigned) mode + tem;
	return hash;
      }

    case CONST_DOUBLE:
      /* This is like the general case, except that it only counts
	 the integers representing the constant.  */
      hash += (unsigned) code + (unsigned) GET_MODE (x);
      if (GET_MODE (x) != VOIDmode)
	hash += real_hash (CONST_DOUBLE_REAL_VALUE (x));
      else
	hash += ((unsigned) CONST_DOUBLE_LOW (x)
		 + (unsigned) CONST_DOUBLE_HIGH (x));
      return hash;

    case CONST_VECTOR:
      {
	int units;
	rtx elt;

	units = CONST_VECTOR_NUNITS (x);

	for (i = 0; i < units; ++i)
	  {
	    elt = CONST_VECTOR_ELT (x, i);
	    hash += canon_hash (elt, GET_MODE (elt));
	  }

	return hash;
      }

      /* Assume there is only one rtx object for any given label.  */
    case LABEL_REF:
      hash += ((unsigned) LABEL_REF << 7) + (unsigned long) XEXP (x, 0);
      return hash;

    case SYMBOL_REF:
      hash += ((unsigned) SYMBOL_REF << 7) + (unsigned long) XSTR (x, 0);
      return hash;

    case MEM:
      /* We don't record if marked volatile or if BLKmode since we don't
	 know the size of the move.  */
      if (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode)
	{
	  do_not_record = 1;
	  return 0;
	}
      if (! RTX_UNCHANGING_P (x) || fixed_base_plus_p (XEXP (x, 0)))
	hash_arg_in_memory = 1;

      /* Now that we have already found this special case,
	 might as well speed it up as much as possible.  */
      hash += (unsigned) MEM;
      x = XEXP (x, 0);
      goto repeat;

    case USE:
      /* A USE that mentions non-volatile memory needs special
	 handling since the MEM may be BLKmode which normally
	 prevents an entry from being made.  Pure calls are
	 marked by a USE which mentions BLKmode memory.  */
      if (GET_CODE (XEXP (x, 0)) == MEM
	  && ! MEM_VOLATILE_P (XEXP (x, 0)))
	{
	  hash += (unsigned) USE;
	  x = XEXP (x, 0);

	  if (! RTX_UNCHANGING_P (x) || fixed_base_plus_p (XEXP (x, 0)))
	    hash_arg_in_memory = 1;

	  /* Now that we have already found this special case,
	     might as well speed it up as much as possible.  */
	  hash += (unsigned) MEM;
	  x = XEXP (x, 0);
	  goto repeat;
	}
      break;

    case PRE_DEC:
    case PRE_INC:
    case POST_DEC:
    case POST_INC:
    case PRE_MODIFY:
    case POST_MODIFY:
    case PC:
    case CC0:
    case CALL:
    case UNSPEC_VOLATILE:
      do_not_record = 1;
      return 0;

    case ASM_OPERANDS:
      if (MEM_VOLATILE_P (x))
	{
	  do_not_record = 1;
	  return 0;
	}
      else
	{
	  /* We don't want to take the filename and line into account.  */
	  hash += (unsigned) code + (unsigned) GET_MODE (x)
	    + canon_hash_string (ASM_OPERANDS_TEMPLATE (x))
	    + canon_hash_string (ASM_OPERANDS_OUTPUT_CONSTRAINT (x))
	    + (unsigned) ASM_OPERANDS_OUTPUT_IDX (x);

	  if (ASM_OPERANDS_INPUT_LENGTH (x))
	    {
	      for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
		{
		  hash += (canon_hash (ASM_OPERANDS_INPUT (x, i),
				       GET_MODE (ASM_OPERANDS_INPUT (x, i)))
			   + canon_hash_string (ASM_OPERANDS_INPUT_CONSTRAINT
						(x, i)));
		}

	      hash += canon_hash_string (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0));
	      x = ASM_OPERANDS_INPUT (x, 0);
	      mode = GET_MODE (x);
	      goto repeat;
	    }

	  return hash;
	}
      break;

    default:
      break;
    }

  i = GET_RTX_LENGTH (code) - 1;
  hash += (unsigned) code + (unsigned) GET_MODE (x);
  fmt = GET_RTX_FORMAT (code);
  for (; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	{
	  rtx tem = XEXP (x, i);

	  /* If we are about to do the last recursive call
	     needed at this level, change it into iteration.
	     This function  is called enough to be worth it.  */
	  if (i == 0)
	    {
	      x = tem;
	      goto repeat;
	    }
	  hash += canon_hash (tem, 0);
	}
      else if (fmt[i] == 'E')
	for (j = 0; j < XVECLEN (x, i); j++)
	  hash += canon_hash (XVECEXP (x, i, j), 0);
      else if (fmt[i] == 's')
	hash += canon_hash_string (XSTR (x, i));
      else if (fmt[i] == 'i')
	{
	  unsigned tem = XINT (x, i);
	  hash += tem;
	}
      else if (fmt[i] == '0' || fmt[i] == 't')
	/* Unused.  */
	;
      else
	abort ();
    }
  return hash;
}

/* Like canon_hash but with no side effects.  */

static unsigned
safe_hash (rtx x, enum machine_mode mode)
{
  int save_do_not_record = do_not_record;
  int save_hash_arg_in_memory = hash_arg_in_memory;
  unsigned hash = canon_hash (x, mode);
  hash_arg_in_memory = save_hash_arg_in_memory;
  do_not_record = save_do_not_record;
  return hash;
}

/* Return 1 iff X and Y would canonicalize into the same thing,
   without actually constructing the canonicalization of either one.
   If VALIDATE is nonzero,
   we assume X is an expression being processed from the rtl
   and Y was found in the hash table.  We check register refs
   in Y for being marked as valid.

   If EQUAL_VALUES is nonzero, we allow a register to match a constant value
   that is known to be in the register.  Ordinarily, we don't allow them
   to match, because letting them match would cause unpredictable results
   in all the places that search a hash table chain for an equivalent
   for a given value.  A possible equivalent that has different structure
   has its hash code computed from different data.  Whether the hash code
   is the same as that of the given value is pure luck.  */

static int
exp_equiv_p (rtx x, rtx y, int validate, int equal_values)
{
  int i, j;
  enum rtx_code code;
  const char *fmt;

  /* Note: it is incorrect to assume an expression is equivalent to itself
     if VALIDATE is nonzero.  */
  if (x == y && !validate)
    return 1;
  if (x == 0 || y == 0)
    return x == y;

  code = GET_CODE (x);
  if (code != GET_CODE (y))
    {
      if (!equal_values)
	return 0;

      /* If X is a constant and Y is a register or vice versa, they may be
	 equivalent.  We only have to validate if Y is a register.  */
      if (CONSTANT_P (x) && GET_CODE (y) == REG
	  && REGNO_QTY_VALID_P (REGNO (y)))
	{
	  int y_q = REG_QTY (REGNO (y));
	  struct qty_table_elem *y_ent = &qty_table[y_q];

	  if (GET_MODE (y) == y_ent->mode
	      && rtx_equal_p (x, y_ent->const_rtx)
	      && (! validate || REG_IN_TABLE (REGNO (y)) == REG_TICK (REGNO (y))))
	    return 1;
	}

      if (CONSTANT_P (y) && code == REG
	  && REGNO_QTY_VALID_P (REGNO (x)))
	{
	  int x_q = REG_QTY (REGNO (x));
	  struct qty_table_elem *x_ent = &qty_table[x_q];

	  if (GET_MODE (x) == x_ent->mode
	      && rtx_equal_p (y, x_ent->const_rtx))
	    return 1;
	}

      return 0;
    }

  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
  if (GET_MODE (x) != GET_MODE (y))
    return 0;

  switch (code)
    {
    case PC:
    case CC0:
    case CONST_INT:
      return x == y;

    case LABEL_REF:
      return XEXP (x, 0) == XEXP (y, 0);

    case SYMBOL_REF:
      return XSTR (x, 0) == XSTR (y, 0);

    case REG:
      {
	unsigned int regno = REGNO (y);
	unsigned int endregno
	  = regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
		     : HARD_REGNO_NREGS (regno, GET_MODE (y)));
	unsigned int i;

	/* If the quantities are not the same, the expressions are not
	   equivalent.  If there are and we are not to validate, they
	   are equivalent.  Otherwise, ensure all regs are up-to-date.  */

	if (REG_QTY (REGNO (x)) != REG_QTY (regno))
	  return 0;

	if (! validate)
	  return 1;

	for (i = regno; i < endregno; i++)
	  if (REG_IN_TABLE (i) != REG_TICK (i))
	    return 0;

	return 1;
      }

    /*  For commutative operations, check both orders.  */
    case PLUS:
    case MULT:
    case AND:
    case IOR:
    case XOR:
    case NE:
    case EQ:
      return ((exp_equiv_p (XEXP (x, 0), XEXP (y, 0), validate, equal_values)
	       && exp_equiv_p (XEXP (x, 1), XEXP (y, 1),
			       validate, equal_values))
	      || (exp_equiv_p (XEXP (x, 0), XEXP (y, 1),
			       validate, equal_values)
		  && exp_equiv_p (XEXP (x, 1), XEXP (y, 0),
				  validate, equal_values)));

    case ASM_OPERANDS:
      /* We don't use the generic code below because we want to
	 disregard filename and line numbers.  */

      /* A volatile asm isn't equivalent to any other.  */
      if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
	return 0;

      if (GET_MODE (x) != GET_MODE (y)
	  || strcmp (ASM_OPERANDS_TEMPLATE (x), ASM_OPERANDS_TEMPLATE (y))
	  || strcmp (ASM_OPERANDS_OUTPUT_CONSTRAINT (x),
		     ASM_OPERANDS_OUTPUT_CONSTRAINT (y))
	  || ASM_OPERANDS_OUTPUT_IDX (x) != ASM_OPERANDS_OUTPUT_IDX (y)
	  || ASM_OPERANDS_INPUT_LENGTH (x) != ASM_OPERANDS_INPUT_LENGTH (y))
	return 0;

      if (ASM_OPERANDS_INPUT_LENGTH (x))
	{
	  for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
	    if (! exp_equiv_p (ASM_OPERANDS_INPUT (x, i),
			       ASM_OPERANDS_INPUT (y, i),
			       validate, equal_values)
		|| strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i),
			   ASM_OPERANDS_INPUT_CONSTRAINT (y, i)))
	      return 0;
	}

      return 1;

    default:
      break;
    }

  /* Compare the elements.  If any pair of corresponding elements
     fail to match, return 0 for the whole things.  */

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      switch (fmt[i])
	{
	case 'e':
	  if (! exp_equiv_p (XEXP (x, i), XEXP (y, i), validate, equal_values))
	    return 0;
	  break;

	case 'E':
	  if (XVECLEN (x, i) != XVECLEN (y, i))
	    return 0;
	  for (j = 0; j < XVECLEN (x, i); j++)
	    if (! exp_equiv_p (XVECEXP (x, i, j), XVECEXP (y, i, j),
			       validate, equal_values))
	      return 0;
	  break;

	case 's':
	  if (strcmp (XSTR (x, i), XSTR (y, i)))
	    return 0;
	  break;

	case 'i':
	  if (XINT (x, i) != XINT (y, i))
	    return 0;
	  break;

	case 'w':
	  if (XWINT (x, i) != XWINT (y, i))
	    return 0;
	  break;

	case '0':
	case 't':
	  break;

	default:
	  abort ();
	}
    }

  return 1;
}

/* Return 1 if X has a value that can vary even between two
   executions of the program.  0 means X can be compared reliably
   against certain constants or near-constants.  */

static int
cse_rtx_varies_p (rtx x, int from_alias)
{
  /* We need not check for X and the equivalence class being of the same
     mode because if X is equivalent to a constant in some mode, it
     doesn't vary in any mode.  */

  if (GET_CODE (x) == REG
      && REGNO_QTY_VALID_P (REGNO (x)))
    {
      int x_q = REG_QTY (REGNO (x));
      struct qty_table_elem *x_ent = &qty_table[x_q];

      if (GET_MODE (x) == x_ent->mode
	  && x_ent->const_rtx != NULL_RTX)
	return 0;
    }

  if (GET_CODE (x) == PLUS
      && GET_CODE (XEXP (x, 1)) == CONST_INT
      && GET_CODE (XEXP (x, 0)) == REG
      && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))))
    {
      int x0_q = REG_QTY (REGNO (XEXP (x, 0)));
      struct qty_table_elem *x0_ent = &qty_table[x0_q];

      if ((GET_MODE (XEXP (x, 0)) == x0_ent->mode)
	  && x0_ent->const_rtx != NULL_RTX)
	return 0;
    }

  /* This can happen as the result of virtual register instantiation, if
     the initial constant is too large to be a valid address.  This gives
     us a three instruction sequence, load large offset into a register,
     load fp minus a constant into a register, then a MEM which is the
     sum of the two `constant' registers.  */
  if (GET_CODE (x) == PLUS
      && GET_CODE (XEXP (x, 0)) == REG
      && GET_CODE (XEXP (x, 1)) == REG
      && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0)))
      && REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))))
    {
      int x0_q = REG_QTY (REGNO (XEXP (x, 0)));
      int x1_q = REG_QTY (REGNO (XEXP (x, 1)));
      struct qty_table_elem *x0_ent = &qty_table[x0_q];
      struct qty_table_elem *x1_ent = &qty_table[x1_q];

      if ((GET_MODE (XEXP (x, 0)) == x0_ent->mode)
	  && x0_ent->const_rtx != NULL_RTX
	  && (GET_MODE (XEXP (x, 1)) == x1_ent->mode)
	  && x1_ent->const_rtx != NULL_RTX)
	return 0;
    }

  return rtx_varies_p (x, from_alias);
}

/* Canonicalize an expression:
   replace each register reference inside it
   with the "oldest" equivalent register.

   If INSN is nonzero and we are replacing a pseudo with a hard register
   or vice versa, validate_change is used to ensure that INSN remains valid
   after we make our substitution.  The calls are made with IN_GROUP nonzero
   so apply_change_group must be called upon the outermost return from this
   function (unless INSN is zero).  The result of apply_change_group can
   generally be discarded since the changes we are making are optional.  */

static rtx
canon_reg (rtx x, rtx insn)
{
  int i;
  enum rtx_code code;
  const char *fmt;

  if (x == 0)
    return x;

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

    case REG:
      {
	int first;
	int q;
	struct qty_table_elem *ent;

	/* Never replace a hard reg, because hard regs can appear
	   in more than one machine mode, and we must preserve the mode
	   of each occurrence.  Also, some hard regs appear in
	   MEMs that are shared and mustn't be altered.  Don't try to
	   replace any reg that maps to a reg of class NO_REGS.  */
	if (REGNO (x) < FIRST_PSEUDO_REGISTER
	    || ! REGNO_QTY_VALID_P (REGNO (x)))
	  return x;

	q = REG_QTY (REGNO (x));
	ent = &qty_table[q];
	first = ent->first_reg;
	return (first >= FIRST_PSEUDO_REGISTER ? regno_reg_rtx[first]
		: REGNO_REG_CLASS (first) == NO_REGS ? x
		: gen_rtx_REG (ent->mode, first));
      }

    default:
      break;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      int j;

      if (fmt[i] == 'e')
	{
	  rtx new = canon_reg (XEXP (x, i), insn);
	  int insn_code;

	  /* If replacing pseudo with hard reg or vice versa, ensure the
	     insn remains valid.  Likewise if the insn has MATCH_DUPs.  */
	  if (insn != 0 && new != 0
	      && GET_CODE (new) == REG && GET_CODE (XEXP (x, i)) == REG
	      && (((REGNO (new) < FIRST_PSEUDO_REGISTER)
		   != (REGNO (XEXP (x, i)) < FIRST_PSEUDO_REGISTER))
		  || (insn_code = recog_memoized (insn)) < 0
		  || insn_data[insn_code].n_dups > 0))
	    validate_change (insn, &XEXP (x, i), new, 1);
	  else
	    XEXP (x, i) = new;
	}
      else if (fmt[i] == 'E')
	for (j = 0; j < XVECLEN (x, i); j++)
	  XVECEXP (x, i, j) = canon_reg (XVECEXP (x, i, j), insn);
    }

  return x;
}

/* LOC is a location within INSN that is an operand address (the contents of
   a MEM).  Find the best equivalent address to use that is valid for this
   insn.

   On most CISC machines, complicated address modes are costly, and rtx_cost
   is a good approximation for that cost.  However, most RISC machines have
   only a few (usually only one) memory reference formats.  If an address is
   valid at all, it is often just as cheap as any other address.  Hence, for
   RISC machines, we use `address_cost' to compare the costs of various
   addresses.  For two addresses of equal cost, choose the one with the
   highest `rtx_cost' value as that has the potential of eliminating the
   most insns.  For equal costs, we choose the first in the equivalence
   class.  Note that we ignore the fact that pseudo registers are cheaper than
   hard registers here because we would also prefer the pseudo registers.  */

static void
find_best_addr (rtx insn, rtx *loc, enum machine_mode mode)
{
  struct table_elt *elt;
  rtx addr = *loc;
  struct table_elt *p;
  int found_better = 1;
  int save_do_not_record = do_not_record;
  int save_hash_arg_in_memory = hash_arg_in_memory;
  int addr_volatile;
  int regno;
  unsigned hash;

  /* Do not try to replace constant addresses or addresses of local and
     argument slots.  These MEM expressions are made only once and inserted
     in many instructions, as well as being used to control symbol table
     output.  It is not safe to clobber them.

     There are some uncommon cases where the address is already in a register
     for some reason, but we cannot take advantage of that because we have
     no easy way to unshare the MEM.  In addition, looking up all stack
     addresses is costly.  */
  if ((GET_CODE (addr) == PLUS
       && GET_CODE (XEXP (addr, 0)) == REG
       && GET_CODE (XEXP (addr, 1)) == CONST_INT
       && (regno = REGNO (XEXP (addr, 0)),
	   regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM
	   || regno == ARG_POINTER_REGNUM))
      || (GET_CODE (addr) == REG
	  && (regno = REGNO (addr), regno == FRAME_POINTER_REGNUM
	      || regno == HARD_FRAME_POINTER_REGNUM
	      || regno == ARG_POINTER_REGNUM))
      || GET_CODE (addr) == ADDRESSOF
      || CONSTANT_ADDRESS_P (addr))
    return;

  /* If this address is not simply a register, try to fold it.  This will
     sometimes simplify the expression.  Many simplifications
     will not be valid, but some, usually applying the associative rule, will
     be valid and produce better code.  */
  if (GET_CODE (addr) != REG)
    {
      rtx folded = fold_rtx (copy_rtx (addr), NULL_RTX);
      int addr_folded_cost = address_cost (folded, mode);
      int addr_cost = address_cost (addr, mode);

      if ((addr_folded_cost < addr_cost
	   || (addr_folded_cost == addr_cost
	       /* ??? The rtx_cost comparison is left over from an older
		  version of this code.  It is probably no longer helpful.  */
	       && (rtx_cost (folded, MEM) > rtx_cost (addr, MEM)
		   || approx_reg_cost (folded) < approx_reg_cost (addr))))
	  && validate_change (insn, loc, folded, 0))
	addr = folded;
    }

  /* If this address is not in the hash table, we can't look for equivalences
     of the whole address.  Also, ignore if volatile.  */

  do_not_record = 0;
  hash = HASH (addr, Pmode);
  addr_volatile = do_not_record;
  do_not_record = save_do_not_record;
  hash_arg_in_memory = save_hash_arg_in_memory;

  if (addr_volatile)
    return;

  elt = lookup (addr, hash, Pmode);

  if (elt)
    {
      /* We need to find the best (under the criteria documented above) entry
	 in the class that is valid.  We use the `flag' field to indicate
	 choices that were invalid and iterate until we can't find a better
	 one that hasn't already been tried.  */

      for (p = elt->first_same_value; p; p = p->next_same_value)
	p->flag = 0;

      while (found_better)
	{
	  int best_addr_cost = address_cost (*loc, mode);
	  int best_rtx_cost = (elt->cost + 1) >> 1;
	  int exp_cost;
	  struct table_elt *best_elt = elt;

	  found_better = 0;
	  for (p = elt->first_same_value; p; p = p->next_same_value)
	    if (! p->flag)
	      {
		if ((GET_CODE (p->exp) == REG
		     || exp_equiv_p (p->exp, p->exp, 1, 0))
		    && ((exp_cost = address_cost (p->exp, mode)) < best_addr_cost
			|| (exp_cost == best_addr_cost
			    && ((p->cost + 1) >> 1) > best_rtx_cost)))
		  {
		    found_better = 1;
		    best_addr_cost = exp_cost;
		    best_rtx_cost = (p->cost + 1) >> 1;
		    best_elt = p;
		  }
	      }

	  if (found_better)
	    {
	      if (validate_change (insn, loc,
				   canon_reg (copy_rtx (best_elt->exp),
					      NULL_RTX), 0))
		return;
	      else
		best_elt->flag = 1;
	    }
	}
    }

  /* If the address is a binary operation with the first operand a register
     and the second a constant, do the same as above, but looking for
     equivalences of the register.  Then try to simplify before checking for
     the best address to use.  This catches a few cases:  First is when we
     have REG+const and the register is another REG+const.  We can often merge
     the constants and eliminate one insn and one register.  It may also be
     that a machine has a cheap REG+REG+const.  Finally, this improves the
     code on the Alpha for unaligned byte stores.  */

  if (flag_expensive_optimizations
      && (GET_RTX_CLASS (GET_CODE (*loc)) == '2'
	  || GET_RTX_CLASS (GET_CODE (*loc)) == 'c')
      && GET_CODE (XEXP (*loc, 0)) == REG)
    {
      rtx op1 = XEXP (*loc, 1);

      do_not_record = 0;
      hash = HASH (XEXP (*loc, 0), Pmode);
      do_not_record = save_do_not_record;
      hash_arg_in_memory = save_hash_arg_in_memory;

      elt = lookup (XEXP (*loc, 0), hash, Pmode);
      if (elt == 0)
	return;

      /* We need to find the best (under the criteria documented above) entry
	 in the class that is valid.  We use the `flag' field to indicate
	 choices that were invalid and iterate until we can't find a better
	 one that hasn't already been tried.  */

      for (p = elt->first_same_value; p; p = p->next_same_value)
	p->flag = 0;

      while (found_better)
	{
	  int best_addr_cost = address_cost (*loc, mode);
	  int best_rtx_cost = (COST (*loc) + 1) >> 1;
	  struct table_elt *best_elt = elt;
	  rtx best_rtx = *loc;
	  int count;

	  /* This is at worst case an O(n^2) algorithm, so limit our search
	     to the first 32 elements on the list.  This avoids trouble
	     compiling code with very long basic blocks that can easily
	     call simplify_gen_binary so many times that we run out of
	     memory.  */

	  found_better = 0;
	  for (p = elt->first_same_value, count = 0;
	       p && count < 32;
	       p = p->next_same_value, count++)
	    if (! p->flag
		&& (GET_CODE (p->exp) == REG
		    || exp_equiv_p (p->exp, p->exp, 1, 0)))
	      {
		rtx new = simplify_gen_binary (GET_CODE (*loc), Pmode,
					       p->exp, op1);
		int new_cost;
		new_cost = address_cost (new, mode);

		if (new_cost < best_addr_cost
		    || (new_cost == best_addr_cost
			&& (COST (new) + 1) >> 1 > best_rtx_cost))
		  {
		    found_better = 1;
		    best_addr_cost = new_cost;
		    best_rtx_cost = (COST (new) + 1) >> 1;
		    best_elt = p;
		    best_rtx = new;
		  }
	      }

	  if (found_better)
	    {
	      if (validate_change (insn, loc,
				   canon_reg (copy_rtx (best_rtx),
					      NULL_RTX), 0))
		return;
	      else
		best_elt->flag = 1;
	    }
	}
    }
}

/* Given an operation (CODE, *PARG1, *PARG2), where code is a comparison
   operation (EQ, NE, GT, etc.), follow it back through the hash table and
   what values are being compared.

   *PARG1 and *PARG2 are updated to contain the rtx representing the values
   actually being compared.  For example, if *PARG1 was (cc0) and *PARG2
   was (const_int 0), *PARG1 and *PARG2 will be set to the objects that were
   compared to produce cc0.

   The return value is the comparison operator and is either the code of
   A or the code corresponding to the inverse of the comparison.  */

static enum rtx_code
find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
		      enum machine_mode *pmode1, enum machine_mode *pmode2)
{
  rtx arg1, arg2;

  arg1 = *parg1, arg2 = *parg2;

  /* If ARG2 is const0_rtx, see what ARG1 is equivalent to.  */

  while (arg2 == CONST0_RTX (GET_MODE (arg1)))
    {
      /* Set nonzero when we find something of interest.  */
      rtx x = 0;
      int reverse_code = 0;
      struct table_elt *p = 0;

      /* If arg1 is a COMPARE, extract the comparison arguments from it.
	 On machines with CC0, this is the only case that can occur, since
	 fold_rtx will return the COMPARE or item being compared with zero
	 when given CC0.  */

      if (GET_CODE (arg1) == COMPARE && arg2 == const0_rtx)
	x = arg1;

      /* If ARG1 is a comparison operator and CODE is testing for
	 STORE_FLAG_VALUE, get the inner arguments.  */

      else if (GET_RTX_CLASS (GET_CODE (arg1)) == '<')
	{
#ifdef FLOAT_STORE_FLAG_VALUE
	  REAL_VALUE_TYPE fsfv;
#endif

	  if (code == NE
	      || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_INT
		  && code == LT && STORE_FLAG_VALUE == -1)
#ifdef FLOAT_STORE_FLAG_VALUE
	      || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_FLOAT
		  && (fsfv = FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)),
		      REAL_VALUE_NEGATIVE (fsfv)))
#endif
	      )
	    x = arg1;
	  else if (code == EQ
		   || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_INT
		       && code == GE && STORE_FLAG_VALUE == -1)
#ifdef FLOAT_STORE_FLAG_VALUE
		   || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_FLOAT
		       && (fsfv = FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)),
			   REAL_VALUE_NEGATIVE (fsfv)))
#endif
		   )
	    x = arg1, reverse_code = 1;
	}

      /* ??? We could also check for

	 (ne (and (eq (...) (const_int 1))) (const_int 0))

	 and related forms, but let's wait until we see them occurring.  */

      if (x == 0)
	/* Look up ARG1 in the hash table and see if it has an equivalence
	   that lets us see what is being compared.  */
	p = lookup (arg1, safe_hash (arg1, GET_MODE (arg1)) & HASH_MASK,
		    GET_MODE (arg1));
      if (p)
	{
	  p = p->first_same_value;

	  /* If what we compare is already known to be constant, that is as
	     good as it gets.
	     We need to break the loop in this case, because otherwise we
	     can have an infinite loop when looking at a reg that is known
	     to be a constant which is the same as a comparison of a reg
	     against zero which appears later in the insn stream, which in
	     turn is constant and the same as the comparison of the first reg
	     against zero...  */
	  if (p->is_const)
	    break;
	}

      for (; p; p = p->next_same_value)
	{
	  enum machine_mode inner_mode = GET_MODE (p->exp);
#ifdef FLOAT_STORE_FLAG_VALUE
	  REAL_VALUE_TYPE fsfv;
#endif

	  /* If the entry isn't valid, skip it.  */
	  if (! exp_equiv_p (p->exp, p->exp, 1, 0))
	    continue;

	  if (GET_CODE (p->exp) == COMPARE
	      /* Another possibility is that this machine has a compare insn
		 that includes the comparison code.  In that case, ARG1 would
		 be equivalent to a comparison operation that would set ARG1 to
		 either STORE_FLAG_VALUE or zero.  If this is an NE operation,
		 ORIG_CODE is the actual comparison being done; if it is an EQ,
		 we must reverse ORIG_CODE.  On machine with a negative value
		 for STORE_FLAG_VALUE, also look at LT and GE operations.  */
	      || ((code == NE
		   || (code == LT
		       && GET_MODE_CLASS (inner_mode) == MODE_INT
		       && (GET_MODE_BITSIZE (inner_mode)
			   <= HOST_BITS_PER_WIDE_INT)
		       && (STORE_FLAG_VALUE
			   & ((HOST_WIDE_INT) 1
			      << (GET_MODE_BITSIZE (inner_mode) - 1))))
#ifdef FLOAT_STORE_FLAG_VALUE
		   || (code == LT
		       && GET_MODE_CLASS (inner_mode) == MODE_FLOAT
		       && (fsfv = FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)),
			   REAL_VALUE_NEGATIVE (fsfv)))
#endif
		   )
		  && GET_RTX_CLASS (GET_CODE (p->exp)) == '<'))
	    {
	      x = p->exp;
	      break;
	    }
	  else if ((code == EQ
		    || (code == GE
			&& GET_MODE_CLASS (inner_mode) == MODE_INT
			&& (GET_MODE_BITSIZE (inner_mode)
			    <= HOST_BITS_PER_WIDE_INT)
			&& (STORE_FLAG_VALUE
			    & ((HOST_WIDE_INT) 1
			       << (GET_MODE_BITSIZE (inner_mode) - 1))))
#ifdef FLOAT_STORE_FLAG_VALUE
		    || (code == GE
			&& GET_MODE_CLASS (inner_mode) == MODE_FLOAT
			&& (fsfv = FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)),
			    REAL_VALUE_NEGATIVE (fsfv)))
#endif
		    )
		   && GET_RTX_CLASS (GET_CODE (p->exp)) == '<')
	    {
	      reverse_code = 1;
	      x = p->exp;
	      break;
	    }

	  /* If this non-trapping address, e.g. fp + constant, the
	     equivalent is a better operand since it may let us predict
	     the value of the comparison.  */
	  else if (!rtx_addr_can_trap_p (p->exp))
	    {
	      arg1 = p->exp;
	      continue;
	    }
	}

      /* If we didn't find a useful equivalence for ARG1, we are done.
	 Otherwise, set up for the next iteration.  */
      if (x == 0)
	break;

      /* If we need to reverse the comparison, make sure that that is
	 possible -- we can't necessarily infer the value of GE from LT
	 with floating-point operands.  */
      if (reverse_code)
	{
	  enum rtx_code reversed = reversed_comparison_code (x, NULL_RTX);
	  if (reversed == UNKNOWN)
	    break;
	  else
	    code = reversed;
	}
      else if (GET_RTX_CLASS (GET_CODE (x)) == '<')
	code = GET_CODE (x);
      arg1 = XEXP (x, 0), arg2 = XEXP (x, 1);
    }

  /* Return our results.  Return the modes from before fold_rtx
     because fold_rtx might produce const_int, and then it's too late.  */
  *pmode1 = GET_MODE (arg1), *pmode2 = GET_MODE (arg2);
  *parg1 = fold_rtx (arg1, 0), *parg2 = fold_rtx (arg2, 0);

  return code;
}

/* If X is a nontrivial arithmetic operation on an argument
   for which a constant value can be determined, return
   the result of operating on that value, as a constant.
   Otherwise, return X, possibly with one or more operands
   modified by recursive calls to this function.

   If X is a register whose contents are known, we do NOT
   return those contents here.  equiv_constant is called to
   perform that task.

   INSN is the insn that we may be modifying.  If it is 0, make a copy
   of X before modifying it.  */

static rtx
fold_rtx (rtx x, rtx insn)
{
  enum rtx_code code;
  enum machine_mode mode;
  const char *fmt;
  int i;
  rtx new = 0;
  int copied = 0;
  int must_swap = 0;

  /* Folded equivalents of first two operands of X.  */
  rtx folded_arg0;
  rtx folded_arg1;

  /* Constant equivalents of first three operands of X;
     0 when no such equivalent is known.  */
  rtx const_arg0;
  rtx const_arg1;
  rtx const_arg2;

  /* The mode of the first operand of X.  We need this for sign and zero
     extends.  */
  enum machine_mode mode_arg0;

  if (x == 0)
    return x;

  mode = GET_MODE (x);
  code = GET_CODE (x);
  switch (code)
    {
    case CONST:
    case CONST_INT:
    case CONST_DOUBLE:
    case CONST_VECTOR:
    case SYMBOL_REF:
    case LABEL_REF:
    case REG:
      /* No use simplifying an EXPR_LIST
	 since they are used only for lists of args
	 in a function call's REG_EQUAL note.  */
    case EXPR_LIST:
      /* Changing anything inside an ADDRESSOF is incorrect; we don't
	 want to (e.g.,) make (addressof (const_int 0)) just because
	 the location is known to be zero.  */
    case ADDRESSOF:
      return x;

#ifdef HAVE_cc0
    case CC0:
      return prev_insn_cc0;
#endif

    case PC:
      /* If the next insn is a CODE_LABEL followed by a jump table,
	 PC's value is a LABEL_REF pointing to that label.  That
	 lets us fold switch statements on the VAX.  */
      {
	rtx next;
	if (insn && tablejump_p (insn, &next, NULL))
	  return gen_rtx_LABEL_REF (Pmode, next);
      }
      break;

    case SUBREG:
      /* See if we previously assigned a constant value to this SUBREG.  */
      if ((new = lookup_as_function (x, CONST_INT)) != 0
	  || (new = lookup_as_function (x, CONST_DOUBLE)) != 0)
	return new;

      /* If this is a paradoxical SUBREG, we have no idea what value the
	 extra bits would have.  However, if the operand is equivalent
	 to a SUBREG whose operand is the same as our mode, and all the
	 modes are within a word, we can just use the inner operand
	 because these SUBREGs just say how to treat the register.

	 Similarly if we find an integer constant.  */

      if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
	{
	  enum machine_mode imode = GET_MODE (SUBREG_REG (x));
	  struct table_elt *elt;

	  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
	      && GET_MODE_SIZE (imode) <= UNITS_PER_WORD
	      && (elt = lookup (SUBREG_REG (x), HASH (SUBREG_REG (x), imode),
				imode)) != 0)
	    for (elt = elt->first_same_value; elt; elt = elt->next_same_value)
	      {
		if (CONSTANT_P (elt->exp)
		    && GET_MODE (elt->exp) == VOIDmode)
		  return elt->exp;

		if (GET_CODE (elt->exp) == SUBREG
		    && GET_MODE (SUBREG_REG (elt->exp)) == mode
		    && exp_equiv_p (elt->exp, elt->exp, 1, 0))
		  return copy_rtx (SUBREG_REG (elt->exp));
	      }

	  return x;
	}

      /* Fold SUBREG_REG.  If it changed, see if we can simplify the SUBREG.
	 We might be able to if the SUBREG is extracting a single word in an
	 integral mode or extracting the low part.  */

      folded_arg0 = fold_rtx (SUBREG_REG (x), insn);
      const_arg0 = equiv_constant (folded_arg0);
      if (const_arg0)
	folded_arg0 = const_arg0;

      if (folded_arg0 != SUBREG_REG (x))
	{
	  new = simplify_subreg (mode, folded_arg0,
				 GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
	  if (new)
	    return new;
	}

      /* If this is a narrowing SUBREG and our operand is a REG, see if
	 we can find an equivalence for REG that is an arithmetic operation
	 in a wider mode where both operands are paradoxical SUBREGs
	 from objects of our result mode.  In that case, we couldn't report
	 an equivalent value for that operation, since we don't know what the
	 extra bits will be.  But we can find an equivalence for this SUBREG
	 by folding that operation is the narrow mode.  This allows us to
	 fold arithmetic in narrow modes when the machine only supports
	 word-sized arithmetic.

	 Also look for a case where we have a SUBREG whose operand is the
	 same as our result.  If both modes are smaller than a word, we
	 are simply interpreting a register in different modes and we
	 can use the inner value.  */

      if (GET_CODE (folded_arg0) == REG
	  && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (folded_arg0))
	  && subreg_lowpart_p (x))
	{
	  struct table_elt *elt;

	  /* We can use HASH here since we know that canon_hash won't be
	     called.  */
	  elt = lookup (folded_arg0,
			HASH (folded_arg0, GET_MODE (folded_arg0)),
			GET_MODE (folded_arg0));

	  if (elt)
	    elt = elt->first_same_value;

	  for (; elt; elt = elt->next_same_value)
	    {
	      enum rtx_code eltcode = GET_CODE (elt->exp);

	      /* Just check for unary and binary operations.  */
	      if (GET_RTX_CLASS (GET_CODE (elt->exp)) == '1'
		  && GET_CODE (elt->exp) != SIGN_EXTEND
		  && GET_CODE (elt->exp) != ZERO_EXTEND
		  && GET_CODE (XEXP (elt->exp, 0)) == SUBREG
		  && GET_MODE (SUBREG_REG (XEXP (elt->exp, 0))) == mode
		  && (GET_MODE_CLASS (mode)
		      == GET_MODE_CLASS (GET_MODE (XEXP (elt->exp, 0)))))
		{
		  rtx op0 = SUBREG_REG (XEXP (elt->exp, 0));

		  if (GET_CODE (op0) != REG && ! CONSTANT_P (op0))
		    op0 = fold_rtx (op0, NULL_RTX);

		  op0 = equiv_constant (op0);
		  if (op0)
		    new = simplify_unary_operation (GET_CODE (elt->exp), mode,
						    op0, mode);
		}
	      else if ((GET_RTX_CLASS (GET_CODE (elt->exp)) == '2'
			|| GET_RTX_CLASS (GET_CODE (elt->exp)) == 'c')
		       && eltcode != DIV && eltcode != MOD
		       && eltcode != UDIV && eltcode != UMOD
		       && eltcode != ASHIFTRT && eltcode != LSHIFTRT
		       && eltcode != ROTATE && eltcode != ROTATERT
		       && ((GET_CODE (XEXP (elt->exp, 0)) == SUBREG
			    && (GET_MODE (SUBREG_REG (XEXP (elt->exp, 0)))
				== mode))
			   || CONSTANT_P (XEXP (elt->exp, 0)))
		       && ((GET_CODE (XEXP (elt->exp, 1)) == SUBREG
			    && (GET_MODE (SUBREG_REG (XEXP (elt->exp, 1)))
				== mode))
			   || CONSTANT_P (XEXP (elt->exp, 1))))
		{
		  rtx op0 = gen_lowpart_common (mode, XEXP (elt->exp, 0));
		  rtx op1 = gen_lowpart_common (mode, XEXP (elt->exp, 1));

		  if (op0 && GET_CODE (op0) != REG && ! CONSTANT_P (op0))
		    op0 = fold_rtx (op0, NULL_RTX);

		  if (op0)
		    op0 = equiv_constant (op0);

		  if (op1 && GET_CODE (op1) != REG && ! CONSTANT_P (op1))
		    op1 = fold_rtx (op1, NULL_RTX);

		  if (op1)
		    op1 = equiv_constant (op1);

		  /* If we are looking for the low SImode part of
		     (ashift:DI c (const_int 32)), it doesn't work
		     to compute that in SImode, because a 32-bit shift
		     in SImode is unpredictable.  We know the value is 0.  */
		  if (op0 && op1
		      && GET_CODE (elt->exp) == ASHIFT
		      && GET_CODE (op1) == CONST_INT
		      && INTVAL (op1) >= GET_MODE_BITSIZE (mode))
		    {
		      if (INTVAL (op1) < GET_MODE_BITSIZE (GET_MODE (elt->exp)))

			/* If the count fits in the inner mode's width,
			   but exceeds the outer mode's width,
			   the value will get truncated to 0
			   by the subreg.  */
			new = const0_rtx;
		      else
			/* If the count exceeds even the inner mode's width,
			   don't fold this expression.  */
			new = 0;
		    }
		  else if (op0 && op1)
		    new = simplify_binary_operation (GET_CODE (elt->exp), mode,
						     op0, op1);
		}

	      else if (GET_CODE (elt->exp) == SUBREG
		       && GET_MODE (SUBREG_REG (elt->exp)) == mode
		       && (GET_MODE_SIZE (GET_MODE (folded_arg0))
			   <= UNITS_PER_WORD)
		       && exp_equiv_p (elt->exp, elt->exp, 1, 0))
		new = copy_rtx (SUBREG_REG (elt->exp));

	      if (new)
		return new;
	    }
	}

      return x;

    case NOT:
    case NEG:
      /* If we have (NOT Y), see if Y is known to be (NOT Z).
	 If so, (NOT Y) simplifies to Z.  Similarly for NEG.  */
      new = lookup_as_function (XEXP (x, 0), code);
      if (new)
	return fold_rtx (copy_rtx (XEXP (new, 0)), insn);
      break;

    case MEM:
      /* If we are not actually processing an insn, don't try to find the
	 best address.  Not only don't we care, but we could modify the
	 MEM in an invalid way since we have no insn to validate against.  */
      if (insn != 0)
	find_best_addr (insn, &XEXP (x, 0), GET_MODE (x));

      {
	/* Even if we don't fold in the insn itself,
	   we can safely do so here, in hopes of getting a constant.  */
	rtx addr = fold_rtx (XEXP (x, 0), NULL_RTX);
	rtx base = 0;
	HOST_WIDE_INT offset = 0;

	if (GET_CODE (addr) == REG
	    && REGNO_QTY_VALID_P (REGNO (addr)))
	  {
	    int addr_q = REG_QTY (REGNO (addr));
	    struct qty_table_elem *addr_ent = &qty_table[addr_q];

	    if (GET_MODE (addr) == addr_ent->mode
		&& addr_ent->const_rtx != NULL_RTX)
	      addr = addr_ent->const_rtx;
	  }

	/* If address is constant, split it into a base and integer offset.  */
	if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
	  base = addr;
	else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
		 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
	  {
	    base = XEXP (XEXP (addr, 0), 0);
	    offset = INTVAL (XEXP (XEXP (addr, 0), 1));
	  }
	else if (GET_CODE (addr) == LO_SUM
		 && GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
	  base = XEXP (addr, 1);
	else if (GET_CODE (addr) == ADDRESSOF)
	  return change_address (x, VOIDmode, addr);

	/* If this is a constant pool reference, we can fold it into its
	   constant to allow better value tracking.  */
	if (base && GET_CODE (base) == SYMBOL_REF
	    && CONSTANT_POOL_ADDRESS_P (base))
	  {
	    rtx constant = get_pool_constant (base);
	    enum machine_mode const_mode = get_pool_mode (base);
	    rtx new;

	    if (CONSTANT_P (constant) && GET_CODE (constant) != CONST_INT)
	      {
		constant_pool_entries_cost = COST (constant);
		constant_pool_entries_regcost = approx_reg_cost (constant);
	      }

	    /* If we are loading the full constant, we have an equivalence.  */
	    if (offset == 0 && mode == const_mode)
	      return constant;

	    /* If this actually isn't a constant (weird!), we can't do
	       anything.  Otherwise, handle the two most common cases:
	       extracting a word from a multi-word constant, and extracting
	       the low-order bits.  Other cases don't seem common enough to
	       worry about.  */
	    if (! CONSTANT_P (constant))
	      return x;

	    if (GET_MODE_CLASS (mode) == MODE_INT
		&& GET_MODE_SIZE (mode) == UNITS_PER_WORD
		&& offset % UNITS_PER_WORD == 0
		&& (new = operand_subword (constant,
					   offset / UNITS_PER_WORD,
					   0, const_mode)) != 0)
	      return new;

	    if (((BYTES_BIG_ENDIAN
		  && offset == GET_MODE_SIZE (GET_MODE (constant)) - 1)
		 || (! BYTES_BIG_ENDIAN && offset == 0))
		&& (new = gen_lowpart_if_possible (mode, constant)) != 0)
	      return new;
	  }

	/* If this is a reference to a label at a known position in a jump
	   table, we also know its value.  */
	if (base && GET_CODE (base) == LABEL_REF)
	  {
	    rtx label = XEXP (base, 0);
	    rtx table_insn = NEXT_INSN (label);

	    if (table_insn && GET_CODE (table_insn) == JUMP_INSN
		&& GET_CODE (PATTERN (table_insn)) == ADDR_VEC)
	      {
		rtx table = PATTERN (table_insn);

		if (offset >= 0
		    && (offset / GET_MODE_SIZE (GET_MODE (table))
			< XVECLEN (table, 0)))
		  return XVECEXP (table, 0,
				  offset / GET_MODE_SIZE (GET_MODE (table)));
	      }
	    if (table_insn && GET_CODE (table_insn) == JUMP_INSN
		&& GET_CODE (PATTERN (table_insn)) == ADDR_DIFF_VEC)
	      {
		rtx table = PATTERN (table_insn);

		if (offset >= 0
		    && (offset / GET_MODE_SIZE (GET_MODE (table))
			< XVECLEN (table, 1)))
		  {
		    offset /= GET_MODE_SIZE (GET_MODE (table));
		    new = gen_rtx_MINUS (Pmode, XVECEXP (table, 1, offset),
					 XEXP (table, 0));

		    if (GET_MODE (table) != Pmode)
		      new = gen_rtx_TRUNCATE (GET_MODE (table), new);

		    /* Indicate this is a constant.  This isn't a
		       valid form of CONST, but it will only be used
		       to fold the next insns and then discarded, so
		       it should be safe.

		       Note this expression must be explicitly discarded,
		       by cse_insn, else it may end up in a REG_EQUAL note
		       and "escape" to cause problems elsewhere.  */
		    return gen_rtx_CONST (GET_MODE (new), new);
		  }
	      }
	  }

	return x;
      }

#ifdef NO_FUNCTION_CSE
    case CALL:
      if (CONSTANT_P (XEXP (XEXP (x, 0), 0)))
	return x;
      break;
#endif

    case ASM_OPERANDS:
      for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
	validate_change (insn, &ASM_OPERANDS_INPUT (x, i),
			 fold_rtx (ASM_OPERANDS_INPUT (x, i), insn), 0);
      break;

    default:
      break;
    }

  const_arg0 = 0;
  const_arg1 = 0;
  const_arg2 = 0;
  mode_arg0 = VOIDmode;

  /* Try folding our operands.
     Then see which ones have constant values known.  */

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    if (fmt[i] == 'e')
      {
	rtx arg = XEXP (x, i);
	rtx folded_arg = arg, const_arg = 0;
	enum machine_mode mode_arg = GET_MODE (arg);
	rtx cheap_arg, expensive_arg;
	rtx replacements[2];
	int j;
	int old_cost = COST_IN (XEXP (x, i), code);

	/* Most arguments are cheap, so handle them specially.  */
	switch (GET_CODE (arg))
	  {
	  case REG:
	    /* This is the same as calling equiv_constant; it is duplicated
	       here for speed.  */
	    if (REGNO_QTY_VALID_P (REGNO (arg)))
	      {
		int arg_q = REG_QTY (REGNO (arg));
		struct qty_table_elem *arg_ent = &qty_table[arg_q];

		if (arg_ent->const_rtx != NULL_RTX
		    && GET_CODE (arg_ent->const_rtx) != REG
		    && GET_CODE (arg_ent->const_rtx) != PLUS)
		  const_arg
		    = gen_lowpart_if_possible (GET_MODE (arg),
					       arg_ent->const_rtx);
	      }
	    break;

	  case CONST:
	  case CONST_INT:
	  case SYMBOL_REF:
	  case LABEL_REF:
	  case CONST_DOUBLE:
	  case CONST_VECTOR:
	    const_arg = arg;
	    break;

#ifdef HAVE_cc0
	  case CC0:
	    folded_arg = prev_insn_cc0;
	    mode_arg = prev_insn_cc0_mode;
	    const_arg = equiv_constant (folded_arg);
	    break;
#endif

	  default:
	    folded_arg = fold_rtx (arg, insn);
	    const_arg = equiv_constant (folded_arg);
	  }

	/* For the first three operands, see if the operand
	   is constant or equivalent to a constant.  */
	switch (i)
	  {
	  case 0:
	    folded_arg0 = folded_arg;
	    const_arg0 = const_arg;
	    mode_arg0 = mode_arg;
	    break;
	  case 1:
	    folded_arg1 = folded_arg;
	    const_arg1 = const_arg;
	    break;
	  case 2:
	    const_arg2 = const_arg;
	    break;
	  }

	/* Pick the least expensive of the folded argument and an
	   equivalent constant argument.  */
	if (const_arg == 0 || const_arg == folded_arg
	    || COST_IN (const_arg, code) > COST_IN (folded_arg, code))
	  cheap_arg = folded_arg, expensive_arg = const_arg;
	else
	  cheap_arg = const_arg, expensive_arg = folded_arg;

	/* Try to replace the operand with the cheapest of the two
	   possibilities.  If it doesn't work and this is either of the first
	   two operands of a commutative operation, try swapping them.
	   If THAT fails, try the more expensive, provided it is cheaper
	   than what is already there.  */

	if (cheap_arg == XEXP (x, i))
	  continue;

	if (insn == 0 && ! copied)
	  {
	    x = copy_rtx (x);
	    copied = 1;
	  }

	/* Order the replacements from cheapest to most expensive.  */
	replacements[0] = cheap_arg;
	replacements[1] = expensive_arg;

	for (j = 0; j < 2 && replacements[j]; j++)
	  {
	    int new_cost = COST_IN (replacements[j], code);

	    /* Stop if what existed before was cheaper.  Prefer constants
	       in the case of a tie.  */
	    if (new_cost > old_cost
		|| (new_cost == old_cost && CONSTANT_P (XEXP (x, i))))
	      break;

	    /* It's not safe to substitute the operand of a conversion
	       operator with a constant, as the conversion's identity
	       depends upon the mode of it's operand.  This optimization
	       is handled by the call to simplify_unary_operation.  */
	    if (GET_RTX_CLASS (code) == '1'
		&& GET_MODE (replacements[j]) != mode_arg0
		&& (code == ZERO_EXTEND
		    || code == SIGN_EXTEND
		    || code == TRUNCATE
		    || code == FLOAT_TRUNCATE
		    || code == FLOAT_EXTEND
		    || code == FLOAT
		    || code == FIX
		    || code == UNSIGNED_FLOAT
		    || code == UNSIGNED_FIX))
	      continue;

	    if (validate_change (insn, &XEXP (x, i), replacements[j], 0))
	      break;

	    if (code == NE || code == EQ || GET_RTX_CLASS (code) == 'c'
		|| code == LTGT || code == UNEQ || code == ORDERED
		|| code == UNORDERED)
	      {
		validate_change (insn, &XEXP (x, i), XEXP (x, 1 - i), 1);
		validate_change (insn, &XEXP (x, 1 - i), replacements[j], 1);

		if (apply_change_group ())
		  {
		    /* Swap them back to be invalid so that this loop can
		       continue and flag them to be swapped back later.  */
		    rtx tem;

		    tem = XEXP (x, 0); XEXP (x, 0) = XEXP (x, 1);
				       XEXP (x, 1) = tem;
		    must_swap = 1;
		    break;
		  }
	      }
	  }
      }

    else
      {
	if (fmt[i] == 'E')
	  /* Don't try to fold inside of a vector of expressions.
	     Doing nothing is harmless.  */
	  {;}
      }

  /* If a commutative operation, place a constant integer as the second
     operand unless the first operand is also a constant integer.  Otherwise,
     place any constant second unless the first operand is also a constant.  */

  if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c'
      || code == LTGT || code == UNEQ || code == ORDERED
      || code == UNORDERED)
    {
      if (must_swap
	  || swap_commutative_operands_p (const_arg0 ? const_arg0
						     : XEXP (x, 0),
					  const_arg1 ? const_arg1
						     : XEXP (x, 1)))
	{
	  rtx tem = XEXP (x, 0);

	  if (insn == 0 && ! copied)
	    {
	      x = copy_rtx (x);
	      copied = 1;
	    }

	  validate_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
	  validate_change (insn, &XEXP (x, 1), tem, 1);
	  if (apply_change_group ())
	    {
	      tem = const_arg0, const_arg0 = const_arg1, const_arg1 = tem;
	      tem = folded_arg0, folded_arg0 = folded_arg1, folded_arg1 = tem;
	    }
	}
    }

  /* If X is an arithmetic operation, see if we can simplify it.  */

  switch (GET_RTX_CLASS (code))
    {
    case '1':
      {
	int is_const = 0;

	/* We can't simplify extension ops unless we know the
	   original mode.  */
	if ((code == ZERO_EXTEND || code == SIGN_EXTEND)
	    && mode_arg0 == VOIDmode)
	  break;

	/* If we had a CONST, strip it off and put it back later if we
	   fold.  */
	if (const_arg0 != 0 && GET_CODE (const_arg0) == CONST)
	  is_const = 1, const_arg0 = XEXP (const_arg0, 0);

	new = simplify_unary_operation (code, mode,
					const_arg0 ? const_arg0 : folded_arg0,
					mode_arg0);
	if (new != 0 && is_const)
	  new = gen_rtx_CONST (mode, new);
      }
      break;

    case '<':
      /* Don't perform any simplifications of vector mode comparisons.  */
      if (VECTOR_MODE_P (mode))
	break;

      /* See what items are actually being compared and set FOLDED_ARG[01]
	 to those values and CODE to the actual comparison code.  If any are
	 constant, set CONST_ARG0 and CONST_ARG1 appropriately.  We needn't
	 do anything if both operands are already known to be constant.  */

      if (const_arg0 == 0 || const_arg1 == 0)
	{
	  struct table_elt *p0, *p1;
	  rtx true_rtx = const_true_rtx, false_rtx = const0_rtx;
	  enum machine_mode mode_arg1;

#ifdef FLOAT_STORE_FLAG_VALUE
	  if (GET_MODE_CLASS (mode) == MODE_FLOAT)
	    {
	      true_rtx = (CONST_DOUBLE_FROM_REAL_VALUE
			  (FLOAT_STORE_FLAG_VALUE (mode), mode));
	      false_rtx = CONST0_RTX (mode);
	    }
#endif

	  code = find_comparison_args (code, &folded_arg0, &folded_arg1,
				       &mode_arg0, &mode_arg1);
	  const_arg0 = equiv_constant (folded_arg0);
	  const_arg1 = equiv_constant (folded_arg1);

	  /* If the mode is VOIDmode or a MODE_CC mode, we don't know
	     what kinds of things are being compared, so we can't do
	     anything with this comparison.  */

	  if (mode_arg0 == VOIDmode || GET_MODE_CLASS (mode_arg0) == MODE_CC)
	    break;

	  /* If we do not now have two constants being compared, see
	     if we can nevertheless deduce some things about the
	     comparison.  */
	  if (const_arg0 == 0 || const_arg1 == 0)
	    {
	      /* Some addresses are known to be nonzero.  We don't know
		 their sign, but equality comparisons are known.  */
	      if (const_arg1 == const0_rtx
		  && nonzero_address_p (folded_arg0))
		{
		  if (code == EQ)
		    return false_rtx;
		  else if (code == NE)
		    return true_rtx;
		}

	      /* See if the two operands are the same.  */

	      if (folded_arg0 == folded_arg1
		  || (GET_CODE (folded_arg0) == REG
		      && GET_CODE (folded_arg1) == REG
		      && (REG_QTY (REGNO (folded_arg0))
			  == REG_QTY (REGNO (folded_arg1))))
		  || ((p0 = lookup (folded_arg0,
				    (safe_hash (folded_arg0, mode_arg0)
				     & HASH_MASK), mode_arg0))
		      && (p1 = lookup (folded_arg1,
				       (safe_hash (folded_arg1, mode_arg0)
					& HASH_MASK), mode_arg0))
		      && p0->first_same_value == p1->first_same_value))
		{
		  /* Sadly two equal NaNs are not equivalent.  */
		  if (!HONOR_NANS (mode_arg0))
		    return ((code == EQ || code == LE || code == GE
			     || code == LEU || code == GEU || code == UNEQ
			     || code == UNLE || code == UNGE
			     || code == ORDERED)
			    ? true_rtx : false_rtx);
		  /* Take care for the FP compares we can resolve.  */
		  if (code == UNEQ || code == UNLE || code == UNGE)
		    return true_rtx;
		  if (code == LTGT || code == LT || code == GT)
		    return false_rtx;
		}

	      /* If FOLDED_ARG0 is a register, see if the comparison we are
		 doing now is either the same as we did before or the reverse
		 (we only check the reverse if not floating-point).  */
	      else if (GET_CODE (folded_arg0) == REG)
		{
		  int qty = REG_QTY (REGNO (folded_arg0));

		  if (REGNO_QTY_VALID_P (REGNO (folded_arg0)))
		    {
		      struct qty_table_elem *ent = &qty_table[qty];

		      if ((comparison_dominates_p (ent->comparison_code, code)
			   || (! FLOAT_MODE_P (mode_arg0)
			       && comparison_dominates_p (ent->comparison_code,
						          reverse_condition (code))))
			  && (rtx_equal_p (ent->comparison_const, folded_arg1)
			      || (const_arg1
				  && rtx_equal_p (ent->comparison_const,
						  const_arg1))
			      || (GET_CODE (folded_arg1) == REG
				  && (REG_QTY (REGNO (folded_arg1)) == ent->comparison_qty))))
			return (comparison_dominates_p (ent->comparison_code, code)
				? true_rtx : false_rtx);
		    }
		}
	    }
	}

      /* If we are comparing against zero, see if the first operand is
	 equivalent to an IOR with a constant.  If so, we may be able to
	 determine the result of this comparison.  */

      if (const_arg1 == const0_rtx)
	{
	  rtx y = lookup_as_function (folded_arg0, IOR);
	  rtx inner_const;

	  if (y != 0
	      && (inner_const = equiv_constant (XEXP (y, 1))) != 0
	      && GET_CODE (inner_const) == CONST_INT
	      && INTVAL (inner_const) != 0)
	    {
	      int sign_bitnum = GET_MODE_BITSIZE (mode_arg0) - 1;
	      int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
			      && (INTVAL (inner_const)
				  & ((HOST_WIDE_INT) 1 << sign_bitnum)));
	      rtx true_rtx = const_true_rtx, false_rtx = const0_rtx;

#ifdef FLOAT_STORE_FLAG_VALUE
	      if (GET_MODE_CLASS (mode) == MODE_FLOAT)
		{
		  true_rtx = (CONST_DOUBLE_FROM_REAL_VALUE
			  (FLOAT_STORE_FLAG_VALUE (mode), mode));
		  false_rtx = CONST0_RTX (mode);
		}
#endif

	      switch (code)
		{
		case EQ:
		  return false_rtx;
		case NE:
		  return true_rtx;
		case LT:  case LE:
		  if (has_sign)
		    return true_rtx;
		  break;
		case GT:  case GE:
		  if (has_sign)
		    return false_rtx;
		  break;
		default:
		  break;
		}
	    }
	}

      new = simplify_relational_operation (code,
					   (mode_arg0 != VOIDmode
					    ? mode_arg0
					    : (GET_MODE (const_arg0
							 ? const_arg0
							 : folded_arg0)
					       != VOIDmode)
					    ? GET_MODE (const_arg0
							? const_arg0
							: folded_arg0)
					    : GET_MODE (const_arg1
							? const_arg1
							: folded_arg1)),
					   const_arg0 ? const_arg0 : folded_arg0,
					   const_arg1 ? const_arg1 : folded_arg1);
#ifdef FLOAT_STORE_FLAG_VALUE
      if (new != 0 && GET_MODE_CLASS (mode) == MODE_FLOAT)
	{
	  if (new == const0_rtx)
	    new = CONST0_RTX (mode);
	  else
	    new = (CONST_DOUBLE_FROM_REAL_VALUE
		   (FLOAT_STORE_FLAG_VALUE (mode), mode));
	}
#endif
      break;

    case '2':
    case 'c':
      switch (code)
	{
	case PLUS:
	  /* If the second operand is a LABEL_REF, see if the first is a MINUS
	     with that LABEL_REF as its second operand.  If so, the result is
	     the first operand of that MINUS.  This handles switches with an
	     ADDR_DIFF_VEC table.  */
	  if (const_arg1 && GET_CODE (const_arg1) == LABEL_REF)
	    {
	      rtx y
		= GET_CODE (folded_arg0) == MINUS ? folded_arg0
		: lookup_as_function (folded_arg0, MINUS);

	      if (y != 0 && GET_CODE (XEXP (y, 1)) == LABEL_REF
		  && XEXP (XEXP (y, 1), 0) == XEXP (const_arg1, 0))
		return XEXP (y, 0);

	      /* Now try for a CONST of a MINUS like the above.  */
	      if ((y = (GET_CODE (folded_arg0) == CONST ? folded_arg0
			: lookup_as_function (folded_arg0, CONST))) != 0
		  && GET_CODE (XEXP (y, 0)) == MINUS
		  && GET_CODE (XEXP (XEXP (y, 0), 1)) == LABEL_REF
		  && XEXP (XEXP (XEXP (y, 0), 1), 0) == XEXP (const_arg1, 0))
		return XEXP (XEXP (y, 0), 0);
	    }

	  /* Likewise if the operands are in the other order.  */
	  if (const_arg0 && GET_CODE (const_arg0) == LABEL_REF)
	    {
	      rtx y
		= GET_CODE (folded_arg1) == MINUS ? folded_arg1
		: lookup_as_function (folded_arg1, MINUS);

	      if (y != 0 && GET_CODE (XEXP (y, 1)) == LABEL_REF
		  && XEXP (XEXP (y, 1), 0) == XEXP (const_arg0, 0))
		return XEXP (y, 0);

	      /* Now try for a CONST of a MINUS like the above.  */
	      if ((y = (GET_CODE (folded_arg1) == CONST ? folded_arg1
			: lookup_as_function (folded_arg1, CONST))) != 0
		  && GET_CODE (XEXP (y, 0)) == MINUS
		  && GET_CODE (XEXP (XEXP (y, 0), 1)) == LABEL_REF
		  && XEXP (XEXP (XEXP (y, 0), 1), 0) == XEXP (const_arg0, 0))
		return XEXP (XEXP (y, 0), 0);
	    }

	  /* If second operand is a register equivalent to a negative
	     CONST_INT, see if we can find a register equivalent to the
	     positive constant.  Make a MINUS if so.  Don't do this for
	     a non-negative constant since we might then alternate between
	     choosing positive and negative constants.  Having the positive
	     constant previously-used is the more common case.  Be sure
	     the resulting constant is non-negative; if const_arg1 were
	     the smallest negative number this would overflow: depending
	     on the mode, this would either just be the same value (and
	     hence not save anything) or be incorrect.  */
	  if (const_arg1 != 0 && GET_CODE (const_arg1) == CONST_INT
	      && INTVAL (const_arg1) < 0
	      /* This used to test

	         -INTVAL (const_arg1) >= 0

		 But The Sun V5.0 compilers mis-compiled that test.  So
		 instead we test for the problematic value in a more direct
		 manner and hope the Sun compilers get it correct.  */
	      && INTVAL (const_arg1) !=
	        ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1))
	      && GET_CODE (folded_arg1) == REG)
	    {
	      rtx new_const = GEN_INT (-INTVAL (const_arg1));
	      struct table_elt *p
		= lookup (new_const, safe_hash (new_const, mode) & HASH_MASK,
			  mode);

	      if (p)
		for (p = p->first_same_value; p; p = p->next_same_value)
		  if (GET_CODE (p->exp) == REG)
		    return simplify_gen_binary (MINUS, mode, folded_arg0,
						canon_reg (p->exp, NULL_RTX));
	    }
	  goto from_plus;

	case MINUS:
	  /* If we have (MINUS Y C), see if Y is known to be (PLUS Z C2).
	     If so, produce (PLUS Z C2-C).  */
	  if (const_arg1 != 0 && GET_CODE (const_arg1) == CONST_INT)
	    {
	      rtx y = lookup_as_function (XEXP (x, 0), PLUS);
	      if (y && GET_CODE (XEXP (y, 1)) == CONST_INT)
		return fold_rtx (plus_constant (copy_rtx (y),
						-INTVAL (const_arg1)),
				 NULL_RTX);
	    }

	  /* Fall through.  */

	from_plus:
	case SMIN:    case SMAX:      case UMIN:    case UMAX:
	case IOR:     case AND:       case XOR:
	case MULT:
	case ASHIFT:  case LSHIFTRT:  case ASHIFTRT:
	  /* If we have (<op> <reg> <const_int>) for an associative OP and REG
	     is known to be of similar form, we may be able to replace the
	     operation with a combined operation.  This may eliminate the
	     intermediate operation if every use is simplified in this way.
	     Note that the similar optimization done by combine.c only works
	     if the intermediate operation's result has only one reference.  */

	  if (GET_CODE (folded_arg0) == REG
	      && const_arg1 && GET_CODE (const_arg1) == CONST_INT)
	    {
	      int is_shift
		= (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT);
	      rtx y = lookup_as_function (folded_arg0, code);
	      rtx inner_const;
	      enum rtx_code associate_code;
	      rtx new_const;

	      if (y == 0
		  || 0 == (inner_const
			   = equiv_constant (fold_rtx (XEXP (y, 1), 0)))
		  || GET_CODE (inner_const) != CONST_INT
		  /* If we have compiled a statement like
		     "if (x == (x & mask1))", and now are looking at
		     "x & mask2", we will have a case where the first operand
		     of Y is the same as our first operand.  Unless we detect
		     this case, an infinite loop will result.  */
		  || XEXP (y, 0) == folded_arg0)
		break;

	      /* Don't associate these operations if they are a PLUS with the
		 same constant and it is a power of two.  These might be doable
		 with a pre- or post-increment.  Similarly for two subtracts of
		 identical powers of two with post decrement.  */

	      if (code == PLUS && const_arg1 == inner_const
		  && ((HAVE_PRE_INCREMENT
			  && exact_log2 (INTVAL (const_arg1)) >= 0)
		      || (HAVE_POST_INCREMENT
			  && exact_log2 (INTVAL (const_arg1)) >= 0)
		      || (HAVE_PRE_DECREMENT
			  && exact_log2 (- INTVAL (const_arg1)) >= 0)
		      || (HAVE_POST_DECREMENT
			  && exact_log2 (- INTVAL (const_arg1)) >= 0)))
		break;

	      /* Compute the code used to compose the constants.  For example,
		 A-C1-C2 is A-(C1 + C2), so if CODE == MINUS, we want PLUS.  */

	      associate_code = (is_shift || code == MINUS ? PLUS : code);

	      new_const = simplify_binary_operation (associate_code, mode,
						     const_arg1, inner_const);

	      if (new_const == 0)
		break;

	      /* If we are associating shift operations, don't let this
		 produce a shift of the size of the object or larger.
		 This could occur when we follow a sign-extend by a right
		 shift on a machine that does a sign-extend as a pair
		 of shifts.  */

	      if (is_shift && GET_CODE (new_const) == CONST_INT
		  && INTVAL (new_const) >= GET_MODE_BITSIZE (mode))
		{
		  /* As an exception, we can turn an ASHIFTRT of this
		     form into a shift of the number of bits - 1.  */
		  if (code == ASHIFTRT)
		    new_const = GEN_INT (GET_MODE_BITSIZE (mode) - 1);
		  else
		    break;
		}

	      y = copy_rtx (XEXP (y, 0));

	      /* If Y contains our first operand (the most common way this
		 can happen is if Y is a MEM), we would do into an infinite
		 loop if we tried to fold it.  So don't in that case.  */

	      if (! reg_mentioned_p (folded_arg0, y))
		y = fold_rtx (y, insn);

	      return simplify_gen_binary (code, mode, y, new_const);
	    }
	  break;

	case DIV:       case UDIV:
	  /* ??? The associative optimization performed immediately above is
	     also possible for DIV and UDIV using associate_code of MULT.
	     However, we would need extra code to verify that the
	     multiplication does not overflow, that is, there is no overflow
	     in the calculation of new_const.  */
	  break;

	default:
	  break;
	}

      new = simplify_binary_operation (code, mode,
				       const_arg0 ? const_arg0 : folded_arg0,
				       const_arg1 ? const_arg1 : folded_arg1);
      break;

    case 'o':
      /* (lo_sum (high X) X) is simply X.  */
      if (code == LO_SUM && const_arg0 != 0
	  && GET_CODE (const_arg0) == HIGH
	  && rtx_equal_p (XEXP (const_arg0, 0), const_arg1))
	return const_arg1;
      break;

    case '3':
    case 'b':
      new = simplify_ternary_operation (code, mode, mode_arg0,
					const_arg0 ? const_arg0 : folded_arg0,
					const_arg1 ? const_arg1 : folded_arg1,
					const_arg2 ? const_arg2 : XEXP (x, 2));
      break;

    case 'x':
      /* Eliminate CONSTANT_P_RTX if its constant.  */
      if (code == CONSTANT_P_RTX)
	{
	  if (const_arg0)
	    return const1_rtx;
	  if (optimize == 0 || !flag_gcse)
	    return const0_rtx;
	}
      break;
    }

  return new ? new : x;
}

/* Return a constant value currently equivalent to X.
   Return 0 if we don't know one.  */

static rtx
equiv_constant (rtx x)
{
  if (GET_CODE (x) == REG
      && REGNO_QTY_VALID_P (REGNO (x)))
    {
      int x_q = REG_QTY (REGNO (x));
      struct qty_table_elem *x_ent = &qty_table[x_q];

      if (x_ent->const_rtx)
	x = gen_lowpart_if_possible (GET_MODE (x), x_ent->const_rtx);
    }

  if (x == 0 || CONSTANT_P (x))
    return x;

  /* If X is a MEM, try to fold it outside the context of any insn to see if
     it might be equivalent to a constant.  That handles the case where it
     is a constant-pool reference.  Then try to look it up in the hash table
     in case it is something whose value we have seen before.  */

  if (GET_CODE (x) == MEM)
    {
      struct table_elt *elt;

      x = fold_rtx (x, NULL_RTX);
      if (CONSTANT_P (x))
	return x;

      elt = lookup (x, safe_hash (x, GET_MODE (x)) & HASH_MASK, GET_MODE (x));
      if (elt == 0)
	return 0;

      for (elt = elt->first_same_value; elt; elt = elt->next_same_value)
	if (elt->is_const && CONSTANT_P (elt->exp))
	  return elt->exp;
    }

  return 0;
}

/* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a fixed-point
   number, return an rtx (MEM, SUBREG, or CONST_INT) that refers to the
   least-significant part of X.
   MODE specifies how big a part of X to return.

   If the requested operation cannot be done, 0 is returned.

   This is similar to gen_lowpart in emit-rtl.c.  */

rtx
gen_lowpart_if_possible (enum machine_mode mode, rtx x)
{
  rtx result = gen_lowpart_common (mode, x);

  if (result)
    return result;
  else if (GET_CODE (x) == MEM)
    {
      /* This is the only other case we handle.  */
      int offset = 0;
      rtx new;

      if (WORDS_BIG_ENDIAN)
	offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
		  - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
      if (BYTES_BIG_ENDIAN)
	/* Adjust the address so that the address-after-the-data is
	   unchanged.  */
	offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
		   - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));

      new = adjust_address_nv (x, mode, offset);
      if (! memory_address_p (mode, XEXP (new, 0)))
	return 0;

      return new;
    }
  else
    return 0;
}

/* Given INSN, a jump insn, TAKEN indicates if we are following the "taken"
   branch.  It will be zero if not.

   In certain cases, this can cause us to add an equivalence.  For example,
   if we are following the taken case of
	if (i == 2)
   we can add the fact that `i' and '2' are now equivalent.

   In any case, we can record that this comparison was passed.  If the same
   comparison is seen later, we will know its value.  */

static void
record_jump_equiv (rtx insn, int taken)
{
  int cond_known_true;
  rtx op0, op1;
  rtx set;
  enum machine_mode mode, mode0, mode1;
  int reversed_nonequality = 0;
  enum rtx_code code;

  /* Ensure this is the right kind of insn.  */
  if (! any_condjump_p (insn))
    return;
  set = pc_set (insn);

  /* See if this jump condition is known true or false.  */
  if (taken)
    cond_known_true = (XEXP (SET_SRC (set), 2) == pc_rtx);
  else
    cond_known_true = (XEXP (SET_SRC (set), 1) == pc_rtx);

  /* Get the type of comparison being done and the operands being compared.
     If we had to reverse a non-equality condition, record that fact so we
     know that it isn't valid for floating-point.  */
  code = GET_CODE (XEXP (SET_SRC (set), 0));
  op0 = fold_rtx (XEXP (XEXP (SET_SRC (set), 0), 0), insn);
  op1 = fold_rtx (XEXP (XEXP (SET_SRC (set), 0), 1), insn);

  code = find_comparison_args (code, &op0, &op1, &mode0, &mode1);
  if (! cond_known_true)
    {
      code = reversed_comparison_code_parts (code, op0, op1, insn);

      /* Don't remember if we can't find the inverse.  */
      if (code == UNKNOWN)
	return;
    }

  /* The mode is the mode of the non-constant.  */
  mode = mode0;
  if (mode1 != VOIDmode)
    mode = mode1;

  record_jump_cond (code, mode, op0, op1, reversed_nonequality);
}

/* We know that comparison CODE applied to OP0 and OP1 in MODE is true.
   REVERSED_NONEQUALITY is nonzero if CODE had to be swapped.
   Make any useful entries we can with that information.  Called from
   above function and called recursively.  */

static void
record_jump_cond (enum rtx_code code, enum machine_mode mode, rtx op0,
		  rtx op1, int reversed_nonequality)
{
  unsigned op0_hash, op1_hash;
  int op0_in_memory, op1_in_memory;
  struct table_elt *op0_elt, *op1_elt;

  /* If OP0 and OP1 are known equal, and either is a paradoxical SUBREG,
     we know that they are also equal in the smaller mode (this is also
     true for all smaller modes whether or not there is a SUBREG, but
     is not worth testing for with no SUBREG).  */

  /* Note that GET_MODE (op0) may not equal MODE.  */
  if (code == EQ && GET_CODE (op0) == SUBREG
      && (GET_MODE_SIZE (GET_MODE (op0))
	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))
    {
      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
      rtx tem = gen_lowpart_if_possible (inner_mode, op1);

      record_jump_cond (code, mode, SUBREG_REG (op0),
			tem ? tem : gen_rtx_SUBREG (inner_mode, op1, 0),
			reversed_nonequality);
    }

  if (code == EQ && GET_CODE (op1) == SUBREG
      && (GET_MODE_SIZE (GET_MODE (op1))
	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1)))))
    {
      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op1));
      rtx tem = gen_lowpart_if_possible (inner_mode, op0);

      record_jump_cond (code, mode, SUBREG_REG (op1),
			tem ? tem : gen_rtx_SUBREG (inner_mode, op0, 0),
			reversed_nonequality);
    }

  /* Similarly, if this is an NE comparison, and either is a SUBREG
     making a smaller mode, we know the whole thing is also NE.  */

  /* Note that GET_MODE (op0) may not equal MODE;
     if we test MODE instead, we can get an infinite recursion
     alternating between two modes each wider than MODE.  */

  if (code == NE && GET_CODE (op0) == SUBREG
      && subreg_lowpart_p (op0)
      && (GET_MODE_SIZE (GET_MODE (op0))
	  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))
    {
      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
      rtx tem = gen_lowpart_if_possible (inner_mode, op1);

      record_jump_cond (code, mode, SUBREG_REG (op0),
			tem ? tem : gen_rtx_SUBREG (inner_mode, op1, 0),
			reversed_nonequality);
    }

  if (code == NE && GET_CODE (op1) == SUBREG
      && subreg_lowpart_p (op1)
      && (GET_MODE_SIZE (GET_MODE (op1))
	  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1)))))
    {
      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op1));
      rtx tem = gen_lowpart_if_possible (inner_mode, op0);

      record_jump_cond (code, mode, SUBREG_REG (op1),
			tem ? tem : gen_rtx_SUBREG (inner_mode, op0, 0),
			reversed_nonequality);
    }

  /* Hash both operands.  */

  do_not_record = 0;
  hash_arg_in_memory = 0;
  op0_hash = HASH (op0, mode);
  op0_in_memory = hash_arg_in_memory;

  if (do_not_record)
    return;

  do_not_record = 0;
  hash_arg_in_memory = 0;
  op1_hash = HASH (op1, mode);
  op1_in_memory = hash_arg_in_memory;

  if (do_not_record)
    return;

  /* Look up both operands.  */
  op0_elt = lookup (op0, op0_hash, mode);
  op1_elt = lookup (op1, op1_hash, mode);

  /* If both operands are already equivalent or if they are not in the
     table but are identical, do nothing.  */
  if ((op0_elt != 0 && op1_elt != 0
       && op0_elt->first_same_value == op1_elt->first_same_value)
      || op0 == op1 || rtx_equal_p (op0, op1))
    return;

  /* If we aren't setting two things equal all we can do is save this
     comparison.   Similarly if this is floating-point.  In the latter
     case, OP1 might be zero and both -0.0 and 0.0 are equal to it.
     If we record the equality, we might inadvertently delete code
     whose intent was to change -0 to +0.  */

  if (code != EQ || FLOAT_MODE_P (GET_MODE (op0)))
    {
      struct qty_table_elem *ent;
      int qty;

      /* If we reversed a floating-point comparison, if OP0 is not a
	 register, or if OP1 is neither a register or constant, we can't
	 do anything.  */

      if (GET_CODE (op1) != REG)
	op1 = equiv_constant (op1);

      if ((reversed_nonequality && FLOAT_MODE_P (mode))
	  || GET_CODE (op0) != REG || op1 == 0)
	return;

      /* Put OP0 in the hash table if it isn't already.  This gives it a
	 new quantity number.  */
      if (op0_elt == 0)
	{
	  if (insert_regs (op0, NULL, 0))
	    {
	      rehash_using_reg (op0);
	      op0_hash = HASH (op0, mode);

	      /* If OP0 is contained in OP1, this changes its hash code
		 as well.  Faster to rehash than to check, except
		 for the simple case of a constant.  */
	      if (! CONSTANT_P (op1))
		op1_hash = HASH (op1,mode);
	    }

	  op0_elt = insert (op0, NULL, op0_hash, mode);
	  op0_elt->in_memory = op0_in_memory;
	}

      qty = REG_QTY (REGNO (op0));
      ent = &qty_table[qty];

      ent->comparison_code = code;
      if (GET_CODE (op1) == REG)
	{
	  /* Look it up again--in case op0 and op1 are the same.  */
	  op1_elt = lookup (op1, op1_hash, mode);

	  /* Put OP1 in the hash table so it gets a new quantity number.  */
	  if (op1_elt == 0)
	    {
	      if (insert_regs (op1, NULL, 0))
		{
		  rehash_using_reg (op1);
		  op1_hash = HASH (op1, mode);
		}

	      op1_elt = insert (op1, NULL, op1_hash, mode);
	      op1_elt->in_memory = op1_in_memory;
	    }

	  ent->comparison_const = NULL_RTX;
	  ent->comparison_qty = REG_QTY (REGNO (op1));
	}
      else
	{
	  ent->comparison_const = op1;
	  ent->comparison_qty = -1;
	}

      return;
    }

  /* If either side is still missing an equivalence, make it now,
     then merge the equivalences.  */

  if (op0_elt == 0)
    {
      if (insert_regs (op0, NULL, 0))
	{
	  rehash_using_reg (op0);
	  op0_hash = HASH (op0, mode);
	}

      op0_elt = insert (op0, NULL, op0_hash, mode);
      op0_elt->in_memory = op0_in_memory;
    }

  if (op1_elt == 0)
    {
      if (insert_regs (op1, NULL, 0))
	{
	  rehash_using_reg (op1);
	  op1_hash = HASH (op1, mode);
	}

      op1_elt = insert (op1, NULL, op1_hash, mode);
      op1_elt->in_memory = op1_in_memory;
    }

  merge_equiv_classes (op0_elt, op1_elt);
  last_jump_equiv_class = op0_elt;
}

/* CSE processing for one instruction.
   First simplify sources and addresses of all assignments
   in the instruction, using previously-computed equivalents values.
   Then install the new sources and destinations in the table
   of available values.

   If LIBCALL_INSN is nonzero, don't record any equivalence made in
   the insn.  It means that INSN is inside libcall block.  In this
   case LIBCALL_INSN is the corresponding insn with REG_LIBCALL.  */

/* Data on one SET contained in the instruction.  */

struct set
{
  /* The SET rtx itself.  */
  rtx rtl;
  /* The SET_SRC of the rtx (the original value, if it is changing).  */
  rtx src;
  /* The hash-table element for the SET_SRC of the SET.  */
  struct table_elt *src_elt;
  /* Hash value for the SET_SRC.  */
  unsigned src_hash;
  /* Hash value for the SET_DEST.  */
  unsigned dest_hash;
  /* The SET_DEST, with SUBREG, etc., stripped.  */
  rtx inner_dest;
  /* Nonzero if the SET_SRC is in memory.  */
  char src_in_memory;
  /* Nonzero if the SET_SRC contains something
     whose value cannot be predicted and understood.  */
  char src_volatile;
  /* Original machine mode, in case it becomes a CONST_INT.
     The size of this field should match the size of the mode
     field of struct rtx_def (see rtl.h).  */
  ENUM_BITFIELD(machine_mode) mode : 8;
  /* A constant equivalent for SET_SRC, if any.  */
  rtx src_const;
  /* Original SET_SRC value used for libcall notes.  */
  rtx orig_src;
  /* Hash value of constant equivalent for SET_SRC.  */
  unsigned src_const_hash;
  /* Table entry for constant equivalent for SET_SRC, if any.  */
  struct table_elt *src_const_elt;
};

static void
cse_insn (rtx insn, rtx libcall_insn)
{
  rtx x = PATTERN (insn);
  int i;
  rtx tem;
  int n_sets = 0;

#ifdef HAVE_cc0
  /* Records what this insn does to set CC0.  */
  rtx this_insn_cc0 = 0;
  enum machine_mode this_insn_cc0_mode = VOIDmode;
#endif

  rtx src_eqv = 0;
  struct table_elt *src_eqv_elt = 0;
  int src_eqv_volatile = 0;
  int src_eqv_in_memory = 0;
  unsigned src_eqv_hash = 0;

  struct set *sets = (struct set *) 0;

  this_insn = insn;

  /* Find all the SETs and CLOBBERs in this instruction.
     Record all the SETs in the array `set' and count them.
     Also determine whether there is a CLOBBER that invalidates
     all memory references, or all references at varying addresses.  */

  if (GET_CODE (insn) == CALL_INSN)
    {
      for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
	{
	  if (GET_CODE (XEXP (tem, 0)) == CLOBBER)
	    invalidate (SET_DEST (XEXP (tem, 0)), VOIDmode);
	  XEXP (tem, 0) = canon_reg (XEXP (tem, 0), insn);
	}
    }

  if (GET_CODE (x) == SET)
    {
      sets = alloca (sizeof (struct set));
      sets[0].rtl = x;

      /* Ignore SETs that are unconditional jumps.
	 They never need cse processing, so this does not hurt.
	 The reason is not efficiency but rather
	 so that we can test at the end for instructions
	 that have been simplified to unconditional jumps
	 and not be misled by unchanged instructions
	 that were unconditional jumps to begin with.  */
      if (SET_DEST (x) == pc_rtx
	  && GET_CODE (SET_SRC (x)) == LABEL_REF)
	;

      /* Don't count call-insns, (set (reg 0) (call ...)), as a set.
	 The hard function value register is used only once, to copy to
	 someplace else, so it isn't worth cse'ing (and on 80386 is unsafe)!
	 Ensure we invalidate the destination register.  On the 80386 no
	 other code would invalidate it since it is a fixed_reg.
	 We need not check the return of apply_change_group; see canon_reg.  */

      else if (GET_CODE (SET_SRC (x)) == CALL)
	{
	  canon_reg (SET_SRC (x), insn);
	  apply_change_group ();
	  fold_rtx (SET_SRC (x), insn);
	  invalidate (SET_DEST (x), VOIDmode);
	}
      else
	n_sets = 1;
    }
  else if (GET_CODE (x) == PARALLEL)
    {
      int lim = XVECLEN (x, 0);

      sets = alloca (lim * sizeof (struct set));

      /* Find all regs explicitly clobbered in this insn,
	 and ensure they are not replaced with any other regs
	 elsewhere in this insn.
	 When a reg that is clobbered is also used for input,
	 we should presume that that is for a reason,
	 and we should not substitute some other register
	 which is not supposed to be clobbered.
	 Therefore, this loop cannot be merged into the one below
	 because a CALL may precede a CLOBBER and refer to the
	 value clobbered.  We must not let a canonicalization do
	 anything in that case.  */
      for (i = 0; i < lim; i++)
	{
	  rtx y = XVECEXP (x, 0, i);
	  if (GET_CODE (y) == CLOBBER)
	    {
	      rtx clobbered = XEXP (y, 0);

	      if (GET_CODE (clobbered) == REG
		  || GET_CODE (clobbered) == SUBREG)
		invalidate (clobbered, VOIDmode);
	      else if (GET_CODE (clobbered) == STRICT_LOW_PART
		       || GET_CODE (clobbered) == ZERO_EXTRACT)
		invalidate (XEXP (clobbered, 0), GET_MODE (clobbered));
	    }
	}

      for (i = 0; i < lim; i++)
	{
	  rtx y = XVECEXP (x, 0, i);
	  if (GET_CODE (y) == SET)
	    {
	      /* As above, we ignore unconditional jumps and call-insns and
		 ignore the result of apply_change_group.  */
	      if (GET_CODE (SET_SRC (y)) == CALL)
		{
		  canon_reg (SET_SRC (y), insn);
		  apply_change_group ();
		  fold_rtx (SET_SRC (y), insn);
		  invalidate (SET_DEST (y), VOIDmode);
		}
	      else if (SET_DEST (y) == pc_rtx
		       && GET_CODE (SET_SRC (y)) == LABEL_REF)
		;
	      else
		sets[n_sets++].rtl = y;
	    }
	  else if (GET_CODE (y) == CLOBBER)
	    {
	      /* If we clobber memory, canon the address.
		 This does nothing when a register is clobbered
		 because we have already invalidated the reg.  */
	      if (GET_CODE (XEXP (y, 0)) == MEM)
		canon_reg (XEXP (y, 0), NULL_RTX);
	    }
	  else if (GET_CODE (y) == USE
		   && ! (GET_CODE (XEXP (y, 0)) == REG
			 && REGNO (XEXP (y, 0)) < FIRST_PSEUDO_REGISTER))
	    canon_reg (y, NULL_RTX);
	  else if (GET_CODE (y) == CALL)
	    {
	      /* The result of apply_change_group can be ignored; see
		 canon_reg.  */
	      canon_reg (y, insn);
	      apply_change_group ();
	      fold_rtx (y, insn);
	    }
	}
    }
  else if (GET_CODE (x) == CLOBBER)
    {
      if (GET_CODE (XEXP (x, 0)) == MEM)
	canon_reg (XEXP (x, 0), NULL_RTX);
    }

  /* Canonicalize a USE of a pseudo register or memory location.  */
  else if (GET_CODE (x) == USE
	   && ! (GET_CODE (XEXP (x, 0)) == REG
		 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER))
    canon_reg (XEXP (x, 0), NULL_RTX);
  else if (GET_CODE (x) == CALL)
    {
      /* The result of apply_change_group can be ignored; see canon_reg.  */
      canon_reg (x, insn);
      apply_change_group ();
      fold_rtx (x, insn);
    }

  /* Store the equivalent value in SRC_EQV, if different, or if the DEST
     is a STRICT_LOW_PART.  The latter condition is necessary because SRC_EQV
     is handled specially for this case, and if it isn't set, then there will
     be no equivalence for the destination.  */
  if (n_sets == 1 && REG_NOTES (insn) != 0
      && (tem = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0
      && (! rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl))
	  || GET_CODE (SET_DEST (sets[0].rtl)) == STRICT_LOW_PART))
    {
      src_eqv = fold_rtx (canon_reg (XEXP (tem, 0), NULL_RTX), insn);
      XEXP (tem, 0) = src_eqv;
    }

  /* Canonicalize sources and addresses of destinations.
     We do this in a separate pass to avoid problems when a MATCH_DUP is
     present in the insn pattern.  In that case, we want to ensure that
     we don't break the duplicate nature of the pattern.  So we will replace
     both operands at the same time.  Otherwise, we would fail to find an
     equivalent substitution in the loop calling validate_change below.

     We used to suppress canonicalization of DEST if it appears in SRC,
     but we don't do this any more.  */

  for (i = 0; i < n_sets; i++)
    {
      rtx dest = SET_DEST (sets[i].rtl);
      rtx src = SET_SRC (sets[i].rtl);
      rtx new = canon_reg (src, insn);
      int insn_code;

      sets[i].orig_src = src;
      if ((GET_CODE (new) == REG && GET_CODE (src) == REG
	   && ((REGNO (new) < FIRST_PSEUDO_REGISTER)
	       != (REGNO (src) < FIRST_PSEUDO_REGISTER)))
	  || (insn_code = recog_memoized (insn)) < 0
	  || insn_data[insn_code].n_dups > 0)
	validate_change (insn, &SET_SRC (sets[i].rtl), new, 1);
      else
	SET_SRC (sets[i].rtl) = new;

      if (GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT)
	{
	  validate_change (insn, &XEXP (dest, 1),
			   canon_reg (XEXP (dest, 1), insn), 1);
	  validate_change (insn, &XEXP (dest, 2),
			   canon_reg (XEXP (dest, 2), insn), 1);
	}

      while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
	     || GET_CODE (dest) == ZERO_EXTRACT
	     || GET_CODE (dest) == SIGN_EXTRACT)
	dest = XEXP (dest, 0);

      if (GET_CODE (dest) == MEM)
	canon_reg (dest, insn);
    }

  /* Now that we have done all the replacements, we can apply the change
     group and see if they all work.  Note that this will cause some
     canonicalizations that would have worked individually not to be applied
     because some other canonicalization didn't work, but this should not
     occur often.

     The result of apply_change_group can be ignored; see canon_reg.  */

  apply_change_group ();

  /* Set sets[i].src_elt to the class each source belongs to.
     Detect assignments from or to volatile things
     and set set[i] to zero so they will be ignored
     in the rest of this function.

     Nothing in this loop changes the hash table or the register chains.  */

  for (i = 0; i < n_sets; i++)
    {
      rtx src, dest;
      rtx src_folded;
      struct table_elt *elt = 0, *p;
      enum machine_mode mode;
      rtx src_eqv_here;
      rtx src_const = 0;
      rtx src_related = 0;
      struct table_elt *src_const_elt = 0;
      int src_cost = MAX_COST;
      int src_eqv_cost = MAX_COST;
      int src_folded_cost = MAX_COST;
      int src_related_cost = MAX_COST;
      int src_elt_cost = MAX_COST;
      int src_regcost = MAX_COST;
      int src_eqv_regcost = MAX_COST;
      int src_folded_regcost = MAX_COST;
      int src_related_regcost = MAX_COST;
      int src_elt_regcost = MAX_COST;
      /* Set nonzero if we need to call force_const_mem on with the
	 contents of src_folded before using it.  */
      int src_folded_force_flag = 0;

      dest = SET_DEST (sets[i].rtl);
      src = SET_SRC (sets[i].rtl);

      /* If SRC is a constant that has no machine mode,
	 hash it with the destination's machine mode.
	 This way we can keep different modes separate.  */

      mode = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src);
      sets[i].mode = mode;

      if (src_eqv)
	{
	  enum machine_mode eqvmode = mode;
	  if (GET_CODE (dest) == STRICT_LOW_PART)
	    eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
	  do_not_record = 0;
	  hash_arg_in_memory = 0;
	  src_eqv_hash = HASH (src_eqv, eqvmode);

	  /* Find the equivalence class for the equivalent expression.  */

	  if (!do_not_record)
	    src_eqv_elt = lookup (src_eqv, src_eqv_hash, eqvmode);

	  src_eqv_volatile = do_not_record;
	  src_eqv_in_memory = hash_arg_in_memory;
	}

      /* If this is a STRICT_LOW_PART assignment, src_eqv corresponds to the
	 value of the INNER register, not the destination.  So it is not
	 a valid substitution for the source.  But save it for later.  */
      if (GET_CODE (dest) == STRICT_LOW_PART)
	src_eqv_here = 0;
      else
	src_eqv_here = src_eqv;

      /* Simplify and foldable subexpressions in SRC.  Then get the fully-
	 simplified result, which may not necessarily be valid.  */
      src_folded = fold_rtx (src, insn);

#if 0
      /* ??? This caused bad code to be generated for the m68k port with -O2.
	 Suppose src is (CONST_INT -1), and that after truncation src_folded
	 is (CONST_INT 3).  Suppose src_folded is then used for src_const.
	 At the end we will add src and src_const to the same equivalence
	 class.  We now have 3 and -1 on the same equivalence class.  This
	 causes later instructions to be mis-optimized.  */
      /* If storing a constant in a bitfield, pre-truncate the constant
	 so we will be able to record it later.  */
      if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT
	  || GET_CODE (SET_DEST (sets[i].rtl)) == SIGN_EXTRACT)
	{
	  rtx width = XEXP (SET_DEST (sets[i].rtl), 1);

	  if (GET_CODE (src) == CONST_INT
	      && GET_CODE (width) == CONST_INT
	      && INTVAL (width) < HOST_BITS_PER_WIDE_INT
	      && (INTVAL (src) & ((HOST_WIDE_INT) (-1) << INTVAL (width))))
	    src_folded
	      = GEN_INT (INTVAL (src) & (((HOST_WIDE_INT) 1
					  << INTVAL (width)) - 1));
	}
#endif

      /* Compute SRC's hash code, and also notice if it
	 should not be recorded at all.  In that case,
	 prevent any further processing of this assignment.  */
      do_not_record = 0;
      hash_arg_in_memory = 0;

      sets[i].src = src;
      sets[i].src_hash = HASH (src, mode);
      sets[i].src_volatile = do_not_record;
      sets[i].src_in_memory = hash_arg_in_memory;

      /* If SRC is a MEM, there is a REG_EQUIV note for SRC, and DEST is
	 a pseudo, do not record SRC.  Using SRC as a replacement for
	 anything else will be incorrect in that situation.  Note that
	 this usually occurs only for stack slots, in which case all the
	 RTL would be referring to SRC, so we don't lose any optimization
	 opportunities by not having SRC in the hash table.  */

      if (GET_CODE (src) == MEM
	  && find_reg_note (insn, REG_EQUIV, NULL_RTX) != 0
	  && GET_CODE (dest) == REG
	  && REGNO (dest) >= FIRST_PSEUDO_REGISTER)
	sets[i].src_volatile = 1;

#if 0
      /* It is no longer clear why we used to do this, but it doesn't
	 appear to still be needed.  So let's try without it since this
	 code hurts cse'ing widened ops.  */
      /* If source is a perverse subreg (such as QI treated as an SI),
	 treat it as volatile.  It may do the work of an SI in one context
	 where the extra bits are not being used, but cannot replace an SI
	 in general.  */
      if (GET_CODE (src) == SUBREG
	  && (GET_MODE_SIZE (GET_MODE (src))
	      > GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))
	sets[i].src_volatile = 1;
#endif

      /* Locate all possible equivalent forms for SRC.  Try to replace
         SRC in the insn with each cheaper equivalent.

         We have the following types of equivalents: SRC itself, a folded
         version, a value given in a REG_EQUAL note, or a value related
	 to a constant.

         Each of these equivalents may be part of an additional class
         of equivalents (if more than one is in the table, they must be in
         the same class; we check for this).

	 If the source is volatile, we don't do any table lookups.

         We note any constant equivalent for possible later use in a
         REG_NOTE.  */

      if (!sets[i].src_volatile)
	elt = lookup (src, sets[i].src_hash, mode);

      sets[i].src_elt = elt;

      if (elt && src_eqv_here && src_eqv_elt)
	{
	  if (elt->first_same_value != src_eqv_elt->first_same_value)
	    {
	      /* The REG_EQUAL is indicating that two formerly distinct
		 classes are now equivalent.  So merge them.  */
	      merge_equiv_classes (elt, src_eqv_elt);
	      src_eqv_hash = HASH (src_eqv, elt->mode);
	      src_eqv_elt = lookup (src_eqv, src_eqv_hash, elt->mode);
	    }

	  src_eqv_here = 0;
	}

      else if (src_eqv_elt)
	elt = src_eqv_elt;

      /* Try to find a constant somewhere and record it in `src_const'.
	 Record its table element, if any, in `src_const_elt'.  Look in
	 any known equivalences first.  (If the constant is not in the
	 table, also set `sets[i].src_const_hash').  */
      if (elt)
	for (p = elt->first_same_value; p; p = p->next_same_value)
	  if (p->is_const)
	    {
	      src_const = p->exp;
	      src_const_elt = elt;
	      break;
	    }

      if (src_const == 0
	  && (CONSTANT_P (src_folded)
	      /* Consider (minus (label_ref L1) (label_ref L2)) as
		 "constant" here so we will record it. This allows us
		 to fold switch statements when an ADDR_DIFF_VEC is used.  */
	      || (GET_CODE (src_folded) == MINUS
		  && GET_CODE (XEXP (src_folded, 0)) == LABEL_REF
		  && GET_CODE (XEXP (src_folded, 1)) == LABEL_REF)))
	src_const = src_folded, src_const_elt = elt;
      else if (src_const == 0 && src_eqv_here && CONSTANT_P (src_eqv_here))
	src_const = src_eqv_here, src_const_elt = src_eqv_elt;

      /* If we don't know if the constant is in the table, get its
	 hash code and look it up.  */
      if (src_const && src_const_elt == 0)
	{
	  sets[i].src_const_hash = HASH (src_const, mode);
	  src_const_elt = lookup (src_const, sets[i].src_const_hash, mode);
	}

      sets[i].src_const = src_const;
      sets[i].src_const_elt = src_const_elt;

      /* If the constant and our source are both in the table, mark them as
	 equivalent.  Otherwise, if a constant is in the table but the source
	 isn't, set ELT to it.  */
      if (src_const_elt && elt
	  && src_const_elt->first_same_value != elt->first_same_value)
	merge_equiv_classes (elt, src_const_elt);
      else if (src_const_elt && elt == 0)
	elt = src_const_elt;

      /* See if there is a register linearly related to a constant
         equivalent of SRC.  */
      if (src_const
	  && (GET_CODE (src_const) == CONST
	      || (src_const_elt && src_const_elt->related_value != 0)))
	{
	  src_related = use_related_value (src_const, src_const_elt);
	  if (src_related)
	    {
	      struct table_elt *src_related_elt
		= lookup (src_related, HASH (src_related, mode), mode);
	      if (src_related_elt && elt)
		{
		  if (elt->first_same_value
		      != src_related_elt->first_same_value)
		    /* This can occur when we previously saw a CONST
		       involving a SYMBOL_REF and then see the SYMBOL_REF
		       twice.  Merge the involved classes.  */
		    merge_equiv_classes (elt, src_related_elt);

		  src_related = 0;
		  src_related_elt = 0;
		}
	      else if (src_related_elt && elt == 0)
		elt = src_related_elt;
	    }
	}

      /* See if we have a CONST_INT that is already in a register in a
	 wider mode.  */

      if (src_const && src_related == 0 && GET_CODE (src_const) == CONST_INT
	  && GET_MODE_CLASS (mode) == MODE_INT
	  && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
	{
	  enum machine_mode wider_mode;

	  for (wider_mode = GET_MODE_WIDER_MODE (mode);
	       GET_MODE_BITSIZE (wider_mode) <= BITS_PER_WORD
	       && src_related == 0;
	       wider_mode = GET_MODE_WIDER_MODE (wider_mode))
	    {
	      struct table_elt *const_elt
		= lookup (src_const, HASH (src_const, wider_mode), wider_mode);

	      if (const_elt == 0)
		continue;

	      for (const_elt = const_elt->first_same_value;
		   const_elt; const_elt = const_elt->next_same_value)
		if (GET_CODE (const_elt->exp) == REG)
		  {
		    src_related = gen_lowpart_if_possible (mode,
							   const_elt->exp);
		    break;
		  }
	    }
	}

      /* Another possibility is that we have an AND with a constant in
	 a mode narrower than a word.  If so, it might have been generated
	 as part of an "if" which would narrow the AND.  If we already
	 have done the AND in a wider mode, we can use a SUBREG of that
	 value.  */

      if (flag_expensive_optimizations && ! src_related
	  && GET_CODE (src) == AND && GET_CODE (XEXP (src, 1)) == CONST_INT
	  && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
	{
	  enum machine_mode tmode;
	  rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));

	  for (tmode = GET_MODE_WIDER_MODE (mode);
	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
	       tmode = GET_MODE_WIDER_MODE (tmode))
	    {
	      rtx inner = gen_lowpart_if_possible (tmode, XEXP (src, 0));
	      struct table_elt *larger_elt;

	      if (inner)
		{
		  PUT_MODE (new_and, tmode);
		  XEXP (new_and, 0) = inner;
		  larger_elt = lookup (new_and, HASH (new_and, tmode), tmode);
		  if (larger_elt == 0)
		    continue;

		  for (larger_elt = larger_elt->first_same_value;
		       larger_elt; larger_elt = larger_elt->next_same_value)
		    if (GET_CODE (larger_elt->exp) == REG)
		      {
			src_related
			  = gen_lowpart_if_possible (mode, larger_elt->exp);
			break;
		      }

		  if (src_related)
		    break;
		}
	    }
	}

#ifdef LOAD_EXTEND_OP
      /* See if a MEM has already been loaded with a widening operation;
	 if it has, we can use a subreg of that.  Many CISC machines
	 also have such operations, but this is only likely to be
	 beneficial these machines.  */

      if (flag_expensive_optimizations && src_related == 0
	  && (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
	  && GET_MODE_CLASS (mode) == MODE_INT
	  && GET_CODE (src) == MEM && ! do_not_record
	  && LOAD_EXTEND_OP (mode) != NIL)
	{
	  enum machine_mode tmode;

	  /* Set what we are trying to extend and the operation it might
	     have been extended with.  */
	  PUT_CODE (memory_extend_rtx, LOAD_EXTEND_OP (mode));
	  XEXP (memory_extend_rtx, 0) = src;

	  for (tmode = GET_MODE_WIDER_MODE (mode);
	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
	       tmode = GET_MODE_WIDER_MODE (tmode))
	    {
	      struct table_elt *larger_elt;

	      PUT_MODE (memory_extend_rtx, tmode);
	      larger_elt = lookup (memory_extend_rtx,
				   HASH (memory_extend_rtx, tmode), tmode);
	      if (larger_elt == 0)
		continue;

	      for (larger_elt = larger_elt->first_same_value;
		   larger_elt; larger_elt = larger_elt->next_same_value)
		if (GET_CODE (larger_elt->exp) == REG)
		  {
		    src_related = gen_lowpart_if_possible (mode,
							   larger_elt->exp);
		    break;
		  }

	      if (src_related)
		break;
	    }
	}
#endif /* LOAD_EXTEND_OP */

      if (src == src_folded)
	src_folded = 0;

      /* At this point, ELT, if nonzero, points to a class of expressions
         equivalent to the source of this SET and SRC, SRC_EQV, SRC_FOLDED,
	 and SRC_RELATED, if nonzero, each contain additional equivalent
	 expressions.  Prune these latter expressions by deleting expressions
	 already in the equivalence class.

	 Check for an equivalent identical to the destination.  If found,
	 this is the preferred equivalent since it will likely lead to
	 elimination of the insn.  Indicate this by placing it in
	 `src_related'.  */

      if (elt)
	elt = elt->first_same_value;
      for (p = elt; p; p = p->next_same_value)
	{
	  enum rtx_code code = GET_CODE (p->exp);

	  /* If the expression is not valid, ignore it.  Then we do not
	     have to check for validity below.  In most cases, we can use
	     `rtx_equal_p', since canonicalization has already been done.  */
	  if (code != REG && ! exp_equiv_p (p->exp, p->exp, 1, 0))
	    continue;

	  /* Also skip paradoxical subregs, unless that's what we're
	     looking for.  */
	  if (code == SUBREG
	      && (GET_MODE_SIZE (GET_MODE (p->exp))
		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (p->exp))))
	      && ! (src != 0
		    && GET_CODE (src) == SUBREG
		    && GET_MODE (src) == GET_MODE (p->exp)
		    && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
			< GET_MODE_SIZE (GET_MODE (SUBREG_REG (p->exp))))))
	    continue;

	  if (src && GET_CODE (src) == code && rtx_equal_p (src, p->exp))
	    src = 0;
	  else if (src_folded && GET_CODE (src_folded) == code
		   && rtx_equal_p (src_folded, p->exp))
	    src_folded = 0;
	  else if (src_eqv_here && GET_CODE (src_eqv_here) == code
		   && rtx_equal_p (src_eqv_here, p->exp))
	    src_eqv_here = 0;
	  else if (src_related && GET_CODE (src_related) == code
		   && rtx_equal_p (src_related, p->exp))
	    src_related = 0;

	  /* This is the same as the destination of the insns, we want
	     to prefer it.  Copy it to src_related.  The code below will
	     then give it a negative cost.  */
	  if (GET_CODE (dest) == code && rtx_equal_p (p->exp, dest))
	    src_related = dest;
	}

      /* Find the cheapest valid equivalent, trying all the available
         possibilities.  Prefer items not in the hash table to ones
         that are when they are equal cost.  Note that we can never
         worsen an insn as the current contents will also succeed.
	 If we find an equivalent identical to the destination, use it as best,
	 since this insn will probably be eliminated in that case.  */
      if (src)
	{
	  if (rtx_equal_p (src, dest))
	    src_cost = src_regcost = -1;
	  else
	    {
	      src_cost = COST (src);
	      src_regcost = approx_reg_cost (src);
	    }
	}

      if (src_eqv_here)
	{
	  if (rtx_equal_p (src_eqv_here, dest))
	    src_eqv_cost = src_eqv_regcost = -1;
	  else
	    {
	      src_eqv_cost = COST (src_eqv_here);
	      src_eqv_regcost = approx_reg_cost (src_eqv_here);
	    }
	}

      if (src_folded)
	{
	  if (rtx_equal_p (src_folded, dest))
	    src_folded_cost = src_folded_regcost = -1;
	  else
	    {
	      src_folded_cost = COST (src_folded);
	      src_folded_regcost = approx_reg_cost (src_folded);
	    }
	}

      if (src_related)
	{
	  if (rtx_equal_p (src_related, dest))
	    src_related_cost = src_related_regcost = -1;
	  else
	    {
	      src_related_cost = COST (src_related);
	      src_related_regcost = approx_reg_cost (src_related);
	    }
	}

      /* If this was an indirect jump insn, a known label will really be
	 cheaper even though it looks more expensive.  */
      if (dest == pc_rtx && src_const && GET_CODE (src_const) == LABEL_REF)
	src_folded = src_const, src_folded_cost = src_folded_regcost = -1;

      /* Terminate loop when replacement made.  This must terminate since
         the current contents will be tested and will always be valid.  */
      while (1)
	{
	  rtx trial;

	  /* Skip invalid entries.  */
	  while (elt && GET_CODE (elt->exp) != REG
		 && ! exp_equiv_p (elt->exp, elt->exp, 1, 0))
	    elt = elt->next_same_value;

	  /* A paradoxical subreg would be bad here: it'll be the right
	     size, but later may be adjusted so that the upper bits aren't
	     what we want.  So reject it.  */
	  if (elt != 0
	      && GET_CODE (elt->exp) == SUBREG
	      && (GET_MODE_SIZE (GET_MODE (elt->exp))
		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (elt->exp))))
	      /* It is okay, though, if the rtx we're trying to match
		 will ignore any of the bits we can't predict.  */
	      && ! (src != 0
		    && GET_CODE (src) == SUBREG
		    && GET_MODE (src) == GET_MODE (elt->exp)
		    && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
			< GET_MODE_SIZE (GET_MODE (SUBREG_REG (elt->exp))))))
	    {
	      elt = elt->next_same_value;
	      continue;
	    }

	  if (elt)
	    {
	      src_elt_cost = elt->cost;
	      src_elt_regcost = elt->regcost;
	    }

	  /* Find cheapest and skip it for the next time.   For items
	     of equal cost, use this order:
	     src_folded, src, src_eqv, src_related and hash table entry.  */
	  if (src_folded
	      && preferrable (src_folded_cost, src_folded_regcost,
			      src_cost, src_regcost) <= 0
	      && preferrable (src_folded_cost, src_folded_regcost,
			      src_eqv_cost, src_eqv_regcost) <= 0
	      && preferrable (src_folded_cost, src_folded_regcost,
			      src_related_cost, src_related_regcost) <= 0
	      && preferrable (src_folded_cost, src_folded_regcost,
			      src_elt_cost, src_elt_regcost) <= 0)
	    {
	      trial = src_folded, src_folded_cost = MAX_COST;
	      if (src_folded_force_flag)
		{
		  rtx forced = force_const_mem (mode, trial);
		  if (forced)
		    trial = forced;
		}
	    }
	  else if (src
		   && preferrable (src_cost, src_regcost,
				   src_eqv_cost, src_eqv_regcost) <= 0
		   && preferrable (src_cost, src_regcost,
				   src_related_cost, src_related_regcost) <= 0
		   && preferrable (src_cost, src_regcost,
				   src_elt_cost, src_elt_regcost) <= 0)
	    trial = src, src_cost = MAX_COST;
	  else if (src_eqv_here
		   && preferrable (src_eqv_cost, src_eqv_regcost,
				   src_related_cost, src_related_regcost) <= 0
		   && preferrable (src_eqv_cost, src_eqv_regcost,
				   src_elt_cost, src_elt_regcost) <= 0)
	    trial = copy_rtx (src_eqv_here), src_eqv_cost = MAX_COST;
	  else if (src_related
		   && preferrable (src_related_cost, src_related_regcost,
				   src_elt_cost, src_elt_regcost) <= 0)
	    trial = copy_rtx (src_related), src_related_cost = MAX_COST;
	  else
	    {
	      trial = copy_rtx (elt->exp);
	      elt = elt->next_same_value;
	      src_elt_cost = MAX_COST;
	    }

	  /* We don't normally have an insn matching (set (pc) (pc)), so
	     check for this separately here.  We will delete such an
	     insn below.

	     For other cases such as a table jump or conditional jump
	     where we know the ultimate target, go ahead and replace the
	     operand.  While that may not make a valid insn, we will
	     reemit the jump below (and also insert any necessary
	     barriers).  */
	  if (n_sets == 1 && dest == pc_rtx
	      && (trial == pc_rtx
		  || (GET_CODE (trial) == LABEL_REF
		      && ! condjump_p (insn))))
	    {
	      SET_SRC (sets[i].rtl) = trial;
	      cse_jumps_altered = 1;
	      break;
	    }

	  /* Look for a substitution that makes a valid insn.  */
	  else if (validate_change (insn, &SET_SRC (sets[i].rtl), trial, 0))
	    {
	      rtx new = canon_reg (SET_SRC (sets[i].rtl), insn);

	      /* If we just made a substitution inside a libcall, then we
		 need to make the same substitution in any notes attached
		 to the RETVAL insn.  */
	      if (libcall_insn
		  && (GET_CODE (sets[i].orig_src) == REG
		      || GET_CODE (sets[i].orig_src) == SUBREG
		      || GET_CODE (sets[i].orig_src) == MEM))
		simplify_replace_rtx (REG_NOTES (libcall_insn),
				      sets[i].orig_src, copy_rtx (new));

	      /* The result of apply_change_group can be ignored; see
		 canon_reg.  */

	      validate_change (insn, &SET_SRC (sets[i].rtl), new, 1);
	      apply_change_group ();
	      break;
	    }

	  /* If we previously found constant pool entries for
	     constants and this is a constant, try making a
	     pool entry.  Put it in src_folded unless we already have done
	     this since that is where it likely came from.  */

	  else if (constant_pool_entries_cost
		   && CONSTANT_P (trial)
		   /* Reject cases that will abort in decode_rtx_const.
		      On the alpha when simplifying a switch, we get
		      (const (truncate (minus (label_ref) (label_ref)))).  */
		   && ! (GET_CODE (trial) == CONST
			 && GET_CODE (XEXP (trial, 0)) == TRUNCATE)
		   /* Likewise on IA-64, except without the truncate.  */
		   && ! (GET_CODE (trial) == CONST
			 && GET_CODE (XEXP (trial, 0)) == MINUS
			 && GET_CODE (XEXP (XEXP (trial, 0), 0)) == LABEL_REF
			 && GET_CODE (XEXP (XEXP (trial, 0), 1)) == LABEL_REF)
		   && (src_folded == 0
		       || (GET_CODE (src_folded) != MEM
			   && ! src_folded_force_flag))
		   && GET_MODE_CLASS (mode) != MODE_CC
		   && mode != VOIDmode)
	    {
	      src_folded_force_flag = 1;
	      src_folded = trial;
	      src_folded_cost = constant_pool_entries_cost;
	      src_folded_regcost = constant_pool_entries_regcost;
	    }
	}

      src = SET_SRC (sets[i].rtl);

      /* In general, it is good to have a SET with SET_SRC == SET_DEST.
	 However, there is an important exception:  If both are registers
	 that are not the head of their equivalence class, replace SET_SRC
	 with the head of the class.  If we do not do this, we will have
	 both registers live over a portion of the basic block.  This way,
	 their lifetimes will likely abut instead of overlapping.  */
      if (GET_CODE (dest) == REG
	  && REGNO_QTY_VALID_P (REGNO (dest)))
	{
	  int dest_q = REG_QTY (REGNO (dest));
	  struct qty_table_elem *dest_ent = &qty_table[dest_q];

	  if (dest_ent->mode == GET_MODE (dest)
	      && dest_ent->first_reg != REGNO (dest)
	      && GET_CODE (src) == REG && REGNO (src) == REGNO (dest)
	      /* Don't do this if the original insn had a hard reg as
		 SET_SRC or SET_DEST.  */
	      && (GET_CODE (sets[i].src) != REG
		  || REGNO (sets[i].src) >= FIRST_PSEUDO_REGISTER)
	      && (GET_CODE (dest) != REG || REGNO (dest) >= FIRST_PSEUDO_REGISTER))
	    /* We can't call canon_reg here because it won't do anything if
	       SRC is a hard register.  */
	    {
	      int src_q = REG_QTY (REGNO (src));
	      struct qty_table_elem *src_ent = &qty_table[src_q];
	      int first = src_ent->first_reg;
	      rtx new_src
		= (first >= FIRST_PSEUDO_REGISTER
		   ? regno_reg_rtx[first] : gen_rtx_REG (GET_MODE (src), first));

	      /* We must use validate-change even for this, because this
		 might be a special no-op instruction, suitable only to
		 tag notes onto.  */
	      if (validate_change (insn, &SET_SRC (sets[i].rtl), new_src, 0))
		{
		  src = new_src;
		  /* If we had a constant that is cheaper than what we are now
		     setting SRC to, use that constant.  We ignored it when we
		     thought we could make this into a no-op.  */
		  if (src_const && COST (src_const) < COST (src)
		      && validate_change (insn, &SET_SRC (sets[i].rtl),
					  src_const, 0))
		    src = src_const;
		}
	    }
	}

      /* If we made a change, recompute SRC values.  */
      if (src != sets[i].src)
	{
	  cse_altered = 1;
	  do_not_record = 0;
	  hash_arg_in_memory = 0;
	  sets[i].src = src;
	  sets[i].src_hash = HASH (src, mode);
	  sets[i].src_volatile = do_not_record;
	  sets[i].src_in_memory = hash_arg_in_memory;
	  sets[i].src_elt = lookup (src, sets[i].src_hash, mode);
	}

      /* If this is a single SET, we are setting a register, and we have an
	 equivalent constant, we want to add a REG_NOTE.   We don't want
	 to write a REG_EQUAL note for a constant pseudo since verifying that
	 that pseudo hasn't been eliminated is a pain.  Such a note also
	 won't help anything.

	 Avoid a REG_EQUAL note for (CONST (MINUS (LABEL_REF) (LABEL_REF)))
	 which can be created for a reference to a compile time computable
	 entry in a jump table.  */

      if (n_sets == 1 && src_const && GET_CODE (dest) == REG
	  && GET_CODE (src_const) != REG
	  && ! (GET_CODE (src_const) == CONST
		&& GET_CODE (XEXP (src_const, 0)) == MINUS
		&& GET_CODE (XEXP (XEXP (src_const, 0), 0)) == LABEL_REF
		&& GET_CODE (XEXP (XEXP (src_const, 0), 1)) == LABEL_REF))
	{
	  /* We only want a REG_EQUAL note if src_const != src.  */
	  if (! rtx_equal_p (src, src_const))
	    {
	      /* Make sure that the rtx is not shared.  */
	      src_const = copy_rtx (src_const);

	      /* Record the actual constant value in a REG_EQUAL note,
		 making a new one if one does not already exist.  */
	      set_unique_reg_note (insn, REG_EQUAL, src_const);
	    }
	}

      /* Now deal with the destination.  */
      do_not_record = 0;

      /* Look within any SIGN_EXTRACT or ZERO_EXTRACT
	 to the MEM or REG within it.  */
      while (GET_CODE (dest) == SIGN_EXTRACT
	     || GET_CODE (dest) == ZERO_EXTRACT
	     || GET_CODE (dest) == SUBREG
	     || GET_CODE (dest) == STRICT_LOW_PART)
	dest = XEXP (dest, 0);

      sets[i].inner_dest = dest;

      if (GET_CODE (dest) == MEM)
	{
#ifdef PUSH_ROUNDING
	  /* Stack pushes invalidate the stack pointer.  */
	  rtx addr = XEXP (dest, 0);
	  if (GET_RTX_CLASS (GET_CODE (addr)) == 'a'
	      && XEXP (addr, 0) == stack_pointer_rtx)
	    invalidate (stack_pointer_rtx, Pmode);
#endif
	  dest = fold_rtx (dest, insn);
	}

      /* Compute the hash code of the destination now,
	 before the effects of this instruction are recorded,
	 since the register values used in the address computation
	 are those before this instruction.  */
      sets[i].dest_hash = HASH (dest, mode);

      /* Don't enter a bit-field in the hash table
	 because the value in it after the store
	 may not equal what was stored, due to truncation.  */

      if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT
	  || GET_CODE (SET_DEST (sets[i].rtl)) == SIGN_EXTRACT)
	{
	  rtx width = XEXP (SET_DEST (sets[i].rtl), 1);

	  if (src_const != 0 && GET_CODE (src_const) == CONST_INT
	      && GET_CODE (width) == CONST_INT
	      && INTVAL (width) < HOST_BITS_PER_WIDE_INT
	      && ! (INTVAL (src_const)
		    & ((HOST_WIDE_INT) (-1) << INTVAL (width))))
	    /* Exception: if the value is constant,
	       and it won't be truncated, record it.  */
	    ;
	  else
	    {
	      /* This is chosen so that the destination will be invalidated
		 but no new value will be recorded.
		 We must invalidate because sometimes constant
		 values can be recorded for bitfields.  */
	      sets[i].src_elt = 0;
	      sets[i].src_volatile = 1;
	      src_eqv = 0;
	      src_eqv_elt = 0;
	    }
	}

      /* If only one set in a JUMP_INSN and it is now a no-op, we can delete
	 the insn.  */
      else if (n_sets == 1 && dest == pc_rtx && src == pc_rtx)
	{
	  /* One less use of the label this insn used to jump to.  */
	  delete_insn (insn);
	  cse_jumps_altered = 1;
	  /* No more processing for this set.  */
	  sets[i].rtl = 0;
	}

      /* If this SET is now setting PC to a label, we know it used to
	 be a conditional or computed branch.  */
      else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF)
	{
	  /* Now emit a BARRIER after the unconditional jump.  */
	  if (NEXT_INSN (insn) == 0
	      || GET_CODE (NEXT_INSN (insn)) != BARRIER)
	    emit_barrier_after (insn);

	  /* We reemit the jump in as many cases as possible just in
	     case the form of an unconditional jump is significantly
	     different than a computed jump or conditional jump.

	     If this insn has multiple sets, then reemitting the
	     jump is nontrivial.  So instead we just force rerecognition
	     and hope for the best.  */
	  if (n_sets == 1)
	    {
	      rtx new = emit_jump_insn_after (gen_jump (XEXP (src, 0)), insn);

	      JUMP_LABEL (new) = XEXP (src, 0);
	      LABEL_NUSES (XEXP (src, 0))++;
	      delete_insn (insn);
	      insn = new;

	      /* Now emit a BARRIER after the unconditional jump.  */
	      if (NEXT_INSN (insn) == 0
		  || GET_CODE (NEXT_INSN (insn)) != BARRIER)
		emit_barrier_after (insn);
	    }
	  else
	    INSN_CODE (insn) = -1;

	  never_reached_warning (insn, NULL);

	  /* Do not bother deleting any unreachable code,
	     let jump/flow do that.  */

	  cse_jumps_altered = 1;
	  sets[i].rtl = 0;
	}

      /* If destination is volatile, invalidate it and then do no further
	 processing for this assignment.  */

      else if (do_not_record)
	{
	  if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
	    invalidate (dest, VOIDmode);
	  else if (GET_CODE (dest) == MEM)
	    {
	      /* Outgoing arguments for a libcall don't
		 affect any recorded expressions.  */
	      if (! libcall_insn || insn == libcall_insn)
		invalidate (dest, VOIDmode);
	    }
	  else if (GET_CODE (dest) == STRICT_LOW_PART
		   || GET_CODE (dest) == ZERO_EXTRACT)
	    invalidate (XEXP (dest, 0), GET_MODE (dest));
	  sets[i].rtl = 0;
	}

      if (sets[i].rtl != 0 && dest != SET_DEST (sets[i].rtl))
	sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode);

#ifdef HAVE_cc0
      /* If setting CC0, record what it was set to, or a constant, if it
	 is equivalent to a constant.  If it is being set to a floating-point
	 value, make a COMPARE with the appropriate constant of 0.  If we
	 don't do this, later code can interpret this as a test against
	 const0_rtx, which can cause problems if we try to put it into an
	 insn as a floating-point operand.  */
      if (dest == cc0_rtx)
	{
	  this_insn_cc0 = src_const && mode != VOIDmode ? src_const : src;
	  this_insn_cc0_mode = mode;
	  if (FLOAT_MODE_P (mode))
	    this_insn_cc0 = gen_rtx_COMPARE (VOIDmode, this_insn_cc0,
					     CONST0_RTX (mode));
	}
#endif
    }

  /* Now enter all non-volatile source expressions in the hash table
     if they are not already present.
     Record their equivalence classes in src_elt.
     This way we can insert the corresponding destinations into
     the same classes even if the actual sources are no longer in them
     (having been invalidated).  */

  if (src_eqv && src_eqv_elt == 0 && sets[0].rtl != 0 && ! src_eqv_volatile
      && ! rtx_equal_p (src_eqv, SET_DEST (sets[0].rtl)))
    {
      struct table_elt *elt;
      struct table_elt *classp = sets[0].src_elt;
      rtx dest = SET_DEST (sets[0].rtl);
      enum machine_mode eqvmode = GET_MODE (dest);

      if (GET_CODE (dest) == STRICT_LOW_PART)
	{
	  eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
	  classp = 0;
	}
      if (insert_regs (src_eqv, classp, 0))
	{
	  rehash_using_reg (src_eqv);
	  src_eqv_hash = HASH (src_eqv, eqvmode);
	}
      elt = insert (src_eqv, classp, src_eqv_hash, eqvmode);
      elt->in_memory = src_eqv_in_memory;
      src_eqv_elt = elt;

      /* Check to see if src_eqv_elt is the same as a set source which
	 does not yet have an elt, and if so set the elt of the set source
	 to src_eqv_elt.  */
      for (i = 0; i < n_sets; i++)
	if (sets[i].rtl && sets[i].src_elt == 0
	    && rtx_equal_p (SET_SRC (sets[i].rtl), src_eqv))
	  sets[i].src_elt = src_eqv_elt;
    }

  for (i = 0; i < n_sets; i++)
    if (sets[i].rtl && ! sets[i].src_volatile
	&& ! rtx_equal_p (SET_SRC (sets[i].rtl), SET_DEST (sets[i].rtl)))
      {
	if (GET_CODE (SET_DEST (sets[i].rtl)) == STRICT_LOW_PART)
	  {
	    /* REG_EQUAL in setting a STRICT_LOW_PART
	       gives an equivalent for the entire destination register,
	       not just for the subreg being stored in now.
	       This is a more interesting equivalence, so we arrange later
	       to treat the entire reg as the destination.  */
	    sets[i].src_elt = src_eqv_elt;
	    sets[i].src_hash = src_eqv_hash;
	  }
	else
	  {
	    /* Insert source and constant equivalent into hash table, if not
	       already present.  */
	    struct table_elt *classp = src_eqv_elt;
	    rtx src = sets[i].src;
	    rtx dest = SET_DEST (sets[i].rtl);
	    enum machine_mode mode
	      = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src);

	    /* It's possible that we have a source value known to be
	       constant but don't have a REG_EQUAL note on the insn.
	       Lack of a note will mean src_eqv_elt will be NULL.  This
	       can happen where we've generated a SUBREG to access a
	       CONST_INT that is already in a register in a wider mode.
	       Ensure that the source expression is put in the proper
	       constant class.  */
	    if (!classp)
	      classp = sets[i].src_const_elt;

	    if (sets[i].src_elt == 0)
	      {
		/* Don't put a hard register source into the table if this is
		   the last insn of a libcall.  In this case, we only need
		   to put src_eqv_elt in src_elt.  */
		if (! find_reg_note (insn, REG_RETVAL, NULL_RTX))
		  {
		    struct table_elt *elt;

		    /* Note that these insert_regs calls cannot remove
		       any of the src_elt's, because they would have failed to
		       match if not still valid.  */
		    if (insert_regs (src, classp, 0))
		      {
			rehash_using_reg (src);
			sets[i].src_hash = HASH (src, mode);
		      }
		    elt = insert (src, classp, sets[i].src_hash, mode);
		    elt->in_memory = sets[i].src_in_memory;
		    sets[i].src_elt = classp = elt;
		  }
		else
		  sets[i].src_elt = classp;
	      }
	    if (sets[i].src_const && sets[i].src_const_elt == 0
		&& src != sets[i].src_const
		&& ! rtx_equal_p (sets[i].src_const, src))
	      sets[i].src_elt = insert (sets[i].src_const, classp,
					sets[i].src_const_hash, mode);
	  }
      }
    else if (sets[i].src_elt == 0)
      /* If we did not insert the source into the hash table (e.g., it was
	 volatile), note the equivalence class for the REG_EQUAL value, if any,
	 so that the destination goes into that class.  */
      sets[i].src_elt = src_eqv_elt;

  invalidate_from_clobbers (x);

  /* Some registers are invalidated by subroutine calls.  Memory is
     invalidated by non-constant calls.  */

  if (GET_CODE (insn) == CALL_INSN)
    {
      if (! CONST_OR_PURE_CALL_P (insn))
	invalidate_memory ();
      invalidate_for_call ();
    }

  /* Now invalidate everything set by this instruction.
     If a SUBREG or other funny destination is being set,
     sets[i].rtl is still nonzero, so here we invalidate the reg
     a part of which is being set.  */

  for (i = 0; i < n_sets; i++)
    if (sets[i].rtl)
      {
	/* We can't use the inner dest, because the mode associated with
	   a ZERO_EXTRACT is significant.  */
	rtx dest = SET_DEST (sets[i].rtl);

	/* Needed for registers to remove the register from its
	   previous quantity's chain.
	   Needed for memory if this is a nonvarying address, unless
	   we have just done an invalidate_memory that covers even those.  */
	if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
	  invalidate (dest, VOIDmode);
	else if (GET_CODE (dest) == MEM)
	  {
	    /* Outgoing arguments for a libcall don't
	       affect any recorded expressions.  */
	    if (! libcall_insn || insn == libcall_insn)
	      invalidate (dest, VOIDmode);
	  }
	else if (GET_CODE (dest) == STRICT_LOW_PART
		 || GET_CODE (dest) == ZERO_EXTRACT)
	  invalidate (XEXP (dest, 0), GET_MODE (dest));
      }

  /* A volatile ASM invalidates everything.  */
  if (GET_CODE (insn) == INSN
      && GET_CODE (PATTERN (insn)) == ASM_OPERANDS
      && MEM_VOLATILE_P (PATTERN (insn)))
    flush_hash_table ();

  /* Make sure registers mentioned in destinations
     are safe for use in an expression to be inserted.
     This removes from the hash table
     any invalid entry that refers to one of these registers.

     We don't care about the return value from mention_regs because
     we are going to hash the SET_DEST values unconditionally.  */

  for (i = 0; i < n_sets; i++)
    {
      if (sets[i].rtl)
	{
	  rtx x = SET_DEST (sets[i].rtl);

	  if (GET_CODE (x) != REG)
	    mention_regs (x);
	  else
	    {
	      /* We used to rely on all references to a register becoming
		 inaccessible when a register changes to a new quantity,
		 since that changes the hash code.  However, that is not
		 safe, since after HASH_SIZE new quantities we get a
		 hash 'collision' of a register with its own invalid
		 entries.  And since SUBREGs have been changed not to
		 change their hash code with the hash code of the register,
		 it wouldn't work any longer at all.  So we have to check
		 for any invalid references lying around now.
		 This code is similar to the REG case in mention_regs,
		 but it knows that reg_tick has been incremented, and
		 it leaves reg_in_table as -1 .  */
	      unsigned int regno = REGNO (x);
	      unsigned int endregno
		= regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
			   : HARD_REGNO_NREGS (regno, GET_MODE (x)));
	      unsigned int i;

	      for (i = regno; i < endregno; i++)
		{
		  if (REG_IN_TABLE (i) >= 0)
		    {
		      remove_invalid_refs (i);
		      REG_IN_TABLE (i) = -1;
		    }
		}
	    }
	}
    }

  /* We may have just removed some of the src_elt's from the hash table.
     So replace each one with the current head of the same class.  */

  for (i = 0; i < n_sets; i++)
    if (sets[i].rtl)
      {
	if (sets[i].src_elt && sets[i].src_elt->first_same_value == 0)
	  /* If elt was removed, find current head of same class,
	     or 0 if nothing remains of that class.  */
	  {
	    struct table_elt *elt = sets[i].src_elt;

	    while (elt && elt->prev_same_value)
	      elt = elt->prev_same_value;

	    while (elt && elt->first_same_value == 0)
	      elt = elt->next_same_value;
	    sets[i].src_elt = elt ? elt->first_same_value : 0;
	  }
      }

  /* Now insert the destinations into their equivalence classes.  */

  for (i = 0; i < n_sets; i++)
    if (sets[i].rtl)
      {
	rtx dest = SET_DEST (sets[i].rtl);
	rtx inner_dest = sets[i].inner_dest;
	struct table_elt *elt;

	/* Don't record value if we are not supposed to risk allocating
	   floating-point values in registers that might be wider than
	   memory.  */
	if ((flag_float_store
	     && GET_CODE (dest) == MEM
	     && FLOAT_MODE_P (GET_MODE (dest)))
	    /* Don't record BLKmode values, because we don't know the
	       size of it, and can't be sure that other BLKmode values
	       have the same or smaller size.  */
	    || GET_MODE (dest) == BLKmode
	    /* Don't record values of destinations set inside a libcall block
	       since we might delete the libcall.  Things should have been set
	       up so we won't want to reuse such a value, but we play it safe
	       here.  */
	    || libcall_insn
	    /* If we didn't put a REG_EQUAL value or a source into the hash
	       table, there is no point is recording DEST.  */
	    || sets[i].src_elt == 0
	    /* If DEST is a paradoxical SUBREG and SRC is a ZERO_EXTEND
	       or SIGN_EXTEND, don't record DEST since it can cause
	       some tracking to be wrong.

	       ??? Think about this more later.  */
	    || (GET_CODE (dest) == SUBREG
		&& (GET_MODE_SIZE (GET_MODE (dest))
		    > GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))))
		&& (GET_CODE (sets[i].src) == SIGN_EXTEND
		    || GET_CODE (sets[i].src) == ZERO_EXTEND)))
	  continue;

	/* STRICT_LOW_PART isn't part of the value BEING set,
	   and neither is the SUBREG inside it.
	   Note that in this case SETS[I].SRC_ELT is really SRC_EQV_ELT.  */
	if (GET_CODE (dest) == STRICT_LOW_PART)
	  dest = SUBREG_REG (XEXP (dest, 0));

	if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
	  /* Registers must also be inserted into chains for quantities.  */
	  if (insert_regs (dest, sets[i].src_elt, 1))
	    {
	      /* If `insert_regs' changes something, the hash code must be
		 recalculated.  */
	      rehash_using_reg (dest);
	      sets[i].dest_hash = HASH (dest, GET_MODE (dest));
	    }

	if (GET_CODE (inner_dest) == MEM
	    && GET_CODE (XEXP (inner_dest, 0)) == ADDRESSOF)
	  /* Given (SET (MEM (ADDRESSOF (X))) Y) we don't want to say
	     that (MEM (ADDRESSOF (X))) is equivalent to Y.
	     Consider the case in which the address of the MEM is
	     passed to a function, which alters the MEM.  Then, if we
	     later use Y instead of the MEM we'll miss the update.  */
	  elt = insert (dest, 0, sets[i].dest_hash, GET_MODE (dest));
	else
	  elt = insert (dest, sets[i].src_elt,
			sets[i].dest_hash, GET_MODE (dest));

	elt->in_memory = (GET_CODE (sets[i].inner_dest) == MEM
			  && (! RTX_UNCHANGING_P (sets[i].inner_dest)
			      || fixed_base_plus_p (XEXP (sets[i].inner_dest,
							  0))));

	/* If we have (set (subreg:m1 (reg:m2 foo) 0) (bar:m1)), M1 is no
	   narrower than M2, and both M1 and M2 are the same number of words,
	   we are also doing (set (reg:m2 foo) (subreg:m2 (bar:m1) 0)) so
	   make that equivalence as well.

	   However, BAR may have equivalences for which gen_lowpart_if_possible
	   will produce a simpler value than gen_lowpart_if_possible applied to
	   BAR (e.g., if BAR was ZERO_EXTENDed from M2), so we will scan all
	   BAR's equivalences.  If we don't get a simplified form, make
	   the SUBREG.  It will not be used in an equivalence, but will
	   cause two similar assignments to be detected.

	   Note the loop below will find SUBREG_REG (DEST) since we have
	   already entered SRC and DEST of the SET in the table.  */

	if (GET_CODE (dest) == SUBREG
	    && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) - 1)
		 / UNITS_PER_WORD)
		== (GET_MODE_SIZE (GET_MODE (dest)) - 1) / UNITS_PER_WORD)
	    && (GET_MODE_SIZE (GET_MODE (dest))
		>= GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))))
	    && sets[i].src_elt != 0)
	  {
	    enum machine_mode new_mode = GET_MODE (SUBREG_REG (dest));
	    struct table_elt *elt, *classp = 0;

	    for (elt = sets[i].src_elt->first_same_value; elt;
		 elt = elt->next_same_value)
	      {
		rtx new_src = 0;
		unsigned src_hash;
		struct table_elt *src_elt;
		int byte = 0;

		/* Ignore invalid entries.  */
		if (GET_CODE (elt->exp) != REG
		    && ! exp_equiv_p (elt->exp, elt->exp, 1, 0))
		  continue;

		/* We may have already been playing subreg games.  If the
		   mode is already correct for the destination, use it.  */
		if (GET_MODE (elt->exp) == new_mode)
		  new_src = elt->exp;
		else
		  {
		    /* Calculate big endian correction for the SUBREG_BYTE.
		       We have already checked that M1 (GET_MODE (dest))
		       is not narrower than M2 (new_mode).  */
		    if (BYTES_BIG_ENDIAN)
		      byte = (GET_MODE_SIZE (GET_MODE (dest))
			      - GET_MODE_SIZE (new_mode));

		    new_src = simplify_gen_subreg (new_mode, elt->exp,
					           GET_MODE (dest), byte);
		  }

		/* The call to simplify_gen_subreg fails if the value
		   is VOIDmode, yet we can't do any simplification, e.g.
		   for EXPR_LISTs denoting function call results.
		   It is invalid to construct a SUBREG with a VOIDmode
		   SUBREG_REG, hence a zero new_src means we can't do
		   this substitution.  */
		if (! new_src)
		  continue;

		src_hash = HASH (new_src, new_mode);
		src_elt = lookup (new_src, src_hash, new_mode);

		/* Put the new source in the hash table is if isn't
		   already.  */
		if (src_elt == 0)
		  {
		    if (insert_regs (new_src, classp, 0))
		      {
			rehash_using_reg (new_src);
			src_hash = HASH (new_src, new_mode);
		      }
		    src_elt = insert (new_src, classp, src_hash, new_mode);
		    src_elt->in_memory = elt->in_memory;
		  }
		else if (classp && classp != src_elt->first_same_value)
		  /* Show that two things that we've seen before are
		     actually the same.  */
		  merge_equiv_classes (src_elt, classp);

		classp = src_elt->first_same_value;
		/* Ignore invalid entries.  */
		while (classp
		       && GET_CODE (classp->exp) != REG
		       && ! exp_equiv_p (classp->exp, classp->exp, 1, 0))
		  classp = classp->next_same_value;
	      }
	  }
      }

  /* Special handling for (set REG0 REG1) where REG0 is the
     "cheapest", cheaper than REG1.  After cse, REG1 will probably not
     be used in the sequel, so (if easily done) change this insn to
     (set REG1 REG0) and replace REG1 with REG0 in the previous insn
     that computed their value.  Then REG1 will become a dead store
     and won't cloud the situation for later optimizations.

     Do not make this change if REG1 is a hard register, because it will
     then be used in the sequel and we may be changing a two-operand insn
     into a three-operand insn.

     Also do not do this if we are operating on a copy of INSN.

     Also don't do this if INSN ends a libcall; this would cause an unrelated
     register to be set in the middle of a libcall, and we then get bad code
     if the libcall is deleted.  */

  if (n_sets == 1 && sets[0].rtl && GET_CODE (SET_DEST (sets[0].rtl)) == REG
      && NEXT_INSN (PREV_INSN (insn)) == insn
      && GET_CODE (SET_SRC (sets[0].rtl)) == REG
      && REGNO (SET_SRC (sets[0].rtl)) >= FIRST_PSEUDO_REGISTER
      && REGNO_QTY_VALID_P (REGNO (SET_SRC (sets[0].rtl))))
    {
      int src_q = REG_QTY (REGNO (SET_SRC (sets[0].rtl)));
      struct qty_table_elem *src_ent = &qty_table[src_q];

      if ((src_ent->first_reg == REGNO (SET_DEST (sets[0].rtl)))
	  && ! find_reg_note (insn, REG_RETVAL, NULL_RTX))
	{
	  rtx prev = insn;
	  /* Scan for the previous nonnote insn, but stop at a basic
	     block boundary.  */
	  do
	    {
	      prev = PREV_INSN (prev);
	    }
	  while (prev && GET_CODE (prev) == NOTE
		 && NOTE_LINE_NUMBER (prev) != NOTE_INSN_BASIC_BLOCK);

	  /* Do not swap the registers around if the previous instruction
	     attaches a REG_EQUIV note to REG1.

	     ??? It's not entirely clear whether we can transfer a REG_EQUIV
	     from the pseudo that originally shadowed an incoming argument
	     to another register.  Some uses of REG_EQUIV might rely on it
	     being attached to REG1 rather than REG2.

	     This section previously turned the REG_EQUIV into a REG_EQUAL
	     note.  We cannot do that because REG_EQUIV may provide an
	     uninitialized stack slot when REG_PARM_STACK_SPACE is used.  */

	  if (prev != 0 && GET_CODE (prev) == INSN
	      && GET_CODE (PATTERN (prev)) == SET
	      && SET_DEST (PATTERN (prev)) == SET_SRC (sets[0].rtl)
	      && ! find_reg_note (prev, REG_EQUIV, NULL_RTX))
	    {
	      rtx dest = SET_DEST (sets[0].rtl);
	      rtx src = SET_SRC (sets[0].rtl);
	      rtx note;

	      validate_change (prev, &SET_DEST (PATTERN (prev)), dest, 1);
	      validate_change (insn, &SET_DEST (sets[0].rtl), src, 1);
	      validate_change (insn, &SET_SRC (sets[0].rtl), dest, 1);
	      apply_change_group ();

	      /* If INSN has a REG_EQUAL note, and this note mentions
		 REG0, then we must delete it, because the value in
		 REG0 has changed.  If the note's value is REG1, we must
		 also delete it because that is now this insn's dest.  */
	      note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
	      if (note != 0
		  && (reg_mentioned_p (dest, XEXP (note, 0))
		      || rtx_equal_p (src, XEXP (note, 0))))
		remove_note (insn, note);
	    }
	}
    }

  /* If this is a conditional jump insn, record any known equivalences due to
     the condition being tested.  */

  last_jump_equiv_class = 0;
  if (GET_CODE (insn) == JUMP_INSN
      && n_sets == 1 && GET_CODE (x) == SET
      && GET_CODE (SET_SRC (x)) == IF_THEN_ELSE)
    record_jump_equiv (insn, 0);

#ifdef HAVE_cc0
  /* If the previous insn set CC0 and this insn no longer references CC0,
     delete the previous insn.  Here we use the fact that nothing expects CC0
     to be valid over an insn, which is true until the final pass.  */
  if (prev_insn && GET_CODE (prev_insn) == INSN
      && (tem = single_set (prev_insn)) != 0
      && SET_DEST (tem) == cc0_rtx
      && ! reg_mentioned_p (cc0_rtx, x))
    delete_insn (prev_insn);

  prev_insn_cc0 = this_insn_cc0;
  prev_insn_cc0_mode = this_insn_cc0_mode;
  prev_insn = insn;
#endif
}

/* Remove from the hash table all expressions that reference memory.  */

static void
invalidate_memory (void)
{
  int i;
  struct table_elt *p, *next;

  for (i = 0; i < HASH_SIZE; i++)
    for (p = table[i]; p; p = next)
      {
	next = p->next_same_hash;
	if (p->in_memory)
	  remove_from_table (p, i);
      }
}

/* If ADDR is an address that implicitly affects the stack pointer, return
   1 and update the register tables to show the effect.  Else, return 0.  */

static int
addr_affects_sp_p (rtx addr)
{
  if (GET_RTX_CLASS (GET_CODE (addr)) == 'a'
      && GET_CODE (XEXP (addr, 0)) == REG
      && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
    {
      if (REG_TICK (STACK_POINTER_REGNUM) >= 0)
	{
	  REG_TICK (STACK_POINTER_REGNUM)++;
	  /* Is it possible to use a subreg of SP?  */
	  SUBREG_TICKED (STACK_POINTER_REGNUM) = -1;
	}

      /* This should be *very* rare.  */
      if (TEST_HARD_REG_BIT (hard_regs_in_table, STACK_POINTER_REGNUM))
	invalidate (stack_pointer_rtx, VOIDmode);

      return 1;
    }

  return 0;
}

/* Perform invalidation on the basis of everything about an insn
   except for invalidating the actual places that are SET in it.
   This includes the places CLOBBERed, and anything that might
   alias with something that is SET or CLOBBERed.

   X is the pattern of the insn.  */

static void
invalidate_from_clobbers (rtx x)
{
  if (GET_CODE (x) == CLOBBER)
    {
      rtx ref = XEXP (x, 0);
      if (ref)
	{
	  if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
	      || GET_CODE (ref) == MEM)
	    invalidate (ref, VOIDmode);
	  else if (GET_CODE (ref) == STRICT_LOW_PART
		   || GET_CODE (ref) == ZERO_EXTRACT)
	    invalidate (XEXP (ref, 0), GET_MODE (ref));
	}
    }
  else if (GET_CODE (x) == PARALLEL)
    {
      int i;
      for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
	{
	  rtx y = XVECEXP (x, 0, i);
	  if (GET_CODE (y) == CLOBBER)
	    {
	      rtx ref = XEXP (y, 0);
	      if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
		  || GET_CODE (ref) == MEM)
		invalidate (ref, VOIDmode);
	      else if (GET_CODE (ref) == STRICT_LOW_PART
		       || GET_CODE (ref) == ZERO_EXTRACT)
		invalidate (XEXP (ref, 0), GET_MODE (ref));
	    }
	}
    }
}

/* Process X, part of the REG_NOTES of an insn.  Look at any REG_EQUAL notes
   and replace any registers in them with either an equivalent constant
   or the canonical form of the register.  If we are inside an address,
   only do this if the address remains valid.

   OBJECT is 0 except when within a MEM in which case it is the MEM.

   Return the replacement for X.  */

static rtx
cse_process_notes (rtx x, rtx object)
{
  enum rtx_code code = GET_CODE (x);
  const char *fmt = GET_RTX_FORMAT (code);
  int i;

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

    case MEM:
      validate_change (x, &XEXP (x, 0),
		       cse_process_notes (XEXP (x, 0), x), 0);
      return x;

    case EXPR_LIST:
    case INSN_LIST:
      if (REG_NOTE_KIND (x) == REG_EQUAL)
	XEXP (x, 0) = cse_process_notes (XEXP (x, 0), NULL_RTX);
      if (XEXP (x, 1))
	XEXP (x, 1) = cse_process_notes (XEXP (x, 1), NULL_RTX);
      return x;

    case SIGN_EXTEND:
    case ZERO_EXTEND:
    case SUBREG:
      {
	rtx new = cse_process_notes (XEXP (x, 0), object);
	/* We don't substitute VOIDmode constants into these rtx,
	   since they would impede folding.  */
	if (GET_MODE (new) != VOIDmode)
	  validate_change (object, &XEXP (x, 0), new, 0);
	return x;
      }

    case REG:
      i = REG_QTY (REGNO (x));

      /* Return a constant or a constant register.  */
      if (REGNO_QTY_VALID_P (REGNO (x)))
	{
	  struct qty_table_elem *ent = &qty_table[i];

	  if (ent->const_rtx != NULL_RTX
	      && (CONSTANT_P (ent->const_rtx)
		  || GET_CODE (ent->const_rtx) == REG))
	    {
	      rtx new = gen_lowpart_if_possible (GET_MODE (x), ent->const_rtx);
	      if (new)
		return new;
	    }
	}

      /* Otherwise, canonicalize this register.  */
      return canon_reg (x, NULL_RTX);

    default:
      break;
    }

  for (i = 0; i < GET_RTX_LENGTH (code); i++)
    if (fmt[i] == 'e')
      validate_change (object, &XEXP (x, i),
		       cse_process_notes (XEXP (x, i), object), 0);

  return x;
}

/* Find common subexpressions between the end test of a loop and the beginning
   of the loop.  LOOP_START is the CODE_LABEL at the start of a loop.

   Often we have a loop where an expression in the exit test is used
   in the body of the loop.  For example "while (*p) *q++ = *p++;".
   Because of the way we duplicate the loop exit test in front of the loop,
   however, we don't detect that common subexpression.  This will be caught
   when global cse is implemented, but this is a quite common case.

   This function handles the most common cases of these common expressions.
   It is called after we have processed the basic block ending with the
   NOTE_INSN_LOOP_END note that ends a loop and the previous JUMP_INSN
   jumps to a label used only once.  */

static void
cse_around_loop (rtx loop_start)
{
  rtx insn;
  int i;
  struct table_elt *p;

  /* If the jump at the end of the loop doesn't go to the start, we don't
     do anything.  */
  for (insn = PREV_INSN (loop_start);
       insn && (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) >= 0);
       insn = PREV_INSN (insn))
    ;

  if (insn == 0
      || GET_CODE (insn) != NOTE
      || NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG)
    return;

  /* If the last insn of the loop (the end test) was an NE comparison,
     we will interpret it as an EQ comparison, since we fell through
     the loop.  Any equivalences resulting from that comparison are
     therefore not valid and must be invalidated.  */
  if (last_jump_equiv_class)
    for (p = last_jump_equiv_class->first_same_value; p;
	 p = p->next_same_value)
      {
	if (GET_CODE (p->exp) == MEM || GET_CODE (p->exp) == REG
	    || (GET_CODE (p->exp) == SUBREG
		&& GET_CODE (SUBREG_REG (p->exp)) == REG))
	  invalidate (p->exp, VOIDmode);
	else if (GET_CODE (p->exp) == STRICT_LOW_PART
		 || GET_CODE (p->exp) == ZERO_EXTRACT)
	  invalidate (XEXP (p->exp, 0), GET_MODE (p->exp));
      }

  /* Process insns starting after LOOP_START until we hit a CALL_INSN or
     a CODE_LABEL (we could handle a CALL_INSN, but it isn't worth it).

     The only thing we do with SET_DEST is invalidate entries, so we
     can safely process each SET in order.  It is slightly less efficient
     to do so, but we only want to handle the most common cases.

     The gen_move_insn call in cse_set_around_loop may create new pseudos.
     These pseudos won't have valid entries in any of the tables indexed
     by register number, such as reg_qty.  We avoid out-of-range array
     accesses by not processing any instructions created after cse started.  */

  for (insn = NEXT_INSN (loop_start);
       GET_CODE (insn) != CALL_INSN && GET_CODE (insn) != CODE_LABEL
       && INSN_UID (insn) < max_insn_uid
       && ! (GET_CODE (insn) == NOTE
	     && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END);
       insn = NEXT_INSN (insn))
    {
      if (INSN_P (insn)
	  && (GET_CODE (PATTERN (insn)) == SET
	      || GET_CODE (PATTERN (insn)) == CLOBBER))
	cse_set_around_loop (PATTERN (insn), insn, loop_start);
      else if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == PARALLEL)
	for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
	  if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
	      || GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == CLOBBER)
	    cse_set_around_loop (XVECEXP (PATTERN (insn), 0, i), insn,
				 loop_start);
    }
}

/* Process one SET of an insn that was skipped.  We ignore CLOBBERs
   since they are done elsewhere.  This function is called via note_stores.  */

static void
invalidate_skipped_set (rtx dest, rtx set, void *data ATTRIBUTE_UNUSED)
{
  enum rtx_code code = GET_CODE (dest);

  if (code == MEM
      && ! addr_affects_sp_p (dest)	/* If this is not a stack push ...  */
      /* There are times when an address can appear varying and be a PLUS
	 during this scan when it would be a fixed address were we to know
	 the proper equivalences.  So invalidate all memory if there is
	 a BLKmode or nonscalar memory reference or a reference to a
	 variable address.  */
      && (MEM_IN_STRUCT_P (dest) || GET_MODE (dest) == BLKmode
	  || cse_rtx_varies_p (XEXP (dest, 0), 0)))
    {
      invalidate_memory ();
      return;
    }

  if (GET_CODE (set) == CLOBBER
      || CC0_P (dest)
      || dest == pc_rtx)
    return;

  if (code == STRICT_LOW_PART || code == ZERO_EXTRACT)
    invalidate (XEXP (dest, 0), GET_MODE (dest));
  else if (code == REG || code == SUBREG || code == MEM)
    invalidate (dest, VOIDmode);
}

/* Invalidate all insns from START up to the end of the function or the
   next label.  This called when we wish to CSE around a block that is
   conditionally executed.  */

static void
invalidate_skipped_block (rtx start)
{
  rtx insn;

  for (insn = start; insn && GET_CODE (insn) != CODE_LABEL;
       insn = NEXT_INSN (insn))
    {
      if (! INSN_P (insn))
	continue;

      if (GET_CODE (insn) == CALL_INSN)
	{
	  if (! CONST_OR_PURE_CALL_P (insn))
	    invalidate_memory ();
	  invalidate_for_call ();
	}

      invalidate_from_clobbers (PATTERN (insn));
      note_stores (PATTERN (insn), invalidate_skipped_set, NULL);
    }
}

/* If modifying X will modify the value in *DATA (which is really an
   `rtx *'), indicate that fact by setting the pointed to value to
   NULL_RTX.  */

static void
cse_check_loop_start (rtx x, rtx set ATTRIBUTE_UNUSED, void *data)
{
  rtx *cse_check_loop_start_value = (rtx *) data;

  if (*cse_check_loop_start_value == NULL_RTX
      || GET_CODE (x) == CC0 || GET_CODE (x) == PC)
    return;

  if ((GET_CODE (x) == MEM && GET_CODE (*cse_check_loop_start_value) == MEM)
      || reg_overlap_mentioned_p (x, *cse_check_loop_start_value))
    *cse_check_loop_start_value = NULL_RTX;
}

/* X is a SET or CLOBBER contained in INSN that was found near the start of
   a loop that starts with the label at LOOP_START.

   If X is a SET, we see if its SET_SRC is currently in our hash table.
   If so, we see if it has a value equal to some register used only in the
   loop exit code (as marked by jump.c).

   If those two conditions are true, we search backwards from the start of
   the loop to see if that same value was loaded into a register that still
   retains its value at the start of the loop.

   If so, we insert an insn after the load to copy the destination of that
   load into the equivalent register and (try to) replace our SET_SRC with that
   register.

   In any event, we invalidate whatever this SET or CLOBBER modifies.  */

static void
cse_set_around_loop (rtx x, rtx insn, rtx loop_start)
{
  struct table_elt *src_elt;

  /* If this is a SET, see if we can replace SET_SRC, but ignore SETs that
     are setting PC or CC0 or whose SET_SRC is already a register.  */
  if (GET_CODE (x) == SET
      && GET_CODE (SET_DEST (x)) != PC && GET_CODE (SET_DEST (x)) != CC0
      && GET_CODE (SET_SRC (x)) != REG)
    {
      src_elt = lookup (SET_SRC (x),
			HASH (SET_SRC (x), GET_MODE (SET_DEST (x))),
			GET_MODE (SET_DEST (x)));

      if (src_elt)
	for (src_elt = src_elt->first_same_value; src_elt;
	     src_elt = src_elt->next_same_value)
	  if (GET_CODE (src_elt->exp) == REG && REG_LOOP_TEST_P (src_elt->exp)
	      && COST (src_elt->exp) < COST (SET_SRC (x)))
	    {
	      rtx p, set;

	      /* Look for an insn in front of LOOP_START that sets
		 something in the desired mode to SET_SRC (x) before we hit
		 a label or CALL_INSN.  */

	      for (p = prev_nonnote_insn (loop_start);
		   p && GET_CODE (p) != CALL_INSN
		   && GET_CODE (p) != CODE_LABEL;
		   p = prev_nonnote_insn  (p))
		if ((set = single_set (p)) != 0
		    && GET_CODE (SET_DEST (set)) == REG
		    && GET_MODE (SET_DEST (set)) == src_elt->mode
		    && rtx_equal_p (SET_SRC (set), SET_SRC (x)))
		  {
		    /* We now have to ensure that nothing between P
		       and LOOP_START modified anything referenced in
		       SET_SRC (x).  We know that nothing within the loop
		       can modify it, or we would have invalidated it in
		       the hash table.  */
		    rtx q;
		    rtx cse_check_loop_start_value = SET_SRC (x);
		    for (q = p; q != loop_start; q = NEXT_INSN (q))
		      if (INSN_P (q))
			note_stores (PATTERN (q),
				     cse_check_loop_start,
				     &cse_check_loop_start_value);

		    /* If nothing was changed and we can replace our
		       SET_SRC, add an insn after P to copy its destination
		       to what we will be replacing SET_SRC with.  */
		    if (cse_check_loop_start_value
			&& single_set (p)
			&& !can_throw_internal (insn)
			&& validate_change (insn, &SET_SRC (x),
					    src_elt->exp, 0))
		      {
			/* If this creates new pseudos, this is unsafe,
			   because the regno of new pseudo is unsuitable
			   to index into reg_qty when cse_insn processes
			   the new insn.  Therefore, if a new pseudo was
			   created, discard this optimization.  */
			int nregs = max_reg_num ();
			rtx move
			  = gen_move_insn (src_elt->exp, SET_DEST (set));
			if (nregs != max_reg_num ())
			  {
			    if (! validate_change (insn, &SET_SRC (x),
						   SET_SRC (set), 0))
			      abort ();
			  }
			else
			  {
			    if (CONSTANT_P (SET_SRC (set))
				&& ! find_reg_equal_equiv_note (insn))
			      set_unique_reg_note (insn, REG_EQUAL,
						   SET_SRC (set));
			    if (control_flow_insn_p (p))
			      /* p can cause a control flow transfer so it
				 is the last insn of a basic block.  We can't
				 therefore use emit_insn_after.  */
			      emit_insn_before (move, next_nonnote_insn (p));
			    else
			      emit_insn_after (move, p);
			  }
		      }
		    break;
		  }
	    }
    }

  /* Deal with the destination of X affecting the stack pointer.  */
  addr_affects_sp_p (SET_DEST (x));

  /* See comment on similar code in cse_insn for explanation of these
     tests.  */
  if (GET_CODE (SET_DEST (x)) == REG || GET_CODE (SET_DEST (x)) == SUBREG
      || GET_CODE (SET_DEST (x)) == MEM)
    invalidate (SET_DEST (x), VOIDmode);
  else if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART
	   || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
    invalidate (XEXP (SET_DEST (x), 0), GET_MODE (SET_DEST (x)));
}

/* Find the end of INSN's basic block and return its range,
   the total number of SETs in all the insns of the block, the last insn of the
   block, and the branch path.

   The branch path indicates which branches should be followed.  If a nonzero
   path size is specified, the block should be rescanned and a different set
   of branches will be taken.  The branch path is only used if
   FLAG_CSE_FOLLOW_JUMPS or FLAG_CSE_SKIP_BLOCKS is nonzero.

   DATA is a pointer to a struct cse_basic_block_data, defined below, that is
   used to describe the block.  It is filled in with the information about
   the current block.  The incoming structure's branch path, if any, is used
   to construct the output branch path.  */

void
cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
			int follow_jumps, int after_loop, int skip_blocks)
{
  rtx p = insn, q;
  int nsets = 0;
  int low_cuid = INSN_CUID (insn), high_cuid = INSN_CUID (insn);
  rtx next = INSN_P (insn) ? insn : next_real_insn (insn);
  int path_size = data->path_size;
  int path_entry = 0;
  int i;

  /* Update the previous branch path, if any.  If the last branch was
     previously TAKEN, mark it NOT_TAKEN.  If it was previously NOT_TAKEN,
     shorten the path by one and look at the previous branch.  We know that
     at least one branch must have been taken if PATH_SIZE is nonzero.  */
  while (path_size > 0)
    {
      if (data->path[path_size - 1].status != NOT_TAKEN)
	{
	  data->path[path_size - 1].status = NOT_TAKEN;
	  break;
	}
      else
	path_size--;
    }

  /* If the first instruction is marked with QImode, that means we've
     already processed this block.  Our caller will look at DATA->LAST
     to figure out where to go next.  We want to return the next block
     in the instruction stream, not some branched-to block somewhere
     else.  We accomplish this by pretending our called forbid us to
     follow jumps, or skip blocks.  */
  if (GET_MODE (insn) == QImode)
    follow_jumps = skip_blocks = 0;

  /* Scan to end of this basic block.  */
  while (p && GET_CODE (p) != CODE_LABEL)
    {
      /* Don't cse out the end of a loop.  This makes a difference
	 only for the unusual loops that always execute at least once;
	 all other loops have labels there so we will stop in any case.
	 Cse'ing out the end of the loop is dangerous because it
	 might cause an invariant expression inside the loop
	 to be reused after the end of the loop.  This would make it
	 hard to move the expression out of the loop in loop.c,
	 especially if it is one of several equivalent expressions
	 and loop.c would like to eliminate it.

	 If we are running after loop.c has finished, we can ignore
	 the NOTE_INSN_LOOP_END.  */

      if (! after_loop && GET_CODE (p) == NOTE
	  && NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)
	break;

      /* Don't cse over a call to setjmp; on some machines (eg VAX)
	 the regs restored by the longjmp come from
	 a later time than the setjmp.  */
      if (PREV_INSN (p) && GET_CODE (PREV_INSN (p)) == CALL_INSN
	  && find_reg_note (PREV_INSN (p), REG_SETJMP, NULL))
	break;

      /* A PARALLEL can have lots of SETs in it,
	 especially if it is really an ASM_OPERANDS.  */
      if (INSN_P (p) && GET_CODE (PATTERN (p)) == PARALLEL)
	nsets += XVECLEN (PATTERN (p), 0);
      else if (GET_CODE (p) != NOTE)
	nsets += 1;

      /* Ignore insns made by CSE; they cannot affect the boundaries of
	 the basic block.  */

      if (INSN_UID (p) <= max_uid && INSN_CUID (p) > high_cuid)
	high_cuid = INSN_CUID (p);
      if (INSN_UID (p) <= max_uid && INSN_CUID (p) < low_cuid)
	low_cuid = INSN_CUID (p);

      /* See if this insn is in our branch path.  If it is and we are to
	 take it, do so.  */
      if (path_entry < path_size && data->path[path_entry].branch == p)
	{
	  if (data->path[path_entry].status != NOT_TAKEN)
	    p = JUMP_LABEL (p);

	  /* Point to next entry in path, if any.  */
	  path_entry++;
	}

      /* If this is a conditional jump, we can follow it if -fcse-follow-jumps
	 was specified, we haven't reached our maximum path length, there are
	 insns following the target of the jump, this is the only use of the
	 jump label, and the target label is preceded by a BARRIER.

	 Alternatively, we can follow the jump if it branches around a
	 block of code and there are no other branches into the block.
	 In this case invalidate_skipped_block will be called to invalidate any
	 registers set in the block when following the jump.  */

      else if ((follow_jumps || skip_blocks) && path_size < PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH) - 1
	       && GET_CODE (p) == JUMP_INSN
	       && GET_CODE (PATTERN (p)) == SET
	       && GET_CODE (SET_SRC (PATTERN (p))) == IF_THEN_ELSE
	       && JUMP_LABEL (p) != 0
	       && LABEL_NUSES (JUMP_LABEL (p)) == 1
	       && NEXT_INSN (JUMP_LABEL (p)) != 0)
	{
	  for (q = PREV_INSN (JUMP_LABEL (p)); q; q = PREV_INSN (q))
	    if ((GET_CODE (q) != NOTE
		 || NOTE_LINE_NUMBER (q) == NOTE_INSN_LOOP_END
		 || (PREV_INSN (q) && GET_CODE (PREV_INSN (q)) == CALL_INSN
		     && find_reg_note (PREV_INSN (q), REG_SETJMP, NULL)))
		&& (GET_CODE (q) != CODE_LABEL || LABEL_NUSES (q) != 0))
	      break;

	  /* If we ran into a BARRIER, this code is an extension of the
	     basic block when the branch is taken.  */
	  if (follow_jumps && q != 0 && GET_CODE (q) == BARRIER)
	    {
	      /* Don't allow ourself to keep walking around an
		 always-executed loop.  */
	      if (next_real_insn (q) == next)
		{
		  p = NEXT_INSN (p);
		  continue;
		}

	      /* Similarly, don't put a branch in our path more than once.  */
	      for (i = 0; i < path_entry; i++)
		if (data->path[i].branch == p)
		  break;

	      if (i != path_entry)
		break;

	      data->path[path_entry].branch = p;
	      data->path[path_entry++].status = TAKEN;

	      /* This branch now ends our path.  It was possible that we
		 didn't see this branch the last time around (when the
		 insn in front of the target was a JUMP_INSN that was
		 turned into a no-op).  */
	      path_size = path_entry;

	      p = JUMP_LABEL (p);
	      /* Mark block so we won't scan it again later.  */
	      PUT_MODE (NEXT_INSN (p), QImode);
	    }
	  /* Detect a branch around a block of code.  */
	  else if (skip_blocks && q != 0 && GET_CODE (q) != CODE_LABEL)
	    {
	      rtx tmp;

	      if (next_real_insn (q) == next)
		{
		  p = NEXT_INSN (p);
		  continue;
		}

	      for (i = 0; i < path_entry; i++)
		if (data->path[i].branch == p)
		  break;

	      if (i != path_entry)
		break;

	      /* This is no_labels_between_p (p, q) with an added check for
		 reaching the end of a function (in case Q precedes P).  */
	      for (tmp = NEXT_INSN (p); tmp && tmp != q; tmp = NEXT_INSN (tmp))
		if (GET_CODE (tmp) == CODE_LABEL)
		  break;

	      if (tmp == q)
		{
		  data->path[path_entry].branch = p;
		  data->path[path_entry++].status = AROUND;

		  path_size = path_entry;

		  p = JUMP_LABEL (p);
		  /* Mark block so we won't scan it again later.  */
		  PUT_MODE (NEXT_INSN (p), QImode);
		}
	    }
	}
      p = NEXT_INSN (p);
    }

  data->low_cuid = low_cuid;
  data->high_cuid = high_cuid;
  data->nsets = nsets;
  data->last = p;

  /* If all jumps in the path are not taken, set our path length to zero
     so a rescan won't be done.  */
  for (i = path_size - 1; i >= 0; i--)
    if (data->path[i].status != NOT_TAKEN)
      break;

  if (i == -1)
    data->path_size = 0;
  else
    data->path_size = path_size;

  /* End the current branch path.  */
  data->path[path_size].branch = 0;
}

/* Perform cse on the instructions of a function.
   F is the first instruction.
   NREGS is one plus the highest pseudo-reg number used in the instruction.

   AFTER_LOOP is 1 if this is the cse call done after loop optimization
   (only if -frerun-cse-after-loop).

   Returns 1 if jump_optimize should be redone due to simplifications
   in conditional jump instructions.  */

int
cse_main (rtx f, int nregs, int after_loop, FILE *file)
{
  struct cse_basic_block_data val;
  rtx insn = f;
  int i;

  val.path = xmalloc (sizeof (struct branch_path)
		      * PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH));

  cse_jumps_altered = 0;
  recorded_label_ref = 0;
  constant_pool_entries_cost = 0;
  constant_pool_entries_regcost = 0;
  val.path_size = 0;

  init_recog ();
  init_alias_analysis ();

  max_reg = nregs;

  max_insn_uid = get_max_uid ();

  reg_eqv_table = xmalloc (nregs * sizeof (struct reg_eqv_elem));

#ifdef LOAD_EXTEND_OP

  /* Allocate scratch rtl here.  cse_insn will fill in the memory reference
     and change the code and mode as appropriate.  */
  memory_extend_rtx = gen_rtx_ZERO_EXTEND (VOIDmode, NULL_RTX);
#endif

  /* Reset the counter indicating how many elements have been made
     thus far.  */
  n_elements_made = 0;

  /* Find the largest uid.  */

  max_uid = get_max_uid ();
  uid_cuid = xcalloc (max_uid + 1, sizeof (int));

  /* Compute the mapping from uids to cuids.
     CUIDs are numbers assigned to insns, like uids,
     except that cuids increase monotonically through the code.
     Don't assign cuids to line-number NOTEs, so that the distance in cuids
     between two insns is not affected by -g.  */

  for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
    {
      if (GET_CODE (insn) != NOTE
	  || NOTE_LINE_NUMBER (insn) < 0)
	INSN_CUID (insn) = ++i;
      else
	/* Give a line number note the same cuid as preceding insn.  */
	INSN_CUID (insn) = i;
    }

  ggc_push_context ();

  /* Loop over basic blocks.
     Compute the maximum number of qty's needed for each basic block
     (which is 2 for each SET).  */
  insn = f;
  while (insn)
    {
      cse_altered = 0;
      cse_end_of_basic_block (insn, &val, flag_cse_follow_jumps, after_loop,
			      flag_cse_skip_blocks);

      /* If this basic block was already processed or has no sets, skip it.  */
      if (val.nsets == 0 || GET_MODE (insn) == QImode)
	{
	  PUT_MODE (insn, VOIDmode);
	  insn = (val.last ? NEXT_INSN (val.last) : 0);
	  val.path_size = 0;
	  continue;
	}

      cse_basic_block_start = val.low_cuid;
      cse_basic_block_end = val.high_cuid;
      max_qty = val.nsets * 2;

      if (file)
	fnotice (file, ";; Processing block from %d to %d, %d sets.\n",
		 INSN_UID (insn), val.last ? INSN_UID (val.last) : 0,
		 val.nsets);

      /* Make MAX_QTY bigger to give us room to optimize
	 past the end of this basic block, if that should prove useful.  */
      if (max_qty < 500)
	max_qty = 500;

      /* If this basic block is being extended by following certain jumps,
         (see `cse_end_of_basic_block'), we reprocess the code from the start.
         Otherwise, we start after this basic block.  */
      if (val.path_size > 0)
	cse_basic_block (insn, val.last, val.path, 0);
      else
	{
	  int old_cse_jumps_altered = cse_jumps_altered;
	  rtx temp;

	  /* When cse changes a conditional jump to an unconditional
	     jump, we want to reprocess the block, since it will give
	     us a new branch path to investigate.  */
	  cse_jumps_altered = 0;
	  temp = cse_basic_block (insn, val.last, val.path, ! after_loop);
	  if (cse_jumps_altered == 0
	      || (flag_cse_follow_jumps == 0 && flag_cse_skip_blocks == 0))
	    insn = temp;

	  cse_jumps_altered |= old_cse_jumps_altered;
	}

      if (cse_altered)
	ggc_collect ();

#ifdef USE_C_ALLOCA
      alloca (0);
#endif
    }

  ggc_pop_context ();

  if (max_elements_made < n_elements_made)
    max_elements_made = n_elements_made;

  /* Clean up.  */
  end_alias_analysis ();
  free (uid_cuid);
  free (reg_eqv_table);
  free (val.path);

  return cse_jumps_altered || recorded_label_ref;
}

/* Process a single basic block.  FROM and TO and the limits of the basic
   block.  NEXT_BRANCH points to the branch path when following jumps or
   a null path when not following jumps.

   AROUND_LOOP is nonzero if we are to try to cse around to the start of a
   loop.  This is true when we are being called for the last time on a
   block and this CSE pass is before loop.c.  */

static rtx
cse_basic_block (rtx from, rtx to, struct branch_path *next_branch,
		 int around_loop)
{
  rtx insn;
  int to_usage = 0;
  rtx libcall_insn = NULL_RTX;
  int num_insns = 0;
  int no_conflict = 0;

  /* Allocate the space needed by qty_table.  */
  qty_table = xmalloc (max_qty * sizeof (struct qty_table_elem));

  new_basic_block ();

  /* TO might be a label.  If so, protect it from being deleted.  */
  if (to != 0 && GET_CODE (to) == CODE_LABEL)
    ++LABEL_NUSES (to);

  for (insn = from; insn != to; insn = NEXT_INSN (insn))
    {
      enum rtx_code code = GET_CODE (insn);

      /* If we have processed 1,000 insns, flush the hash table to
	 avoid extreme quadratic behavior.  We must not include NOTEs
	 in the count since there may be more of them when generating
	 debugging information.  If we clear the table at different
	 times, code generated with -g -O might be different than code
	 generated with -O but not -g.

	 ??? This is a real kludge and needs to be done some other way.
	 Perhaps for 2.9.  */
      if (code != NOTE && num_insns++ > 1000)
	{
	  flush_hash_table ();
	  num_insns = 0;
	}

      /* See if this is a branch that is part of the path.  If so, and it is
	 to be taken, do so.  */
      if (next_branch->branch == insn)
	{
	  enum taken status = next_branch++->status;
	  if (status != NOT_TAKEN)
	    {
	      if (status == TAKEN)
		record_jump_equiv (insn, 1);
	      else
		invalidate_skipped_block (NEXT_INSN (insn));

	      /* Set the last insn as the jump insn; it doesn't affect cc0.
		 Then follow this branch.  */
#ifdef HAVE_cc0
	      prev_insn_cc0 = 0;
	      prev_insn = insn;
#endif
	      insn = JUMP_LABEL (insn);
	      continue;
	    }
	}

      if (GET_MODE (insn) == QImode)
	PUT_MODE (insn, VOIDmode);

      if (GET_RTX_CLASS (code) == 'i')
	{
	  rtx p;

	  /* Process notes first so we have all notes in canonical forms when
	     looking for duplicate operations.  */

	  if (REG_NOTES (insn))
	    REG_NOTES (insn) = cse_process_notes (REG_NOTES (insn), NULL_RTX);

	  /* Track when we are inside in LIBCALL block.  Inside such a block,
	     we do not want to record destinations.  The last insn of a
	     LIBCALL block is not considered to be part of the block, since
	     its destination is the result of the block and hence should be
	     recorded.  */

	  if (REG_NOTES (insn) != 0)
	    {
	      if ((p = find_reg_note (insn, REG_LIBCALL, NULL_RTX)))
		libcall_insn = XEXP (p, 0);
	      else if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
		{
		  /* Keep libcall_insn for the last SET insn of a no-conflict
		     block to prevent changing the destination.  */
		  if (! no_conflict)
		    libcall_insn = 0;
		  else
		    no_conflict = -1;
		}
	      else if (find_reg_note (insn, REG_NO_CONFLICT, NULL_RTX))
		no_conflict = 1;
	    }

	  cse_insn (insn, libcall_insn);

	  if (no_conflict == -1)
	    {
	      libcall_insn = 0;
	      no_conflict = 0;
	    }
	    
	  /* If we haven't already found an insn where we added a LABEL_REF,
	     check this one.  */
	  if (GET_CODE (insn) == INSN && ! recorded_label_ref
	      && for_each_rtx (&PATTERN (insn), check_for_label_ref,
			       (void *) insn))
	    recorded_label_ref = 1;
	}

      /* If INSN is now an unconditional jump, skip to the end of our
	 basic block by pretending that we just did the last insn in the
	 basic block.  If we are jumping to the end of our block, show
	 that we can have one usage of TO.  */

      if (any_uncondjump_p (insn))
	{
	  if (to == 0)
	    {
	      free (qty_table);
	      return 0;
	    }

	  if (JUMP_LABEL (insn) == to)
	    to_usage = 1;

	  /* Maybe TO was deleted because the jump is unconditional.
	     If so, there is nothing left in this basic block.  */
	  /* ??? Perhaps it would be smarter to set TO
	     to whatever follows this insn,
	     and pretend the basic block had always ended here.  */
	  if (INSN_DELETED_P (to))
	    break;

	  insn = PREV_INSN (to);
	}

      /* See if it is ok to keep on going past the label
	 which used to end our basic block.  Remember that we incremented
	 the count of that label, so we decrement it here.  If we made
	 a jump unconditional, TO_USAGE will be one; in that case, we don't
	 want to count the use in that jump.  */

      if (to != 0 && NEXT_INSN (insn) == to
	  && GET_CODE (to) == CODE_LABEL && --LABEL_NUSES (to) == to_usage)
	{
	  struct cse_basic_block_data val;
	  rtx prev;

	  insn = NEXT_INSN (to);

	  /* If TO was the last insn in the function, we are done.  */
	  if (insn == 0)
	    {
	      free (qty_table);
	      return 0;
	    }

	  /* If TO was preceded by a BARRIER we are done with this block
	     because it has no continuation.  */
	  prev = prev_nonnote_insn (to);
	  if (prev && GET_CODE (prev) == BARRIER)
	    {
	      free (qty_table);
	      return insn;
	    }

	  /* Find the end of the following block.  Note that we won't be
	     following branches in this case.  */
	  to_usage = 0;
	  val.path_size = 0;
	  val.path = xmalloc (sizeof (struct branch_path)
			      * PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH));
	  cse_end_of_basic_block (insn, &val, 0, 0, 0);
	  free (val.path);

	  /* If the tables we allocated have enough space left
	     to handle all the SETs in the next basic block,
	     continue through it.  Otherwise, return,
	     and that block will be scanned individually.  */
	  if (val.nsets * 2 + next_qty > max_qty)
	    break;

	  cse_basic_block_start = val.low_cuid;
	  cse_basic_block_end = val.high_cuid;
	  to = val.last;

	  /* Prevent TO from being deleted if it is a label.  */
	  if (to != 0 && GET_CODE (to) == CODE_LABEL)
	    ++LABEL_NUSES (to);

	  /* Back up so we process the first insn in the extension.  */
	  insn = PREV_INSN (insn);
	}
    }

  if (next_qty > max_qty)
    abort ();

  /* If we are running before loop.c, we stopped on a NOTE_INSN_LOOP_END, and
     the previous insn is the only insn that branches to the head of a loop,
     we can cse into the loop.  Don't do this if we changed the jump
     structure of a loop unless we aren't going to be following jumps.  */

  insn = prev_nonnote_insn (to);
  if ((cse_jumps_altered == 0
       || (flag_cse_follow_jumps == 0 && flag_cse_skip_blocks == 0))
      && around_loop && to != 0
      && GET_CODE (to) == NOTE && NOTE_LINE_NUMBER (to) == NOTE_INSN_LOOP_END
      && GET_CODE (insn) == JUMP_INSN
      && JUMP_LABEL (insn) != 0
      && LABEL_NUSES (JUMP_LABEL (insn)) == 1)
    cse_around_loop (JUMP_LABEL (insn));

  free (qty_table);

  return to ? NEXT_INSN (to) : 0;
}

/* Called via for_each_rtx to see if an insn is using a LABEL_REF for which
   there isn't a REG_LABEL note.  Return one if so.  DATA is the insn.  */

static int
check_for_label_ref (rtx *rtl, void *data)
{
  rtx insn = (rtx) data;

  /* If this insn uses a LABEL_REF and there isn't a REG_LABEL note for it,
     we must rerun jump since it needs to place the note.  If this is a
     LABEL_REF for a CODE_LABEL that isn't in the insn chain, don't do this
     since no REG_LABEL will be added.  */
  return (GET_CODE (*rtl) == LABEL_REF
	  && ! LABEL_REF_NONLOCAL_P (*rtl)
	  && LABEL_P (XEXP (*rtl, 0))
	  && INSN_UID (XEXP (*rtl, 0)) != 0
	  && ! find_reg_note (insn, REG_LABEL, XEXP (*rtl, 0)));
}

/* Count the number of times registers are used (not set) in X.
   COUNTS is an array in which we accumulate the count, INCR is how much
   we count each register usage.  */

static void
count_reg_usage (rtx x, int *counts, int incr)
{
  enum rtx_code code;
  rtx note;
  const char *fmt;
  int i, j;

  if (x == 0)
    return;

  switch (code = GET_CODE (x))
    {
    case REG:
      counts[REGNO (x)] += incr;
      return;

    case PC:
    case CC0:
    case CONST:
    case CONST_INT:
    case CONST_DOUBLE:
    case CONST_VECTOR:
    case SYMBOL_REF:
    case LABEL_REF:
      return;

    case CLOBBER:
      /* If we are clobbering a MEM, mark any registers inside the address
         as being used.  */
      if (GET_CODE (XEXP (x, 0)) == MEM)
	count_reg_usage (XEXP (XEXP (x, 0), 0), counts, incr);
      return;

    case SET:
      /* Unless we are setting a REG, count everything in SET_DEST.  */
      if (GET_CODE (SET_DEST (x)) != REG)
	count_reg_usage (SET_DEST (x), counts, incr);
      count_reg_usage (SET_SRC (x), counts, incr);
      return;

    case CALL_INSN:
      count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, incr);
      /* Fall through.  */

    case INSN:
    case JUMP_INSN:
      count_reg_usage (PATTERN (x), counts, incr);

      /* Things used in a REG_EQUAL note aren't dead since loop may try to
	 use them.  */

      note = find_reg_equal_equiv_note (x);
      if (note)
	{
	  rtx eqv = XEXP (note, 0);

	  if (GET_CODE (eqv) == EXPR_LIST)
	  /* This REG_EQUAL note describes the result of a function call.
	     Process all the arguments.  */
	    do
	      {
		count_reg_usage (XEXP (eqv, 0), counts, incr);
		eqv = XEXP (eqv, 1);
	      }
	    while (eqv && GET_CODE (eqv) == EXPR_LIST);
	  else
	    count_reg_usage (eqv, counts, incr);
	}
      return;

    case EXPR_LIST:
      if (REG_NOTE_KIND (x) == REG_EQUAL
	  || (REG_NOTE_KIND (x) != REG_NONNEG && GET_CODE (XEXP (x,0)) == USE)
	  /* FUNCTION_USAGE expression lists may include (CLOBBER (mem /u)),
	     involving registers in the address.  */
	  || GET_CODE (XEXP (x, 0)) == CLOBBER)
	count_reg_usage (XEXP (x, 0), counts, incr);

      count_reg_usage (XEXP (x, 1), counts, incr);
      return;

    case ASM_OPERANDS:
      /* Iterate over just the inputs, not the constraints as well.  */
      for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
	count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, incr);
      return;

    case INSN_LIST:
      abort ();

    default:
      break;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	count_reg_usage (XEXP (x, i), counts, incr);
      else if (fmt[i] == 'E')
	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	  count_reg_usage (XVECEXP (x, i, j), counts, incr);
    }
}

/* Return true if set is live.  */
static bool
set_live_p (rtx set, rtx insn ATTRIBUTE_UNUSED, /* Only used with HAVE_cc0.  */
	    int *counts)
{
#ifdef HAVE_cc0
  rtx tem;
#endif

  if (set_noop_p (set))
    ;

#ifdef HAVE_cc0
  else if (GET_CODE (SET_DEST (set)) == CC0
	   && !side_effects_p (SET_SRC (set))
	   && ((tem = next_nonnote_insn (insn)) == 0
	       || !INSN_P (tem)
	       || !reg_referenced_p (cc0_rtx, PATTERN (tem))))
    return false;
#endif
  else if (GET_CODE (SET_DEST (set)) != REG
	   || REGNO (SET_DEST (set)) < FIRST_PSEUDO_REGISTER
	   || counts[REGNO (SET_DEST (set))] != 0
	   || side_effects_p (SET_SRC (set))
	   /* An ADDRESSOF expression can turn into a use of the
	      internal arg pointer, so always consider the
	      internal arg pointer live.  If it is truly dead,
	      flow will delete the initializing insn.  */
	   || (SET_DEST (set) == current_function_internal_arg_pointer))
    return true;
  return false;
}

/* Return true if insn is live.  */

static bool
insn_live_p (rtx insn, int *counts)
{
  int i;
  if (flag_non_call_exceptions && may_trap_p (PATTERN (insn)))
    return true;
  else if (GET_CODE (PATTERN (insn)) == SET)
    return set_live_p (PATTERN (insn), insn, counts);
  else if (GET_CODE (PATTERN (insn)) == PARALLEL)
    {
      for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
	{
	  rtx elt = XVECEXP (PATTERN (insn), 0, i);

	  if (GET_CODE (elt) == SET)
	    {
	      if (set_live_p (elt, insn, counts))
		return true;
	    }
	  else if (GET_CODE (elt) != CLOBBER && GET_CODE (elt) != USE)
	    return true;
	}
      return false;
    }
  else
    return true;
}

/* Return true if libcall is dead as a whole.  */

static bool
dead_libcall_p (rtx insn, int *counts)
{
  rtx note, set, new;

  /* See if there's a REG_EQUAL note on this insn and try to
     replace the source with the REG_EQUAL expression.

     We assume that insns with REG_RETVALs can only be reg->reg
     copies at this point.  */
  note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
  if (!note)
    return false;

  set = single_set (insn);
  if (!set)
    return false;

  new = simplify_rtx (XEXP (note, 0));
  if (!new)
    new = XEXP (note, 0);

  /* While changing insn, we must update the counts accordingly.  */
  count_reg_usage (insn, counts, -1);

  if (validate_change (insn, &SET_SRC (set), new, 0))
    {
      count_reg_usage (insn, counts, 1);
      remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
      remove_note (insn, note);
      return true;
    }

  if (CONSTANT_P (new))
    {
      new = force_const_mem (GET_MODE (SET_DEST (set)), new);
      if (new && validate_change (insn, &SET_SRC (set), new, 0))
	{
	  count_reg_usage (insn, counts, 1);
	  remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
	  remove_note (insn, note);
	  return true;
	}
    }

  count_reg_usage (insn, counts, 1);
  return false;
}

/* Scan all the insns and delete any that are dead; i.e., they store a register
   that is never used or they copy a register to itself.

   This is used to remove insns made obviously dead by cse, loop or other
   optimizations.  It improves the heuristics in loop since it won't try to
   move dead invariants out of loops or make givs for dead quantities.  The
   remaining passes of the compilation are also sped up.  */

int
delete_trivially_dead_insns (rtx insns, int nreg)
{
  int *counts;
  rtx insn, prev;
  int in_libcall = 0, dead_libcall = 0;
  int ndead = 0, nlastdead, niterations = 0;

  timevar_push (TV_DELETE_TRIVIALLY_DEAD);
  /* First count the number of times each register is used.  */
  counts = xcalloc (nreg, sizeof (int));
  for (insn = next_real_insn (insns); insn; insn = next_real_insn (insn))
    count_reg_usage (insn, counts, 1);

  do
    {
      nlastdead = ndead;
      niterations++;
      /* Go from the last insn to the first and delete insns that only set unused
	 registers or copy a register to itself.  As we delete an insn, remove
	 usage counts for registers it uses.

	 The first jump optimization pass may leave a real insn as the last
	 insn in the function.   We must not skip that insn or we may end
	 up deleting code that is not really dead.  */
      insn = get_last_insn ();
      if (! INSN_P (insn))
	insn = prev_real_insn (insn);

      for (; insn; insn = prev)
	{
	  int live_insn = 0;

	  prev = prev_real_insn (insn);

	  /* Don't delete any insns that are part of a libcall block unless
	     we can delete the whole libcall block.

	     Flow or loop might get confused if we did that.  Remember
	     that we are scanning backwards.  */
	  if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
	    {
	      in_libcall = 1;
	      live_insn = 1;
	      dead_libcall = dead_libcall_p (insn, counts);
	    }
	  else if (in_libcall)
	    live_insn = ! dead_libcall;
	  else
	    live_insn = insn_live_p (insn, counts);

	  /* If this is a dead insn, delete it and show registers in it aren't
	     being used.  */

	  if (! live_insn)
	    {
	      count_reg_usage (insn, counts, -1);
	      delete_insn_and_edges (insn);
	      ndead++;
	    }

	  if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
	    {
	      in_libcall = 0;
	      dead_libcall = 0;
	    }
	}
    }
  while (ndead != nlastdead);

  if (rtl_dump_file && ndead)
    fprintf (rtl_dump_file, "Deleted %i trivially dead insns; %i iterations\n",
	     ndead, niterations);
  /* Clean up.  */
  free (counts);
  timevar_pop (TV_DELETE_TRIVIALLY_DEAD);
  return ndead;
}

/* This function is called via for_each_rtx.  The argument, NEWREG, is
   a condition code register with the desired mode.  If we are looking
   at the same register in a different mode, replace it with
   NEWREG.  */

static int
cse_change_cc_mode (rtx *loc, void *data)
{
  rtx newreg = (rtx) data;

  if (*loc
      && GET_CODE (*loc) == REG
      && REGNO (*loc) == REGNO (newreg)
      && GET_MODE (*loc) != GET_MODE (newreg))
    {
      *loc = newreg;
      return -1;
    }
  return 0;
}

/* Change the mode of any reference to the register REGNO (NEWREG) to
   GET_MODE (NEWREG), starting at START.  Stop before END.  Stop at
   any instruction which modifies NEWREG.  */

static void
cse_change_cc_mode_insns (rtx start, rtx end, rtx newreg)
{
  rtx insn;

  for (insn = start; insn != end; insn = NEXT_INSN (insn))
    {
      if (! INSN_P (insn))
	continue;

      if (reg_set_p (newreg, insn))
	return;

      for_each_rtx (&PATTERN (insn), cse_change_cc_mode, newreg);
      for_each_rtx (&REG_NOTES (insn), cse_change_cc_mode, newreg);
    }
}

/* BB is a basic block which finishes with CC_REG as a condition code
   register which is set to CC_SRC.  Look through the successors of BB
   to find blocks which have a single predecessor (i.e., this one),
   and look through those blocks for an assignment to CC_REG which is
   equivalent to CC_SRC.  CAN_CHANGE_MODE indicates whether we are
   permitted to change the mode of CC_SRC to a compatible mode.  This
   returns VOIDmode if no equivalent assignments were found.
   Otherwise it returns the mode which CC_SRC should wind up with.

   The main complexity in this function is handling the mode issues.
   We may have more than one duplicate which we can eliminate, and we
   try to find a mode which will work for multiple duplicates.  */

static enum machine_mode
cse_cc_succs (basic_block bb, rtx cc_reg, rtx cc_src, bool can_change_mode)
{
  bool found_equiv;
  enum machine_mode mode;
  unsigned int insn_count;
  edge e;
  rtx insns[2];
  enum machine_mode modes[2];
  rtx last_insns[2];
  unsigned int i;
  rtx newreg;

  /* We expect to have two successors.  Look at both before picking
     the final mode for the comparison.  If we have more successors
     (i.e., some sort of table jump, although that seems unlikely),
     then we require all beyond the first two to use the same
     mode.  */

  found_equiv = false;
  mode = GET_MODE (cc_src);
  insn_count = 0;
  for (e = bb->succ; e; e = e->succ_next)
    {
      rtx insn;
      rtx end;

      if (e->flags & EDGE_COMPLEX)
	continue;

      if (! e->dest->pred
	  || e->dest->pred->pred_next
	  || e->dest == EXIT_BLOCK_PTR)
	continue;

      end = NEXT_INSN (BB_END (e->dest));
      for (insn = BB_HEAD (e->dest); insn != end; insn = NEXT_INSN (insn))
	{
	  rtx set;

	  if (! INSN_P (insn))
	    continue;

	  /* If CC_SRC is modified, we have to stop looking for
	     something which uses it.  */
	  if (modified_in_p (cc_src, insn))
	    break;

	  /* Check whether INSN sets CC_REG to CC_SRC.  */
	  set = single_set (insn);
	  if (set
	      && GET_CODE (SET_DEST (set)) == REG
	      && REGNO (SET_DEST (set)) == REGNO (cc_reg))
	    {
	      bool found;
	      enum machine_mode set_mode;
	      enum machine_mode comp_mode;

	      found = false;
	      set_mode = GET_MODE (SET_SRC (set));
	      comp_mode = set_mode;
	      if (rtx_equal_p (cc_src, SET_SRC (set)))
		found = true;
	      else if (GET_CODE (cc_src) == COMPARE
		       && GET_CODE (SET_SRC (set)) == COMPARE
		       && mode != set_mode
		       && rtx_equal_p (XEXP (cc_src, 0),
				       XEXP (SET_SRC (set), 0))
		       && rtx_equal_p (XEXP (cc_src, 1),
				       XEXP (SET_SRC (set), 1)))
			   
		{
		  comp_mode = (*targetm.cc_modes_compatible) (mode, set_mode);
		  if (comp_mode != VOIDmode
		      && (can_change_mode || comp_mode == mode))
		    found = true;
		}

	      if (found)
		{
		  found_equiv = true;
		  if (insn_count < ARRAY_SIZE (insns))
		    {
		      insns[insn_count] = insn;
		      modes[insn_count] = set_mode;
		      last_insns[insn_count] = end;
		      ++insn_count;

		      if (mode != comp_mode)
			{
			  if (! can_change_mode)
			    abort ();
			  mode = comp_mode;
			  PUT_MODE (cc_src, mode);
			}
		    }
		  else
		    {
		      if (set_mode != mode)
			{
			  /* We found a matching expression in the
			     wrong mode, but we don't have room to
			     store it in the array.  Punt.  This case
			     should be rare.  */
			  break;
			}
		      /* INSN sets CC_REG to a value equal to CC_SRC
			 with the right mode.  We can simply delete
			 it.  */
		      delete_insn (insn);
		    }

		  /* We found an instruction to delete.  Keep looking,
		     in the hopes of finding a three-way jump.  */
		  continue;
		}

	      /* We found an instruction which sets the condition
		 code, so don't look any farther.  */
	      break;
	    }

	  /* If INSN sets CC_REG in some other way, don't look any
	     farther.  */
	  if (reg_set_p (cc_reg, insn))
	    break;
	}

      /* If we fell off the bottom of the block, we can keep looking
	 through successors.  We pass CAN_CHANGE_MODE as false because
	 we aren't prepared to handle compatibility between the
	 further blocks and this block.  */
      if (insn == end)
	{
	  enum machine_mode submode;

	  submode = cse_cc_succs (e->dest, cc_reg, cc_src, false);
	  if (submode != VOIDmode)
	    {
	      if (submode != mode)
		abort ();
	      found_equiv = true;
	      can_change_mode = false;
	    }
	}
    }

  if (! found_equiv)
    return VOIDmode;

  /* Now INSN_COUNT is the number of instructions we found which set
     CC_REG to a value equivalent to CC_SRC.  The instructions are in
     INSNS.  The modes used by those instructions are in MODES.  */

  newreg = NULL_RTX;
  for (i = 0; i < insn_count; ++i)
    {
      if (modes[i] != mode)
	{
	  /* We need to change the mode of CC_REG in INSNS[i] and
	     subsequent instructions.  */
	  if (! newreg)
	    {
	      if (GET_MODE (cc_reg) == mode)
		newreg = cc_reg;
	      else
		newreg = gen_rtx_REG (mode, REGNO (cc_reg));
	    }
	  cse_change_cc_mode_insns (NEXT_INSN (insns[i]), last_insns[i],
				    newreg);
	}

      delete_insn (insns[i]);
    }

  return mode;
}

/* If we have a fixed condition code register (or two), walk through
   the instructions and try to eliminate duplicate assignments.  */

void
cse_condition_code_reg (void)
{
  unsigned int cc_regno_1;
  unsigned int cc_regno_2;
  rtx cc_reg_1;
  rtx cc_reg_2;
  basic_block bb;

  if (! (*targetm.fixed_condition_code_regs) (&cc_regno_1, &cc_regno_2))
    return;

  cc_reg_1 = gen_rtx_REG (CCmode, cc_regno_1);
  if (cc_regno_2 != INVALID_REGNUM)
    cc_reg_2 = gen_rtx_REG (CCmode, cc_regno_2);
  else
    cc_reg_2 = NULL_RTX;

  FOR_EACH_BB (bb)
    {
      rtx last_insn;
      rtx cc_reg;
      rtx insn;
      rtx cc_src_insn;
      rtx cc_src;
      enum machine_mode mode;
      enum machine_mode orig_mode;

      /* Look for blocks which end with a conditional jump based on a
	 condition code register.  Then look for the instruction which
	 sets the condition code register.  Then look through the
	 successor blocks for instructions which set the condition
	 code register to the same value.  There are other possible
	 uses of the condition code register, but these are by far the
	 most common and the ones which we are most likely to be able
	 to optimize.  */

      last_insn = BB_END (bb);
      if (GET_CODE (last_insn) != JUMP_INSN)
	continue;

      if (reg_referenced_p (cc_reg_1, PATTERN (last_insn)))
	cc_reg = cc_reg_1;
      else if (cc_reg_2 && reg_referenced_p (cc_reg_2, PATTERN (last_insn)))
	cc_reg = cc_reg_2;
      else
	continue;

      cc_src_insn = NULL_RTX;
      cc_src = NULL_RTX;
      for (insn = PREV_INSN (last_insn);
	   insn && insn != PREV_INSN (BB_HEAD (bb));
	   insn = PREV_INSN (insn))
	{
	  rtx set;

	  if (! INSN_P (insn))
	    continue;
	  set = single_set (insn);
	  if (set
	      && GET_CODE (SET_DEST (set)) == REG
	      && REGNO (SET_DEST (set)) == REGNO (cc_reg))
	    {
	      cc_src_insn = insn;
	      cc_src = SET_SRC (set);
	      break;
	    }
	  else if (reg_set_p (cc_reg, insn))
	    break;
	}

      if (! cc_src_insn)
	continue;

      if (modified_between_p (cc_src, cc_src_insn, NEXT_INSN (last_insn)))
	continue;

      /* Now CC_REG is a condition code register used for a
	 conditional jump at the end of the block, and CC_SRC, in
	 CC_SRC_INSN, is the value to which that condition code
	 register is set, and CC_SRC is still meaningful at the end of
	 the basic block.  */

      orig_mode = GET_MODE (cc_src);
      mode = cse_cc_succs (bb, cc_reg, cc_src, true);
      if (mode != VOIDmode)
	{
	  if (mode != GET_MODE (cc_src))
	    abort ();
	  if (mode != orig_mode)
	    {
	      rtx newreg = gen_rtx_REG (mode, REGNO (cc_reg));

	      /* Change the mode of CC_REG in CC_SRC_INSN to
		 GET_MODE (NEWREG).  */
	      for_each_rtx (&PATTERN (cc_src_insn), cse_change_cc_mode,
			    newreg);
	      for_each_rtx (&REG_NOTES (cc_src_insn), cse_change_cc_mode,
			    newreg);

	      /* Do the same in the following insns that use the
		 current value of CC_REG within BB.  */
	      cse_change_cc_mode_insns (NEXT_INSN (cc_src_insn),
					NEXT_INSN (last_insn),
					newreg);
	    }
	}
    }
}
