/* Common subexpression elimination for GNU compiler.
   Copyright (C) 1987, 88, 89, 92-7, 1998, 1999 Free Software Foundation, Inc.

This file is part of GNU CC.

GNU CC 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.

GNU CC 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 GNU CC; 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 <setjmp.h>

#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "flags.h"
#include "real.h"
#include "insn-config.h"
#include "recog.h"
#include "expr.h"
#include "toplev.h"
#include "output.h"
#include "splay-tree.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; so, at each label, we forget all that is
   known and start fresh.  This can be described as processing each
   basic block separately.  Note, however, that these are not quite
   the same as the basic blocks found by a later pass and used for
   data flow analysis and register packing.  We do not need to start fresh
   after a conditional jump instruction if there is no label there.

   We use two data structures to record the equivalent expressions:
   a hash table for most expressions, and several vectors together
   with "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 `max_reg'.
   If register N has not been assigned a quantity, reg_qty[N] will equal N.

   Quantity numbers below `max_reg' do not exist and none of the `qty_...'
   variables should be referenced with an index below `max_reg'.

   We also maintain a bidirectional chain of registers for each
   quantity number.  `qty_first_reg', `qty_last_reg',
   `reg_next_eqv' and `reg_prev_eqv' 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_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 element of qty_const.  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 element
   of qty_const.

   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_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 vectors indexed by quantity number.
   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;

/* Indexed by quantity number, gives the first (or last) register 
   in the chain of registers that currently contain this quantity.  */

static int *qty_first_reg;
static int *qty_last_reg;

/* Index by quantity number, gives the mode of the quantity.  */

static enum machine_mode *qty_mode;

/* Indexed by quantity number, gives the rtx of the constant value of the
   quantity, or zero if it does not have a known value.
   A sum of the frame pointer (or arg pointer) plus a constant
   can also be entered here.  */

static rtx *qty_const;

/* Indexed by qty number, gives the insn that stored the constant value
   recorded in `qty_const'.  */

static rtx *qty_const_insn;

/* The next three variables are used to track when a comparison between a
   quantity and some constant or register has been passed.  In that case, we
   know the results of the comparison in case we see it again.  These variables
   record a comparison that is known to be true.  */

/* Indexed by qty number, gives the rtx code of a comparison with a known
   result involving this quantity.  If none, it is UNKNOWN.  */
static enum rtx_code *qty_comparison_code;

/* Indexed by qty number, gives the constant being compared against in a
   comparison of known result.  If no such comparison, it is undefined.
   If the comparison is not with a constant, it is zero.  */

static rtx *qty_comparison_const;

/* Indexed by qty number, gives the quantity being compared against in a
   comparison of known result.  If no such comparison, if it undefined.
   If the comparison is not with a register, it is -1.  */

static int *qty_comparison_qty;

#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;
#endif

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

static rtx prev_insn;

/* 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_next_eqv[N] is undefined.  */

static int *reg_next_eqv;
static int *reg_prev_eqv;

struct cse_reg_info {
  union {
    /* The number of times the register has been altered in the current
       basic block.  */
    int reg_tick;
    
    /* The next cse_reg_info structure in the free list.  */
    struct cse_reg_info* next;
  } variant;

  /* 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 quantity number of the register's current contents.  */
  int reg_qty;
};

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

/* A mapping from registers to cse_reg_info data structures.  */
static splay_tree cse_reg_info_tree;

/* The last lookup we did into the cse_reg_info_tree.  This allows us
   to cache repeated lookups.  */
static 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;

/* A HARD_REG_SET containing all the hard registers that are invalidated
   by a CALL_INSN.  */

static HARD_REG_SET regs_invalidated_by_call;

/* 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 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.  Since we may have put
   it into 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;

/* canon_hash stores 1 in hash_arg_in_struct
   if it notices a reference to memory that's part of a structure.  */

static int hash_arg_in_struct;

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

   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 `in_struct' field is nonzero for elements that
   involve any reference to memory inside a structure or array.

   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 `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;
  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;
  enum machine_mode mode;
  char in_memory;
  char in_struct;
  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 NBUCKETS 31

/* 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))) % NBUCKETS	\
  : canon_hash (X, M) % NBUCKETS)

/* Determine whether register number N is considered a fixed register for CSE.
   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,
   but not if it is an overlapping register.  */
#ifdef OVERLAPPING_REGNO_P
#define FIXED_REGNO_P(N)  \
  (((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \
    || fixed_regs[N] || global_regs[N])	  \
   && ! OVERLAPPING_REGNO_P ((N)))
#else
#define FIXED_REGNO_P(N)  \
  ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \
   || fixed_regs[N] || global_regs[N])
#endif

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

/* A register is cheap if it is a user variable assigned to the register
   or if its register number always corresponds to a cheap register.  */

#define CHEAP_REG(N) \
  ((REG_USERVAR_P (N) && REGNO (N) < FIRST_PSEUDO_REGISTER)	\
   || CHEAP_REGNO (REGNO (N)))

#define COST(X)								\
  (GET_CODE (X) == REG							\
   ? (CHEAP_REG (X) ? 0							\
      : REGNO (X) >= FIRST_PSEUDO_REGISTER ? 1				\
      : 2)								\
   : notreg_cost(X))

/* 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))->variant.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 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_...' variables.  */

#define REGNO_QTY_VALID_P(N) (REG_QTY (N) != (N))

#ifdef ADDRESS_COST
/* The ADDRESS_COST macro 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.  */
#define CSE_ADDRESS_COST(RTX)					\
  ((GET_CODE (RTX) == ADDRESSOF && REG_P (XEXP ((RTX), 0)))	\
   ? -1 : ADDRESS_COST(RTX))
#endif 

static struct table_elt *table[NBUCKETS];

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

/* Define maximum length of a branch path.  */

#define PATHLENGTH	10

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

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

#define FIXED_BASE_PLUS_P(X)					\
  ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx	\
   || (X) == arg_pointer_rtx					\
   || (X) == virtual_stack_vars_rtx				\
   || (X) == virtual_incoming_args_rtx				\
   || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
       && (XEXP (X, 0) == frame_pointer_rtx			\
	   || XEXP (X, 0) == hard_frame_pointer_rtx		\
	   || XEXP (X, 0) == arg_pointer_rtx			\
	   || XEXP (X, 0) == virtual_stack_vars_rtx		\
	   || XEXP (X, 0) == virtual_incoming_args_rtx))	\
   || GET_CODE (X) == ADDRESSOF)

/* Similar, but also allows reference to the stack pointer.

   This used to include FIXED_BASE_PLUS_P, however, we can't assume that
   arg_pointer_rtx by itself is nonzero, because on at least one machine,
   the i960, the arg pointer is zero when it is unused.  */

#define NONZERO_BASE_PLUS_P(X)					\
  ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx	\
   || (X) == virtual_stack_vars_rtx				\
   || (X) == virtual_incoming_args_rtx				\
   || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
       && (XEXP (X, 0) == frame_pointer_rtx			\
	   || XEXP (X, 0) == hard_frame_pointer_rtx		\
	   || XEXP (X, 0) == arg_pointer_rtx			\
	   || XEXP (X, 0) == virtual_stack_vars_rtx		\
	   || XEXP (X, 0) == virtual_incoming_args_rtx))	\
   || (X) == stack_pointer_rtx					\
   || (X) == virtual_stack_dynamic_rtx				\
   || (X) == virtual_outgoing_args_rtx				\
   || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
       && (XEXP (X, 0) == stack_pointer_rtx			\
	   || XEXP (X, 0) == virtual_stack_dynamic_rtx		\
	   || XEXP (X, 0) == virtual_outgoing_args_rtx))	\
   || GET_CODE (X) == ADDRESSOF)

static int notreg_cost		PROTO((rtx));
static void new_basic_block	PROTO((void));
static void make_new_qty	PROTO((int));
static void make_regs_eqv	PROTO((int, int));
static void delete_reg_equiv	PROTO((int));
static int mention_regs		PROTO((rtx));
static int insert_regs		PROTO((rtx, struct table_elt *, int));
static void free_element	PROTO((struct table_elt *));
static void remove_from_table	PROTO((struct table_elt *, unsigned));
static struct table_elt *get_element PROTO((void));
static struct table_elt *lookup	PROTO((rtx, unsigned, enum machine_mode)),
       *lookup_for_remove PROTO((rtx, unsigned, enum machine_mode));
static rtx lookup_as_function	PROTO((rtx, enum rtx_code));
static struct table_elt *insert PROTO((rtx, struct table_elt *, unsigned,
				       enum machine_mode));
static void merge_equiv_classes PROTO((struct table_elt *,
				       struct table_elt *));
static void invalidate		PROTO((rtx, enum machine_mode));
static int cse_rtx_varies_p	PROTO((rtx));
static void remove_invalid_refs	PROTO((int));
static void remove_invalid_subreg_refs	PROTO((int, int, enum machine_mode));
static void rehash_using_reg	PROTO((rtx));
static void invalidate_memory	PROTO((void));
static void invalidate_for_call	PROTO((void));
static rtx use_related_value	PROTO((rtx, struct table_elt *));
static unsigned canon_hash	PROTO((rtx, enum machine_mode));
static unsigned safe_hash	PROTO((rtx, enum machine_mode));
static int exp_equiv_p		PROTO((rtx, rtx, int, int));
static void set_nonvarying_address_components PROTO((rtx, int, rtx *,
						     HOST_WIDE_INT *,
						     HOST_WIDE_INT *));
static int refers_to_p		PROTO((rtx, rtx));
static rtx canon_reg		PROTO((rtx, rtx));
static void find_best_addr	PROTO((rtx, rtx *));
static enum rtx_code find_comparison_args PROTO((enum rtx_code, rtx *, rtx *,
						 enum machine_mode *,
						 enum machine_mode *));
static rtx cse_gen_binary	PROTO((enum rtx_code, enum machine_mode,
				       rtx, rtx));
static rtx simplify_plus_minus	PROTO((enum rtx_code, enum machine_mode,
				       rtx, rtx));
static rtx fold_rtx		PROTO((rtx, rtx));
static rtx equiv_constant	PROTO((rtx));
static void record_jump_equiv	PROTO((rtx, int));
static void record_jump_cond	PROTO((enum rtx_code, enum machine_mode,
				       rtx, rtx, int));
static void cse_insn		PROTO((rtx, rtx));
static int note_mem_written	PROTO((rtx));
static void invalidate_from_clobbers PROTO((rtx));
static rtx cse_process_notes	PROTO((rtx, rtx));
static void cse_around_loop	PROTO((rtx));
static void invalidate_skipped_set PROTO((rtx, rtx));
static void invalidate_skipped_block PROTO((rtx));
static void cse_check_loop_start PROTO((rtx, rtx));
static void cse_set_around_loop	PROTO((rtx, rtx, rtx));
static rtx cse_basic_block	PROTO((rtx, rtx, struct branch_path *, int));
static void count_reg_usage	PROTO((rtx, int *, rtx, int));
extern void dump_class          PROTO((struct table_elt*));
static void check_fold_consts	PROTO((PTR));
static struct cse_reg_info* get_cse_reg_info PROTO((int));
static void free_cse_reg_info   PROTO((splay_tree_value));
static void flush_hash_table	PROTO((void));

extern int rtx_equal_function_value_matters;

/* Dump the expressions in the equivalence class indicated by CLASSP.
   This function is used only for debugging.  */
void
dump_class (classp)
     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");
    }
}

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

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

static int
notreg_cost (x)
     rtx x;
{
  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)))))
	  ? (CHEAP_REG (SUBREG_REG (x)) ? 0
	     : (REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER ? 1
		: 2))
	  : rtx_cost (x, SET) * 2);
}

/* Return the right cost to give to an operation
   to make the cost of the corresponding register-to-register instruction
   N times that of a fast register-to-register instruction.  */

#define COSTS_N_INSNS(N) ((N) * 4 - 2)

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

  if (x == 0)
    return 0;

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

  code = GET_CODE (x);
  switch (code)
    {
    case MULT:
      /* Count multiplication by 2**n as a shift,
	 because if we are considering it, we would output it as a shift.  */
      if (GET_CODE (XEXP (x, 1)) == CONST_INT
	  && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
	total = 2;
      else
	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;
    case ASM_OPERANDS:
      /* We don't want these to be used in substitutions because
	 we have no way of validating the resulting insn.  So assign
	 anything containing an ASM_OPERANDS a very high cost.  */
      total = 1000;
      break;
    default:
      total = 2;
    }

  switch (code)
    {
    case REG:
      return ! CHEAP_REG (x);

    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);
      return 2;
#ifdef RTX_COSTS
      RTX_COSTS (x, code, outer_code);
#endif 
#ifdef CONST_COSTS
      CONST_COSTS (x, code, outer_code);
#endif

    default:
#ifdef DEFAULT_RTX_COSTS
      DEFAULT_RTX_COSTS(x, code, outer_code);
#endif
      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;
}

static struct cse_reg_info *
get_cse_reg_info (regno)
     int regno;
{
  struct cse_reg_info *cri;
  splay_tree_node n;

  /* See if we already have this entry.  */
  n = splay_tree_lookup (cse_reg_info_tree, 
			(splay_tree_key) regno);
  if (n)
    cri = (struct cse_reg_info *) (n->value);
  else 
    {
      /* Get a new cse_reg_info structure.  */
      if (cse_reg_info_free_list) 
	{
	  cri = cse_reg_info_free_list;
	  cse_reg_info_free_list = cri->variant.next;
	}
      else
	cri = (struct cse_reg_info *) xmalloc (sizeof (struct cse_reg_info));

      /* Initialize it.  */
      cri->variant.reg_tick = 0;
      cri->reg_in_table = -1;
      cri->reg_qty = regno;

      splay_tree_insert (cse_reg_info_tree, 
			 (splay_tree_key) regno, 
			 (splay_tree_value) cri);
    }

  /* 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 = cri;

  return cri;
}

static void
free_cse_reg_info (v)
     splay_tree_value v;
{
  struct cse_reg_info *cri = (struct cse_reg_info *) v;
  
  cri->variant.next = cse_reg_info_free_list;
  cse_reg_info_free_list = cri;
}

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

static void
new_basic_block ()
{
  register int i;

  next_qty = max_reg;

  if (cse_reg_info_tree) 
    {
      splay_tree_delete (cse_reg_info_tree);
      cached_cse_reg_info = 0;
    }

  cse_reg_info_tree = splay_tree_new (splay_tree_compare_ints, 0, 
				      free_cse_reg_info);

  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 < NBUCKETS; i++)
    {
      register struct table_elt *this, *next;
      for (this = table[i]; this; this = next)
	{
	  next = this->next_same_hash;
	  free_element (this);
	}
    }

  bzero ((char *) table, sizeof table);

  prev_insn = 0;

#ifdef HAVE_cc0
  prev_insn_cc0 = 0;
#endif
}

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

static void
make_new_qty (reg)
     register int reg;
{
  register int q;

  if (next_qty >= max_qty)
    abort ();

  q = REG_QTY (reg) = next_qty++;
  qty_first_reg[q] = reg;
  qty_last_reg[q] = reg;
  qty_const[q] = qty_const_insn[q] = 0;
  qty_comparison_code[q] = UNKNOWN;

  reg_next_eqv[reg] = reg_prev_eqv[reg] = -1;
}

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

static void
make_regs_eqv (new, old)
     register int new, old;
{
  register int lastr, firstr;
  register int q = REG_QTY (old);

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

  REG_QTY (new) = q;
  firstr = qty_first_reg[q];
  lastr = qty_last_reg[q];

  /* 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_prev_eqv[firstr] = new;
      reg_next_eqv[new] = firstr;
      reg_prev_eqv[new] = -1;
      qty_first_reg[q] = 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_prev_eqv[lastr] >= 0
	     && (REGNO_REG_CLASS (lastr) == NO_REGS || ! FIXED_REGNO_P (lastr))
	     && new >= FIRST_PSEUDO_REGISTER)
	lastr = reg_prev_eqv[lastr];
      reg_next_eqv[new] = reg_next_eqv[lastr];
      if (reg_next_eqv[lastr] >= 0)
	reg_prev_eqv[reg_next_eqv[lastr]] = new;
      else
	qty_last_reg[q] = new;
      reg_next_eqv[lastr] = new;
      reg_prev_eqv[new] = lastr;
    }
}

/* Remove REG from its equivalence class.  */

static void
delete_reg_equiv (reg)
     register int reg;
{
  register int q = REG_QTY (reg);
  register int p, n;

  /* If invalid, do nothing.  */
  if (q == reg)
    return;

  p = reg_prev_eqv[reg];
  n = reg_next_eqv[reg];

  if (n != -1)
    reg_prev_eqv[n] = p;
  else
    qty_last_reg[q] = p;
  if (p != -1)
    reg_next_eqv[p] = n;
  else
    qty_first_reg[q] = n;

  REG_QTY (reg) = reg;
}

/* 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 (x)
     rtx x;
{
  register enum rtx_code code;
  register int i, j;
  register char *fmt;
  register int changed = 0;

  if (x == 0)
    return 0;

  code = GET_CODE (x);
  if (code == REG)
    {
      register int regno = REGNO (x);
      register int endregno
	= regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
		   : HARD_REGNO_NREGS (regno, GET_MODE (x)));
      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);
	}

      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)
    {
      int i = REGNO (SUBREG_REG (x));

      if (REG_IN_TABLE (i) >= 0 && REG_IN_TABLE (i) != REG_TICK (i))
	{
	  /* If reg_tick has been incremented more than once since
	     reg_in_table was last set, that means that the entire
	     register has been set before, so discard anything memorized
	     for the entrire register, including all SUBREG expressions.  */
	  if (REG_IN_TABLE (i) != REG_TICK (i) - 1)
	    remove_invalid_refs (i);
	  else
	    remove_invalid_subreg_refs (i, SUBREG_WORD (x), GET_MODE (x));
	}

      REG_IN_TABLE (i) = REG_TICK (i);
      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_PTR, 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_PTR, 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 (x, classp, modified)
     rtx x;
     struct table_elt *classp;
     int modified;
{
  if (GET_CODE (x) == REG)
    {
      register int regno = REGNO (x);

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

      if (REGNO_QTY_VALID_P (regno)
	  && qty_mode[REG_QTY (regno)] != GET_MODE (x))
	return 0;

      if (modified || ! REGNO_QTY_VALID_P (regno))
	{
	  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;
		}

	  make_new_qty (regno);
	  qty_mode[REG_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))))
    {
      int regno = REGNO (SUBREG_REG (x));

      insert_regs (SUBREG_REG (x), NULL_PTR, 0);
      /* Mention_regs 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.  Since we don't invalidate the SUBREG
	 here first, we might have to bump up REG_TICK so that mention_regs
	 will do the right thing.  */
      if (REG_IN_TABLE (regno) >= 0
	  && REG_TICK (regno) == REG_IN_TABLE (regno) + 1)
	REG_TICK (regno)++;
      mention_regs (x);
      return 1;
    }
  else
    return mention_regs (x);
}

/* Look in or update the hash table.  */

/* Put the element ELT on the list of free elements.  */

static void
free_element (elt)
     struct table_elt *elt;
{
  elt->next_same_hash = free_element_chain;
  free_element_chain = elt;
}

/* Return an element that is free for use.  */

static struct table_elt *
get_element ()
{
  struct table_elt *elt = free_element_chain;
  if (elt)
    {
      free_element_chain = elt->next_same_hash;
      return elt;
    }
  n_elements_made++;
  return (struct table_elt *) oballoc (sizeof (struct table_elt));
}

/* 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 (elt, hash)
     register struct table_elt *elt;
     unsigned 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.  */
     
  {
    register struct table_elt *prev = elt->prev_same_value;
    register struct table_elt *next = elt->next_same_value;

    if (next) next->prev_same_value = prev;

    if (prev)
      prev->next_same_value = next;
    else
      {
	register 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.  */

  {
    register struct table_elt *prev = elt->prev_same_hash;
    register 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 < NBUCKETS; 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)
    {
      register 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;
    }

  free_element (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 (x, hash, mode)
     rtx x;
     unsigned hash;
     enum machine_mode mode;
{
  register 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 (x, hash, mode)
     rtx x;
     unsigned hash;
     enum machine_mode mode;
{
  register struct table_elt *p;

  if (GET_CODE (x) == REG)
    {
      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 (x, code)
     rtx x;
     enum rtx_code code;
{
  register struct table_elt *p = lookup (x, safe_hash (x, VOIDmode) % NBUCKETS,
					 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) % NBUCKETS, 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)   ((X)->cost < (Y)->cost)

static struct table_elt *
insert (x, classp, hash, mode)
     register rtx x;
     register struct table_elt *classp;
     unsigned hash;
     enum machine_mode mode;
{
  register 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)
    {
      int regno = REGNO (x);
      int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
      int i;

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

  /* If X is a label, show we recorded it.  */
  if (GET_CODE (x) == LABEL_REF
      || (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF))
    recorded_label_ref = 1;

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

  elt = get_element ();
  elt->exp = x;
  elt->cost = 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).  */
		   || (RTX_UNCHANGING_P (x)
		       && GET_CODE (x) == REG
		       && 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 */
	{
	  register 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.  */
	  register 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 `qty_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)
    {
      qty_const[REG_QTY (REGNO (classp->exp))]
	= gen_lowpart_if_possible (qty_mode[REG_QTY (REGNO (classp->exp))], x);
      qty_const_insn[REG_QTY (REGNO (classp->exp))] = this_insn;
    }

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

      for (p = classp; p != 0; p = p->next_same_value)
	{
	  if (p->is_const && GET_CODE (p->exp) != REG)
	    {
	      qty_const[REG_QTY (REGNO (x))]
		= gen_lowpart_if_possible (GET_MODE (x), p->exp);
	      qty_const_insn[REG_QTY (REGNO (x))] = this_insn;
	      break;
	    }
	}
    }

  else if (GET_CODE (x) == REG && qty_const[REG_QTY (REGNO (x))]
	   && GET_MODE (x) == qty_mode[REG_QTY (REGNO (x))])
    qty_const_insn[REG_QTY (REGNO (x))] = 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) % NBUCKETS;
	  subelt = lookup (subexp, subhash, mode);
	  if (subelt == 0)
	    subelt = insert (subexp, NULL_PTR, 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 (class1, class2)
     struct table_elt *class1, *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 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))
	{
	  hash_arg_in_memory = 0;
	  hash_arg_in_struct = 0;
	  hash = HASH (exp, mode);
	      
	  if (GET_CODE (exp) == REG)
	    delete_reg_equiv (REGNO (exp));
	      
	  remove_from_table (elt, hash);

	  if (insert_regs (exp, class1, 0))
	    {
	      rehash_using_reg (exp);
	      hash = HASH (exp, mode);
	    }
	  new = insert (exp, class1, hash, mode);
	  new->in_memory = hash_arg_in_memory;
	  new->in_struct = hash_arg_in_struct;
	}
    }
}


/* Flush the entire hash table.  */

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

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


/* 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 (x, full_mode)
     rtx x;
     enum machine_mode full_mode;
{
  register int i;
  register struct table_elt *p;

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

  if (GET_CODE (x) == REG)
    {
      register int regno = REGNO (x);
      register unsigned 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)++;

      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);
	  int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
	  int tregno, tendregno;
	  register struct table_elt *p, *next;

	  CLEAR_HARD_REG_BIT (hard_regs_in_table, regno);

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

	  if (in_table)
	    for (hash = 0; hash < NBUCKETS; 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;
    }

  if (GET_CODE (x) == SUBREG)
    {
      if (GET_CODE (SUBREG_REG (x)) != REG)
	abort ();
      invalidate (SUBREG_REG (x), VOIDmode);
      return;
    }

  /* If X is a parallel, invalidate all of its elements.  */

  if (GET_CODE (x) == PARALLEL)
    {
      for (i = XVECLEN (x, 0) - 1; i >= 0 ; --i)
	invalidate (XVECEXP (x, 0, i), VOIDmode);
      return;
    }

  /* If X is an expr_list, this is part of a disjoint return value;
     extract the location in question ignoring the offset.  */

  if (GET_CODE (x) == EXPR_LIST)
    {
      invalidate (XEXP (x, 0), VOIDmode);
      return;
    }

  /* X is not a register; it must be a memory reference with
     a nonvarying address.  Remove all hash table elements
     that refer to overlapping pieces of memory.  */

  if (GET_CODE (x) != MEM)
    abort ();

  if (full_mode == VOIDmode)
    full_mode = GET_MODE (x);

  for (i = 0; i < NBUCKETS; i++)
    {
      register struct table_elt *next;
      for (p = table[i]; p; p = next)
	{
	  next = p->next_same_hash;
	  /* Invalidate ASM_OPERANDS which reference memory (this is easier
	     than checking all the aliases).  */
	  if (p->in_memory
	      && (GET_CODE (p->exp) != MEM
		  || true_dependence (x, full_mode, p->exp, cse_rtx_varies_p)))
	    remove_from_table (p, i);
	}
    }
}

/* 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 (regno)
     int regno;
{
  register int i;
  register struct table_elt *p, *next;

  for (i = 0; i < NBUCKETS; 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, NULL_PTR))
	  remove_from_table (p, i);
      }
}

/* Likewise for a subreg with subreg_reg WORD and mode MODE.  */
static void
remove_invalid_subreg_refs (regno, word, mode)
     int regno;
     int word;
     enum machine_mode mode;
{
  register int i;
  register struct table_elt *p, *next;
  int end = word + (GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD;

  for (i = 0; i < NBUCKETS; i++)
    for (p = table[i]; p; p = next)
      {
	rtx exp;
	next = p->next_same_hash;
	
	exp = p->exp;
	if (GET_CODE (p->exp) != REG
	    && (GET_CODE (exp) != SUBREG
		|| GET_CODE (SUBREG_REG (exp)) != REG
		|| REGNO (SUBREG_REG (exp)) != regno
		|| (((SUBREG_WORD (exp)
		      + (GET_MODE_SIZE (GET_MODE (exp)) - 1) / UNITS_PER_WORD)
		     >= word)
		 && SUBREG_WORD (exp) <= end))
	    && refers_to_regno_p (regno, regno + 1, p->exp, NULL_PTR))
	  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 (x)
     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.  We can skip
     objects that are registers, since they are handled specially.  */

  for (i = 0; i < NBUCKETS; i++)
    for (p = table[i]; p; p = next)
      {
	next = p->next_same_hash;
	if (GET_CODE (p->exp) != REG && reg_mentioned_p (x, p->exp)
	    && exp_equiv_p (p->exp, p->exp, 1, 0)
	    && i != (hash = safe_hash (p->exp, p->mode) % NBUCKETS))
	  {
	    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 ()
{
  int regno, endregno;
  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)++;

	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 < NBUCKETS; hash++)
      for (p = table[hash]; p; p = next)
	{
	  next = p->next_same_hash;

	  if (p->in_memory)
	    {
	      remove_from_table (p, hash);
	      continue;
	    }

	  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 (x, elt)
     rtx x;
     struct table_elt *elt;
{
  register struct table_elt *relt = 0;
  register 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)) % NBUCKETS,
		       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 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.
   In this case, also store 1 in hash_arg_in_struct
   if there is a MEM rtx which has the MEM_IN_STRUCT_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 (x, mode)
     rtx x;
     enum machine_mode mode;
{
  register int i, j;
  register unsigned hash = 0;
  register enum rtx_code code;
  register 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:
      {
	register int regno = REGNO (x);

	/* On some machines, we can't record any non-fixed hard register,
	   because extending its life will cause reload problems.  We
	   consider ap, fp, and sp 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.  */

	if (regno < FIRST_PSEUDO_REGISTER
	    && (global_regs[regno]
		|| (SMALL_REGISTER_CLASSES
		    && ! fixed_regs[regno]
		    && regno != FRAME_POINTER_REGNUM
		    && regno != HARD_FRAME_POINTER_REGNUM
		    && regno != ARG_POINTER_REGNUM
		    && regno != STACK_POINTER_REGNUM
		    && GET_MODE_CLASS (GET_MODE (x)) != MODE_CC)))
	  {
	    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_WORD (x));
	    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)
	for (i = 2; i < GET_RTX_LENGTH (CONST_DOUBLE); i++)
	  {
	    unsigned tem = XINT (x, i);
	    hash += tem;
	  }
      else
	hash += ((unsigned) CONST_DOUBLE_LOW (x)
		 + (unsigned) CONST_DOUBLE_HIGH (x));
      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:
      if (MEM_VOLATILE_P (x))
	{
	  do_not_record = 1;
	  return 0;
	}
      if (! RTX_UNCHANGING_P (x) || FIXED_BASE_PLUS_P (XEXP (x, 0)))
	{
	  hash_arg_in_memory = 1;
	  if (MEM_IN_STRUCT_P (x)) hash_arg_in_struct = 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 PRE_DEC:
    case PRE_INC:
    case POST_DEC:
    case POST_INC:
    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;
	}
      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')
	{
	  register unsigned char *p = (unsigned char *) XSTR (x, i);
	  if (p)
	    while (*p)
	      hash += *p++;
	}
      else if (fmt[i] == 'i')
	{
	  register unsigned tem = XINT (x, i);
	  hash += tem;
	}
      else if (fmt[i] == '0')
	/* unused */;
      else
	abort ();
    }
  return hash;
}

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

static unsigned
safe_hash (x, mode)
     rtx x;
     enum machine_mode mode;
{
  int save_do_not_record = do_not_record;
  int save_hash_arg_in_memory = hash_arg_in_memory;
  int save_hash_arg_in_struct = hash_arg_in_struct;
  unsigned hash = canon_hash (x, mode);
  hash_arg_in_memory = save_hash_arg_in_memory;
  hash_arg_in_struct = save_hash_arg_in_struct;
  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 (x, y, validate, equal_values)
     rtx x, y;
     int validate;
     int equal_values;
{
  register int i, j;
  register enum rtx_code code;
  register 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))
	  && GET_MODE (y) == qty_mode[REG_QTY (REGNO (y))]
	  && rtx_equal_p (x, qty_const[REG_QTY (REGNO (y))])
	  && (! validate || REG_IN_TABLE (REGNO (y)) == REG_TICK (REGNO (y))))
	return 1;

      if (CONSTANT_P (y) && code == REG
	  && REGNO_QTY_VALID_P (REGNO (x))
	  && GET_MODE (x) == qty_mode[REG_QTY (REGNO (x))]
	  && rtx_equal_p (y, qty_const[REG_QTY (REGNO (x))]))
	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:
      return x == y;

    case CONST_INT:
      return INTVAL (x) == INTVAL (y);

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

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

    case REG:
      {
	int regno = REGNO (y);
	int endregno
	  = regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
		     : HARD_REGNO_NREGS (regno, GET_MODE (y)));
	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)));
      
    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':
	  break;

	default:
	  abort ();
	}
      }

  return 1;
}

/* Return 1 iff any subexpression of X matches Y.
   Here we do not require that X or Y be valid (for registers referred to)
   for being in the hash table.  */

static int
refers_to_p (x, y)
     rtx x, y;
{
  register int i;
  register enum rtx_code code;
  register char *fmt;

 repeat:
  if (x == y)
    return 1;
  if (x == 0 || y == 0)
    return 0;

  code = GET_CODE (x);
  /* If X as a whole has the same code as Y, they may match.
     If so, return 1.  */
  if (code == GET_CODE (y))
    {
      if (exp_equiv_p (x, y, 0, 1))
	return 1;
    }

  /* X does not match, so try its subexpressions.  */

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    if (fmt[i] == 'e')
      {
	if (i == 0)
	  {
	    x = XEXP (x, 0);
	    goto repeat;
	  }
	else
	  if (refers_to_p (XEXP (x, i), y))
	    return 1;
      }
    else if (fmt[i] == 'E')
      {
	int j;
	for (j = 0; j < XVECLEN (x, i); j++)
	  if (refers_to_p (XVECEXP (x, i, j), y))
	    return 1;
      }

  return 0;
}

/* Given ADDR and SIZE (a memory address, and the size of the memory reference),
   set PBASE, PSTART, and PEND which correspond to the base of the address,
   the starting offset, and ending offset respectively.

   ADDR is known to be a nonvarying address.  */

/* ??? Despite what the comments say, this function is in fact frequently
   passed varying addresses.  This does not appear to cause any problems.  */

static void
set_nonvarying_address_components (addr, size, pbase, pstart, pend)
     rtx addr;
     int size;
     rtx *pbase;
     HOST_WIDE_INT *pstart, *pend;
{
  rtx base;
  HOST_WIDE_INT start, end;

  base = addr;
  start = 0;
  end = 0;

  if (flag_pic && GET_CODE (base) == PLUS
      && XEXP (base, 0) == pic_offset_table_rtx)
    base = XEXP (base, 1);

  /* Registers with nonvarying addresses usually have constant equivalents;
     but the frame pointer register is also possible.  */
  if (GET_CODE (base) == REG
      && qty_const != 0
      && REGNO_QTY_VALID_P (REGNO (base))
      && qty_mode[REG_QTY (REGNO (base))] == GET_MODE (base)
      && qty_const[REG_QTY (REGNO (base))] != 0)
    base = qty_const[REG_QTY (REGNO (base))];
  else if (GET_CODE (base) == PLUS
	   && GET_CODE (XEXP (base, 1)) == CONST_INT
	   && GET_CODE (XEXP (base, 0)) == REG
	   && qty_const != 0
	   && REGNO_QTY_VALID_P (REGNO (XEXP (base, 0)))
	   && (qty_mode[REG_QTY (REGNO (XEXP (base, 0)))]
	       == GET_MODE (XEXP (base, 0)))
	   && qty_const[REG_QTY (REGNO (XEXP (base, 0)))])
    {
      start = INTVAL (XEXP (base, 1));
      base = qty_const[REG_QTY (REGNO (XEXP (base, 0)))];
    }
  /* This can happen as the result of virtual register instantiation,
     if the initial offset is too large to be a valid address.  */
  else if (GET_CODE (base) == PLUS
	   && GET_CODE (XEXP (base, 0)) == REG
	   && GET_CODE (XEXP (base, 1)) == REG
	   && qty_const != 0
	   && REGNO_QTY_VALID_P (REGNO (XEXP (base, 0)))
	   && (qty_mode[REG_QTY (REGNO (XEXP (base, 0)))]
	       == GET_MODE (XEXP (base, 0)))
	   && qty_const[REG_QTY (REGNO (XEXP (base, 0)))]
	   && REGNO_QTY_VALID_P (REGNO (XEXP (base, 1)))
	   && (qty_mode[REG_QTY (REGNO (XEXP (base, 1)))]
	       == GET_MODE (XEXP (base, 1)))
	   && qty_const[REG_QTY (REGNO (XEXP (base, 1)))])
    {
      rtx tem = qty_const[REG_QTY (REGNO (XEXP (base, 1)))];
      base = qty_const[REG_QTY (REGNO (XEXP (base, 0)))];

      /* One of the two values must be a constant.  */
      if (GET_CODE (base) != CONST_INT)
	{
	  if (GET_CODE (tem) != CONST_INT)
	    abort ();
	  start = INTVAL (tem);
	}
      else
	{
	  start = INTVAL (base);
	  base = tem;
	}
    }

  /* Handle everything that we can find inside an address that has been
     viewed as constant.  */

  while (1)
    {
      /* If no part of this switch does a "continue", the code outside
	 will exit this loop.  */

      switch (GET_CODE (base))
	{
	case LO_SUM:
	  /* By definition, operand1 of a LO_SUM is the associated constant
	     address.  Use the associated constant address as the base
	     instead.  */
	  base = XEXP (base, 1);
	  continue;

	case CONST:
	  /* Strip off CONST.  */
	  base = XEXP (base, 0);
	  continue;

	case PLUS:
	  if (GET_CODE (XEXP (base, 1)) == CONST_INT)
	    {
	      start += INTVAL (XEXP (base, 1));
	      base = XEXP (base, 0);
	      continue;
	    }
	  break;

	case AND:
	  /* Handle the case of an AND which is the negative of a power of
	     two.  This is used to represent unaligned memory operations.  */
	  if (GET_CODE (XEXP (base, 1)) == CONST_INT
	      && exact_log2 (- INTVAL (XEXP (base, 1))) > 0)
	    {
	      set_nonvarying_address_components (XEXP (base, 0), size,
						 pbase, pstart, pend);

	      /* Assume the worst misalignment.  START is affected, but not
		 END, so compensate but adjusting SIZE.  Don't lose any
		 constant we already had.  */

	      size = *pend - *pstart - INTVAL (XEXP (base, 1)) - 1;
	      start += *pstart + INTVAL (XEXP (base, 1)) + 1;
	      end += *pend;
	      base = *pbase;
	    }
	  break;

	default:
	  break;
	}

      break;
    }

  if (GET_CODE (base) == CONST_INT)
    {
      start += INTVAL (base);
      base = const0_rtx;
    }

  end = start + size;

  /* Set the return values.  */
  *pbase = base;
  *pstart = start;
  *pend = end;
}

/* 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 (x)
     register rtx x;
{
  /* 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))
      && GET_MODE (x) == qty_mode[REG_QTY (REGNO (x))]
      && qty_const[REG_QTY (REGNO (x))] != 0)
    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)))
      && (GET_MODE (XEXP (x, 0))
	  == qty_mode[REG_QTY (REGNO (XEXP (x, 0)))])
      && qty_const[REG_QTY (REGNO (XEXP (x, 0)))])
    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)))
      && (GET_MODE (XEXP (x, 0))
	  == qty_mode[REG_QTY (REGNO (XEXP (x, 0)))])
      && qty_const[REG_QTY (REGNO (XEXP (x, 0)))]
      && REGNO_QTY_VALID_P (REGNO (XEXP (x, 1)))
      && (GET_MODE (XEXP (x, 1))
	  == qty_mode[REG_QTY (REGNO (XEXP (x, 1)))])
      && qty_const[REG_QTY (REGNO (XEXP (x, 1)))])
    return 0;

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

   If INSN is non-zero 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 non-zero
   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 (x, insn)
     rtx x;
     rtx insn;
{
  register int i;
  register enum rtx_code code;
  register 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 SYMBOL_REF:
    case LABEL_REF:
    case ADDR_VEC:
    case ADDR_DIFF_VEC:
      return x;

    case REG:
      {
	register int first;

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

	first = qty_first_reg[REG_QTY (REGNO (x))];
	return (first >= FIRST_PSEUDO_REGISTER ? regno_reg_rtx[first]
		: REGNO_REG_CLASS (first) == NO_REGS ? x
		: gen_rtx_REG (qty_mode[REG_QTY (REGNO (x))], first));
      }
      
    default:
      break;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      register 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_n_dups[insn_code] > 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 the configuration macro `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 (insn, loc)
     rtx insn;
     rtx *loc;
{
  struct table_elt *elt;
  rtx addr = *loc;
#ifdef ADDRESS_COST
  struct table_elt *p;
  int found_better = 1;
#endif
  int save_do_not_record = do_not_record;
  int save_hash_arg_in_memory = hash_arg_in_memory;
  int save_hash_arg_in_struct = hash_arg_in_struct;
  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);

      if (1
#ifdef ADDRESS_COST
	  && (CSE_ADDRESS_COST (folded) < CSE_ADDRESS_COST (addr)
	      || (CSE_ADDRESS_COST (folded) == CSE_ADDRESS_COST (addr)
		  && rtx_cost (folded, MEM) > rtx_cost (addr, MEM)))
#else
	  && rtx_cost (folded, MEM) < rtx_cost (addr, MEM)
#endif
	  && 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;
  hash_arg_in_struct = save_hash_arg_in_struct;

  if (addr_volatile)
    return;

  elt = lookup (addr, hash, Pmode);

#ifndef ADDRESS_COST
  if (elt)
    {
      int our_cost = elt->cost;

      /* Find the lowest cost below ours that works.  */
      for (elt = elt->first_same_value; elt; elt = elt->next_same_value)
	if (elt->cost < our_cost
	    && (GET_CODE (elt->exp) == REG
		|| exp_equiv_p (elt->exp, elt->exp, 1, 0))
	    && validate_change (insn, loc,
				canon_reg (copy_rtx (elt->exp), NULL_RTX), 0))
	  return;
    }
#else

  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 = CSE_ADDRESS_COST (*loc);
	  int best_rtx_cost = (elt->cost + 1) >> 1;
	  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))
		    && (CSE_ADDRESS_COST (p->exp) < best_addr_cost
			|| (CSE_ADDRESS_COST (p->exp) == best_addr_cost
			    && (p->cost + 1) >> 1 > best_rtx_cost)))
		  {
		    found_better = 1;
		    best_addr_cost = CSE_ADDRESS_COST (p->exp);
		    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
      && GET_CODE (XEXP (*loc, 1)) == CONST_INT)
    {
      rtx c = 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;
      hash_arg_in_struct = save_hash_arg_in_struct;

      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 = CSE_ADDRESS_COST (*loc);
	  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 cse_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 = cse_gen_binary (GET_CODE (*loc), Pmode, p->exp, c);

		if ((CSE_ADDRESS_COST (new) < best_addr_cost
		    || (CSE_ADDRESS_COST (new) == best_addr_cost
			&& (COST (new) + 1) >> 1 > best_rtx_cost)))
		  {
		    found_better = 1;
		    best_addr_cost = CSE_ADDRESS_COST (new);
		    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;
	    }
	}
    }
#endif
}

/* 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 (code, parg1, parg2, pmode1, pmode2)
     enum rtx_code code;
     rtx *parg1, *parg2;
     enum machine_mode *pmode1, *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 non-zero 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)) == '<')
	{
	  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
		  && FLOAT_STORE_FLAG_VALUE < 0)
#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
		       && FLOAT_STORE_FLAG_VALUE < 0)
#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)) % NBUCKETS,
		    GET_MODE (arg1));
      if (p) p = p->first_same_value;

      for (; p; p = p->next_same_value)
	{
	  enum machine_mode inner_mode = GET_MODE (p->exp);

	  /* 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
		       && FLOAT_STORE_FLAG_VALUE < 0)
#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
			&& FLOAT_STORE_FLAG_VALUE < 0)
#endif
		    )
		   && GET_RTX_CLASS (GET_CODE (p->exp)) == '<')
	    {
	      reverse_code = 1;
	      x = p->exp;
	      break;
	    }

	  /* If this is fp + constant, the equivalent is a better operand since
	     it may let us predict the value of the comparison.  */
	  else if (NONZERO_BASE_PLUS_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;

      arg1 = XEXP (x, 0),  arg2 = XEXP (x, 1);
      if (GET_RTX_CLASS (GET_CODE (x)) == '<')
	code = GET_CODE (x);

      if (reverse_code)
	code = reverse_condition (code);
    }

  /* 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;
}

/* Try to simplify a unary operation CODE whose output mode is to be
   MODE with input operand OP whose mode was originally OP_MODE.
   Return zero if no simplification can be made.  */

rtx
simplify_unary_operation (code, mode, op, op_mode)
     enum rtx_code code;
     enum machine_mode mode;
     rtx op;
     enum machine_mode op_mode;
{
  register int width = GET_MODE_BITSIZE (mode);

  /* The order of these tests is critical so that, for example, we don't
     check the wrong mode (input vs. output) for a conversion operation,
     such as FIX.  At some point, this should be simplified.  */

#if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)

  if (code == FLOAT && GET_MODE (op) == VOIDmode
      && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
    {
      HOST_WIDE_INT hv, lv;
      REAL_VALUE_TYPE d;

      if (GET_CODE (op) == CONST_INT)
	lv = INTVAL (op), hv = INTVAL (op) < 0 ? -1 : 0;
      else
	lv = CONST_DOUBLE_LOW (op),  hv = CONST_DOUBLE_HIGH (op);

#ifdef REAL_ARITHMETIC
      REAL_VALUE_FROM_INT (d, lv, hv, mode);
#else
      if (hv < 0)
	{
	  d = (double) (~ hv);
	  d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
		* (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
	  d += (double) (unsigned HOST_WIDE_INT) (~ lv);
	  d = (- d - 1.0);
	}
      else
	{
	  d = (double) hv;
	  d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
		* (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
	  d += (double) (unsigned HOST_WIDE_INT) lv;
	}
#endif  /* REAL_ARITHMETIC */
      d = real_value_truncate (mode, d);
      return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
    }
  else if (code == UNSIGNED_FLOAT && GET_MODE (op) == VOIDmode
	   && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
    {
      HOST_WIDE_INT hv, lv;
      REAL_VALUE_TYPE d;

      if (GET_CODE (op) == CONST_INT)
	lv = INTVAL (op), hv = INTVAL (op) < 0 ? -1 : 0;
      else
	lv = CONST_DOUBLE_LOW (op),  hv = CONST_DOUBLE_HIGH (op);

      if (op_mode == VOIDmode)
	{
	  /* We don't know how to interpret negative-looking numbers in
	     this case, so don't try to fold those.  */
	  if (hv < 0)
	    return 0;
	}
      else if (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT * 2)
	;
      else
	hv = 0, lv &= GET_MODE_MASK (op_mode);

#ifdef REAL_ARITHMETIC
      REAL_VALUE_FROM_UNSIGNED_INT (d, lv, hv, mode);
#else

      d = (double) (unsigned HOST_WIDE_INT) hv;
      d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
	    * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
      d += (double) (unsigned HOST_WIDE_INT) lv;
#endif  /* REAL_ARITHMETIC */
      d = real_value_truncate (mode, d);
      return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
    }
#endif

  if (GET_CODE (op) == CONST_INT
      && width <= HOST_BITS_PER_WIDE_INT && width > 0)
    {
      register HOST_WIDE_INT arg0 = INTVAL (op);
      register HOST_WIDE_INT val;

      switch (code)
	{
	case NOT:
	  val = ~ arg0;
	  break;

	case NEG:
	  val = - arg0;
	  break;

	case ABS:
	  val = (arg0 >= 0 ? arg0 : - arg0);
	  break;

	case FFS:
	  /* Don't use ffs here.  Instead, get low order bit and then its
	     number.  If arg0 is zero, this will return 0, as desired.  */
	  arg0 &= GET_MODE_MASK (mode);
	  val = exact_log2 (arg0 & (- arg0)) + 1;
	  break;

	case TRUNCATE:
	  val = arg0;
	  break;

	case ZERO_EXTEND:
	  if (op_mode == VOIDmode)
	    op_mode = mode;
	  if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
	    {
	      /* If we were really extending the mode,
		 we would have to distinguish between zero-extension
		 and sign-extension.  */
	      if (width != GET_MODE_BITSIZE (op_mode))
		abort ();
	      val = arg0;
	    }
	  else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
	    val = arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode));
	  else
	    return 0;
	  break;

	case SIGN_EXTEND:
	  if (op_mode == VOIDmode)
	    op_mode = mode;
	  if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
	    {
	      /* If we were really extending the mode,
		 we would have to distinguish between zero-extension
		 and sign-extension.  */
	      if (width != GET_MODE_BITSIZE (op_mode))
		abort ();
	      val = arg0;
	    }
	  else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
	    {
	      val
		= arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode));
	      if (val
		  & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (op_mode) - 1)))
		val -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
	    }
	  else
	    return 0;
	  break;

	case SQRT:
	  return 0;

	default:
	  abort ();
	}

      /* Clear the bits that don't belong in our mode,
	 unless they and our sign bit are all one.
	 So we get either a reasonable negative value or a reasonable
	 unsigned value for this mode.  */
      if (width < HOST_BITS_PER_WIDE_INT
	  && ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
	      != ((HOST_WIDE_INT) (-1) << (width - 1))))
	val &= ((HOST_WIDE_INT) 1 << width) - 1;

      /* If this would be an entire word for the target, but is not for
	 the host, then sign-extend on the host so that the number will look
	 the same way on the host that it would on the target.

	 For example, when building a 64 bit alpha hosted 32 bit sparc
	 targeted compiler, then we want the 32 bit unsigned value -1 to be
	 represented as a 64 bit value -1, and not as 0x00000000ffffffff.
	 The later confuses the sparc backend.  */

      if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
	  && (val & ((HOST_WIDE_INT) 1 << (width - 1))))
	val |= ((HOST_WIDE_INT) (-1) << width);

      return GEN_INT (val);
    }

  /* We can do some operations on integer CONST_DOUBLEs.  Also allow
     for a DImode operation on a CONST_INT.  */
  else if (GET_MODE (op) == VOIDmode && width <= HOST_BITS_PER_INT * 2
	   && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
    {
      HOST_WIDE_INT l1, h1, lv, hv;

      if (GET_CODE (op) == CONST_DOUBLE)
	l1 = CONST_DOUBLE_LOW (op), h1 = CONST_DOUBLE_HIGH (op);
      else
	l1 = INTVAL (op), h1 = l1 < 0 ? -1 : 0;

      switch (code)
	{
	case NOT:
	  lv = ~ l1;
	  hv = ~ h1;
	  break;

	case NEG:
	  neg_double (l1, h1, &lv, &hv);
	  break;

	case ABS:
	  if (h1 < 0)
	    neg_double (l1, h1, &lv, &hv);
	  else
	    lv = l1, hv = h1;
	  break;

	case FFS:
	  hv = 0;
	  if (l1 == 0)
	    lv = HOST_BITS_PER_WIDE_INT + exact_log2 (h1 & (-h1)) + 1;
	  else
	    lv = exact_log2 (l1 & (-l1)) + 1;
	  break;

	case TRUNCATE:
	  /* This is just a change-of-mode, so do nothing.  */
	  lv = l1, hv = h1;
	  break;

	case ZERO_EXTEND:
	  if (op_mode == VOIDmode
	      || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
	    return 0;

	  hv = 0;
	  lv = l1 & GET_MODE_MASK (op_mode);
	  break;

	case SIGN_EXTEND:
	  if (op_mode == VOIDmode
	      || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
	    return 0;
	  else
	    {
	      lv = l1 & GET_MODE_MASK (op_mode);
	      if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT
		  && (lv & ((HOST_WIDE_INT) 1
			    << (GET_MODE_BITSIZE (op_mode) - 1))) != 0)
		lv -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);

	      hv = (lv < 0) ? ~ (HOST_WIDE_INT) 0 : 0;
	    }
	  break;

	case SQRT:
	  return 0;

	default:
	  return 0;
	}

      return immed_double_const (lv, hv, mode);
    }

#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
  else if (GET_CODE (op) == CONST_DOUBLE
	   && GET_MODE_CLASS (mode) == MODE_FLOAT)
    {
      REAL_VALUE_TYPE d;
      jmp_buf handler;
      rtx x;

      if (setjmp (handler))
	/* There used to be a warning here, but that is inadvisable.
	   People may want to cause traps, and the natural way
	   to do it should not get a warning.  */
	return 0;

      set_float_handler (handler);

      REAL_VALUE_FROM_CONST_DOUBLE (d, op);

      switch (code)
	{
	case NEG:
	  d = REAL_VALUE_NEGATE (d);
	  break;

	case ABS:
	  if (REAL_VALUE_NEGATIVE (d))
	    d = REAL_VALUE_NEGATE (d);
	  break;

	case FLOAT_TRUNCATE:
	  d = real_value_truncate (mode, d);
	  break;

	case FLOAT_EXTEND:
	  /* All this does is change the mode.  */
	  break;

	case FIX:
	  d = REAL_VALUE_RNDZINT (d);
	  break;

	case UNSIGNED_FIX:
	  d = REAL_VALUE_UNSIGNED_RNDZINT (d);
	  break;

	case SQRT:
	  return 0;

	default:
	  abort ();
	}

      x = CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
      set_float_handler (NULL_PTR);
      return x;
    }

  else if (GET_CODE (op) == CONST_DOUBLE
	   && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
	   && GET_MODE_CLASS (mode) == MODE_INT
	   && width <= HOST_BITS_PER_WIDE_INT && width > 0)
    {
      REAL_VALUE_TYPE d;
      jmp_buf handler;
      HOST_WIDE_INT val;

      if (setjmp (handler))
	return 0;

      set_float_handler (handler);

      REAL_VALUE_FROM_CONST_DOUBLE (d, op);

      switch (code)
	{
	case FIX:
	  val = REAL_VALUE_FIX (d);
	  break;

	case UNSIGNED_FIX:
	  val = REAL_VALUE_UNSIGNED_FIX (d);
	  break;

	default:
	  abort ();
	}

      set_float_handler (NULL_PTR);

      /* Clear the bits that don't belong in our mode,
	 unless they and our sign bit are all one.
	 So we get either a reasonable negative value or a reasonable
	 unsigned value for this mode.  */
      if (width < HOST_BITS_PER_WIDE_INT
	  && ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
	      != ((HOST_WIDE_INT) (-1) << (width - 1))))
	val &= ((HOST_WIDE_INT) 1 << width) - 1;

      /* If this would be an entire word for the target, but is not for
	 the host, then sign-extend on the host so that the number will look
	 the same way on the host that it would on the target.

	 For example, when building a 64 bit alpha hosted 32 bit sparc
	 targeted compiler, then we want the 32 bit unsigned value -1 to be
	 represented as a 64 bit value -1, and not as 0x00000000ffffffff.
	 The later confuses the sparc backend.  */

      if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
	  && (val & ((HOST_WIDE_INT) 1 << (width - 1))))
	val |= ((HOST_WIDE_INT) (-1) << width);

      return GEN_INT (val);
    }
#endif
  /* This was formerly used only for non-IEEE float.
     eggert@twinsun.com says it is safe for IEEE also.  */
  else
    {
      /* There are some simplifications we can do even if the operands
	 aren't constant.  */
      switch (code)
	{
	case NEG:
	case NOT:
	  /* (not (not X)) == X, similarly for NEG.  */
	  if (GET_CODE (op) == code)
	    return XEXP (op, 0);
	  break;

	case SIGN_EXTEND:
	  /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
	     becomes just the MINUS if its mode is MODE.  This allows
	     folding switch statements on machines using casesi (such as
	     the Vax).  */
	  if (GET_CODE (op) == TRUNCATE
	      && GET_MODE (XEXP (op, 0)) == mode
	      && GET_CODE (XEXP (op, 0)) == MINUS
	      && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
	      && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
	    return XEXP (op, 0);

#ifdef POINTERS_EXTEND_UNSIGNED
	  if (! POINTERS_EXTEND_UNSIGNED
	      && mode == Pmode && GET_MODE (op) == ptr_mode
	      && CONSTANT_P (op))
	    return convert_memory_address (Pmode, op);
#endif
	  break;

#ifdef POINTERS_EXTEND_UNSIGNED
	case ZERO_EXTEND:
	  if (POINTERS_EXTEND_UNSIGNED
	      && mode == Pmode && GET_MODE (op) == ptr_mode
	      && CONSTANT_P (op))
	    return convert_memory_address (Pmode, op);
	  break;
#endif
	  
	default:
	  break;
	}

      return 0;
    }
}

/* Simplify a binary operation CODE with result mode MODE, operating on OP0
   and OP1.  Return 0 if no simplification is possible.

   Don't use this for relational operations such as EQ or LT.
   Use simplify_relational_operation instead.  */

rtx
simplify_binary_operation (code, mode, op0, op1)
     enum rtx_code code;
     enum machine_mode mode;
     rtx op0, op1;
{
  register HOST_WIDE_INT arg0, arg1, arg0s, arg1s;
  HOST_WIDE_INT val;
  int width = GET_MODE_BITSIZE (mode);
  rtx tem;

  /* Relational operations don't work here.  We must know the mode
     of the operands in order to do the comparison correctly.
     Assuming a full word can give incorrect results.
     Consider comparing 128 with -128 in QImode.  */

  if (GET_RTX_CLASS (code) == '<')
    abort ();

#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
  if (GET_MODE_CLASS (mode) == MODE_FLOAT
      && GET_CODE (op0) == CONST_DOUBLE && GET_CODE (op1) == CONST_DOUBLE
      && mode == GET_MODE (op0) && mode == GET_MODE (op1))
    {
      REAL_VALUE_TYPE f0, f1, value;
      jmp_buf handler;

      if (setjmp (handler))
	return 0;

      set_float_handler (handler);

      REAL_VALUE_FROM_CONST_DOUBLE (f0, op0);
      REAL_VALUE_FROM_CONST_DOUBLE (f1, op1);
      f0 = real_value_truncate (mode, f0);
      f1 = real_value_truncate (mode, f1);

#ifdef REAL_ARITHMETIC
#ifndef REAL_INFINITY
      if (code == DIV && REAL_VALUES_EQUAL (f1, dconst0))
	return 0;
#endif
      REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1);
#else
      switch (code)
	{
	case PLUS:
	  value = f0 + f1;
	  break;
	case MINUS:
	  value = f0 - f1;
	  break;
	case MULT:
	  value = f0 * f1;
	  break;
	case DIV:
#ifndef REAL_INFINITY
	  if (f1 == 0)
	    return 0;
#endif
	  value = f0 / f1;
	  break;
	case SMIN:
	  value = MIN (f0, f1);
	  break;
	case SMAX:
	  value = MAX (f0, f1);
	  break;
	default:
	  abort ();
	}
#endif

      value = real_value_truncate (mode, value);
      set_float_handler (NULL_PTR);
      return CONST_DOUBLE_FROM_REAL_VALUE (value, mode);
    }
#endif  /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */

  /* We can fold some multi-word operations.  */
  if (GET_MODE_CLASS (mode) == MODE_INT
      && width == HOST_BITS_PER_WIDE_INT * 2
      && (GET_CODE (op0) == CONST_DOUBLE || GET_CODE (op0) == CONST_INT)
      && (GET_CODE (op1) == CONST_DOUBLE || GET_CODE (op1) == CONST_INT))
    {
      HOST_WIDE_INT l1, l2, h1, h2, lv, hv;

      if (GET_CODE (op0) == CONST_DOUBLE)
	l1 = CONST_DOUBLE_LOW (op0), h1 = CONST_DOUBLE_HIGH (op0);
      else
	l1 = INTVAL (op0), h1 = l1 < 0 ? -1 : 0;

      if (GET_CODE (op1) == CONST_DOUBLE)
	l2 = CONST_DOUBLE_LOW (op1), h2 = CONST_DOUBLE_HIGH (op1);
      else
	l2 = INTVAL (op1), h2 = l2 < 0 ? -1 : 0;

      switch (code)
	{
	case MINUS:
	  /* A - B == A + (-B).  */
	  neg_double (l2, h2, &lv, &hv);
	  l2 = lv, h2 = hv;

	  /* .. fall through ...  */

	case PLUS:
	  add_double (l1, h1, l2, h2, &lv, &hv);
	  break;

	case MULT:
	  mul_double (l1, h1, l2, h2, &lv, &hv);
	  break;

	case DIV:  case MOD:   case UDIV:  case UMOD:
	  /* We'd need to include tree.h to do this and it doesn't seem worth
	     it.  */
	  return 0;

	case AND:
	  lv = l1 & l2, hv = h1 & h2;
	  break;

	case IOR:
	  lv = l1 | l2, hv = h1 | h2;
	  break;

	case XOR:
	  lv = l1 ^ l2, hv = h1 ^ h2;
	  break;

	case SMIN:
	  if (h1 < h2
	      || (h1 == h2
		  && ((unsigned HOST_WIDE_INT) l1
		      < (unsigned HOST_WIDE_INT) l2)))
	    lv = l1, hv = h1;
	  else
	    lv = l2, hv = h2;
	  break;

	case SMAX:
	  if (h1 > h2
	      || (h1 == h2
		  && ((unsigned HOST_WIDE_INT) l1
		      > (unsigned HOST_WIDE_INT) l2)))
	    lv = l1, hv = h1;
	  else
	    lv = l2, hv = h2;
	  break;

	case UMIN:
	  if ((unsigned HOST_WIDE_INT) h1 < (unsigned HOST_WIDE_INT) h2
	      || (h1 == h2
		  && ((unsigned HOST_WIDE_INT) l1
		      < (unsigned HOST_WIDE_INT) l2)))
	    lv = l1, hv = h1;
	  else
	    lv = l2, hv = h2;
	  break;

	case UMAX:
	  if ((unsigned HOST_WIDE_INT) h1 > (unsigned HOST_WIDE_INT) h2
	      || (h1 == h2
		  && ((unsigned HOST_WIDE_INT) l1
		      > (unsigned HOST_WIDE_INT) l2)))
	    lv = l1, hv = h1;
	  else
	    lv = l2, hv = h2;
	  break;

	case LSHIFTRT:   case ASHIFTRT:
	case ASHIFT:
	case ROTATE:     case ROTATERT:
#ifdef SHIFT_COUNT_TRUNCATED
	  if (SHIFT_COUNT_TRUNCATED)
	    l2 &= (GET_MODE_BITSIZE (mode) - 1), h2 = 0;
#endif

	  if (h2 != 0 || l2 < 0 || l2 >= GET_MODE_BITSIZE (mode))
	    return 0;

	  if (code == LSHIFTRT || code == ASHIFTRT)
	    rshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv,
			   code == ASHIFTRT);
	  else if (code == ASHIFT)
	    lshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv, 1);
	  else if (code == ROTATE)
	    lrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
	  else /* code == ROTATERT */
	    rrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
	  break;

	default:
	  return 0;
	}

      return immed_double_const (lv, hv, mode);
    }

  if (GET_CODE (op0) != CONST_INT || GET_CODE (op1) != CONST_INT
      || width > HOST_BITS_PER_WIDE_INT || width == 0)
    {
      /* Even if we can't compute a constant result,
	 there are some cases worth simplifying.  */

      switch (code)
	{
	case PLUS:
	  /* In IEEE floating point, x+0 is not the same as x.  Similarly
	     for the other optimizations below.  */
	  if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
	      && FLOAT_MODE_P (mode) && ! flag_fast_math)
	    break;

	  if (op1 == CONST0_RTX (mode))
	    return op0;

	  /* ((-a) + b) -> (b - a) and similarly for (a + (-b)) */
	  if (GET_CODE (op0) == NEG)
	    return cse_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
	  else if (GET_CODE (op1) == NEG)
	    return cse_gen_binary (MINUS, mode, op0, XEXP (op1, 0));

	  /* Handle both-operands-constant cases.  We can only add
	     CONST_INTs to constants since the sum of relocatable symbols
	     can't be handled by most assemblers.  Don't add CONST_INT
	     to CONST_INT since overflow won't be computed properly if wider
	     than HOST_BITS_PER_WIDE_INT.  */

	  if (CONSTANT_P (op0) && GET_MODE (op0) != VOIDmode
	      && GET_CODE (op1) == CONST_INT)
	    return plus_constant (op0, INTVAL (op1));
	  else if (CONSTANT_P (op1) && GET_MODE (op1) != VOIDmode
		   && GET_CODE (op0) == CONST_INT)
	    return plus_constant (op1, INTVAL (op0));

	  /* See if this is something like X * C - X or vice versa or
	     if the multiplication is written as a shift.  If so, we can
	     distribute and make a new multiply, shift, or maybe just
	     have X (if C is 2 in the example above).  But don't make
	     real multiply if we didn't have one before.  */

	  if (! FLOAT_MODE_P (mode))
	    {
	      HOST_WIDE_INT coeff0 = 1, coeff1 = 1;
	      rtx lhs = op0, rhs = op1;
	      int had_mult = 0;

	      if (GET_CODE (lhs) == NEG)
		coeff0 = -1, lhs = XEXP (lhs, 0);
	      else if (GET_CODE (lhs) == MULT
		       && GET_CODE (XEXP (lhs, 1)) == CONST_INT)
		{
		  coeff0 = INTVAL (XEXP (lhs, 1)), lhs = XEXP (lhs, 0);
		  had_mult = 1;
		}
	      else if (GET_CODE (lhs) == ASHIFT
		       && GET_CODE (XEXP (lhs, 1)) == CONST_INT
		       && INTVAL (XEXP (lhs, 1)) >= 0
		       && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
		{
		  coeff0 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
		  lhs = XEXP (lhs, 0);
		}

	      if (GET_CODE (rhs) == NEG)
		coeff1 = -1, rhs = XEXP (rhs, 0);
	      else if (GET_CODE (rhs) == MULT
		       && GET_CODE (XEXP (rhs, 1)) == CONST_INT)
		{
		  coeff1 = INTVAL (XEXP (rhs, 1)), rhs = XEXP (rhs, 0);
		  had_mult = 1;
		}
	      else if (GET_CODE (rhs) == ASHIFT
		       && GET_CODE (XEXP (rhs, 1)) == CONST_INT
		       && INTVAL (XEXP (rhs, 1)) >= 0
		       && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
		{
		  coeff1 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1));
		  rhs = XEXP (rhs, 0);
		}

	      if (rtx_equal_p (lhs, rhs))
		{
		  tem = cse_gen_binary (MULT, mode, lhs,
					GEN_INT (coeff0 + coeff1));
		  return (GET_CODE (tem) == MULT && ! had_mult) ? 0 : tem;
		}
	    }

	  /* If one of the operands is a PLUS or a MINUS, see if we can
	     simplify this by the associative law. 
	     Don't use the associative law for floating point.
	     The inaccuracy makes it nonassociative,
	     and subtle programs can break if operations are associated.  */

	  if (INTEGRAL_MODE_P (mode)
	      && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
		  || GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS)
	      && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
	    return tem;
	  break;

	case COMPARE:
#ifdef HAVE_cc0
	  /* Convert (compare FOO (const_int 0)) to FOO unless we aren't
	     using cc0, in which case we want to leave it as a COMPARE
	     so we can distinguish it from a register-register-copy.

	     In IEEE floating point, x-0 is not the same as x.  */

	  if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
	       || ! FLOAT_MODE_P (mode) || flag_fast_math)
	      && op1 == CONST0_RTX (mode))
	    return op0;
#else
	  /* Do nothing here.  */
#endif
	  break;
	      
	case MINUS:
	  /* None of these optimizations can be done for IEEE
	     floating point.  */
	  if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
	      && FLOAT_MODE_P (mode) && ! flag_fast_math)
	    break;

	  /* We can't assume x-x is 0 even with non-IEEE floating point,
	     but since it is zero except in very strange circumstances, we
	     will treat it as zero with -ffast-math.  */
	  if (rtx_equal_p (op0, op1)
	      && ! side_effects_p (op0)
	      && (! FLOAT_MODE_P (mode) || flag_fast_math))
	    return CONST0_RTX (mode);

	  /* Change subtraction from zero into negation.  */
	  if (op0 == CONST0_RTX (mode))
	    return gen_rtx_NEG (mode, op1);

	  /* (-1 - a) is ~a.  */
	  if (op0 == constm1_rtx)
	    return gen_rtx_NOT (mode, op1);

	  /* Subtracting 0 has no effect.  */
	  if (op1 == CONST0_RTX (mode))
	    return op0;

	  /* See if this is something like X * C - X or vice versa or
	     if the multiplication is written as a shift.  If so, we can
	     distribute and make a new multiply, shift, or maybe just
	     have X (if C is 2 in the example above).  But don't make
	     real multiply if we didn't have one before.  */

	  if (! FLOAT_MODE_P (mode))
	    {
	      HOST_WIDE_INT coeff0 = 1, coeff1 = 1;
	      rtx lhs = op0, rhs = op1;
	      int had_mult = 0;

	      if (GET_CODE (lhs) == NEG)
		coeff0 = -1, lhs = XEXP (lhs, 0);
	      else if (GET_CODE (lhs) == MULT
		       && GET_CODE (XEXP (lhs, 1)) == CONST_INT)
		{
		  coeff0 = INTVAL (XEXP (lhs, 1)), lhs = XEXP (lhs, 0);
		  had_mult = 1;
		}
	      else if (GET_CODE (lhs) == ASHIFT
		       && GET_CODE (XEXP (lhs, 1)) == CONST_INT
		       && INTVAL (XEXP (lhs, 1)) >= 0
		       && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
		{
		  coeff0 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
		  lhs = XEXP (lhs, 0);
		}

	      if (GET_CODE (rhs) == NEG)
		coeff1 = - 1, rhs = XEXP (rhs, 0);
	      else if (GET_CODE (rhs) == MULT
		       && GET_CODE (XEXP (rhs, 1)) == CONST_INT)
		{
		  coeff1 = INTVAL (XEXP (rhs, 1)), rhs = XEXP (rhs, 0);
		  had_mult = 1;
		}
	      else if (GET_CODE (rhs) == ASHIFT
		       && GET_CODE (XEXP (rhs, 1)) == CONST_INT
		       && INTVAL (XEXP (rhs, 1)) >= 0
		       && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
		{
		  coeff1 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1));
		  rhs = XEXP (rhs, 0);
		}

	      if (rtx_equal_p (lhs, rhs))
		{
		  tem = cse_gen_binary (MULT, mode, lhs,
					GEN_INT (coeff0 - coeff1));
		  return (GET_CODE (tem) == MULT && ! had_mult) ? 0 : tem;
		}
	    }

	  /* (a - (-b)) -> (a + b).  */
	  if (GET_CODE (op1) == NEG)
	    return cse_gen_binary (PLUS, mode, op0, XEXP (op1, 0));

	  /* If one of the operands is a PLUS or a MINUS, see if we can
	     simplify this by the associative law. 
	     Don't use the associative law for floating point.
	     The inaccuracy makes it nonassociative,
	     and subtle programs can break if operations are associated.  */

	  if (INTEGRAL_MODE_P (mode)
	      && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
		  || GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS)
	      && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
	    return tem;

	  /* Don't let a relocatable value get a negative coeff.  */
	  if (GET_CODE (op1) == CONST_INT && GET_MODE (op0) != VOIDmode)
	    return plus_constant (op0, - INTVAL (op1));

	  /* (x - (x & y)) -> (x & ~y) */
	  if (GET_CODE (op1) == AND)
	    {
	     if (rtx_equal_p (op0, XEXP (op1, 0)))
	       return cse_gen_binary (AND, mode, op0, gen_rtx_NOT (mode, XEXP (op1, 1)));
	     if (rtx_equal_p (op0, XEXP (op1, 1)))
	       return cse_gen_binary (AND, mode, op0, gen_rtx_NOT (mode, XEXP (op1, 0)));
	   }
	  break;

	case MULT:
	  if (op1 == constm1_rtx)
	    {
	      tem = simplify_unary_operation (NEG, mode, op0, mode);

	      return tem ? tem : gen_rtx_NEG (mode, op0);
	    }

	  /* In IEEE floating point, x*0 is not always 0.  */
	  if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
	       || ! FLOAT_MODE_P (mode) || flag_fast_math)
	      && op1 == CONST0_RTX (mode)
	      && ! side_effects_p (op0))
	    return op1;

	  /* In IEEE floating point, x*1 is not equivalent to x for nans.
	     However, ANSI says we can drop signals,
	     so we can do this anyway.  */
	  if (op1 == CONST1_RTX (mode))
	    return op0;

	  /* Convert multiply by constant power of two into shift unless
	     we are still generating RTL.  This test is a kludge.  */
	  if (GET_CODE (op1) == CONST_INT
	      && (val = exact_log2 (INTVAL (op1))) >= 0
	      /* If the mode is larger than the host word size, and the
		 uppermost bit is set, then this isn't a power of two due
		 to implicit sign extension.  */
	      && (width <= HOST_BITS_PER_WIDE_INT
		  || val != HOST_BITS_PER_WIDE_INT - 1)
	      && ! rtx_equal_function_value_matters)
	    return gen_rtx_ASHIFT (mode, op0, GEN_INT (val));

	  if (GET_CODE (op1) == CONST_DOUBLE
	      && GET_MODE_CLASS (GET_MODE (op1)) == MODE_FLOAT)
	    {
	      REAL_VALUE_TYPE d;
	      jmp_buf handler;
	      int op1is2, op1ism1;

	      if (setjmp (handler))
		return 0;

	      set_float_handler (handler);
	      REAL_VALUE_FROM_CONST_DOUBLE (d, op1);
	      op1is2 = REAL_VALUES_EQUAL (d, dconst2);
	      op1ism1 = REAL_VALUES_EQUAL (d, dconstm1);
	      set_float_handler (NULL_PTR);

	      /* x*2 is x+x and x*(-1) is -x */
	      if (op1is2 && GET_MODE (op0) == mode)
		return gen_rtx_PLUS (mode, op0, copy_rtx (op0));

	      else if (op1ism1 && GET_MODE (op0) == mode)
		return gen_rtx_NEG (mode, op0);
	    }
	  break;

	case IOR:
	  if (op1 == const0_rtx)
	    return op0;
	  if (GET_CODE (op1) == CONST_INT
	      && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode))
	    return op1;
	  if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
	    return op0;
	  /* A | (~A) -> -1 */
	  if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
	       || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
	      && ! side_effects_p (op0)
	      && GET_MODE_CLASS (mode) != MODE_CC)
	    return constm1_rtx;
	  break;

	case XOR:
	  if (op1 == const0_rtx)
	    return op0;
	  if (GET_CODE (op1) == CONST_INT
	      && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode))
	    return gen_rtx_NOT (mode, op0);
	  if (op0 == op1 && ! side_effects_p (op0)
	      && GET_MODE_CLASS (mode) != MODE_CC)
	    return const0_rtx;
	  break;

	case AND:
	  if (op1 == const0_rtx && ! side_effects_p (op0))
	    return const0_rtx;
	  if (GET_CODE (op1) == CONST_INT
	      && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode))
	    return op0;
	  if (op0 == op1 && ! side_effects_p (op0)
	      && GET_MODE_CLASS (mode) != MODE_CC)
	    return op0;
	  /* A & (~A) -> 0 */
	  if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
	       || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
	      && ! side_effects_p (op0)
	      && GET_MODE_CLASS (mode) != MODE_CC)
	    return const0_rtx;
	  break;

	case UDIV:
	  /* Convert divide by power of two into shift (divide by 1 handled
	     below).  */
	  if (GET_CODE (op1) == CONST_INT
	      && (arg1 = exact_log2 (INTVAL (op1))) > 0)
	    return gen_rtx_LSHIFTRT (mode, op0, GEN_INT (arg1));

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

	case DIV:
	  if (op1 == CONST1_RTX (mode))
	    return op0;

	  /* In IEEE floating point, 0/x is not always 0.  */
	  if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
	       || ! FLOAT_MODE_P (mode) || flag_fast_math)
	      && op0 == CONST0_RTX (mode)
	      && ! side_effects_p (op1))
	    return op0;

#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
	  /* Change division by a constant into multiplication.  Only do
	     this with -ffast-math until an expert says it is safe in
	     general.  */
	  else if (GET_CODE (op1) == CONST_DOUBLE
		   && GET_MODE_CLASS (GET_MODE (op1)) == MODE_FLOAT
		   && op1 != CONST0_RTX (mode)
		   && flag_fast_math)
	    {
	      REAL_VALUE_TYPE d;
	      REAL_VALUE_FROM_CONST_DOUBLE (d, op1);

	      if (! REAL_VALUES_EQUAL (d, dconst0))
		{
#if defined (REAL_ARITHMETIC)
		  REAL_ARITHMETIC (d, rtx_to_tree_code (DIV), dconst1, d);
		  return gen_rtx_MULT (mode, op0, 
				       CONST_DOUBLE_FROM_REAL_VALUE (d, mode));
#else
		  return gen_rtx_MULT (mode, op0, 
				       CONST_DOUBLE_FROM_REAL_VALUE (1./d, mode));
#endif
		}
	    }
#endif
	  break;

	case UMOD:
	  /* Handle modulus by power of two (mod with 1 handled below).  */
	  if (GET_CODE (op1) == CONST_INT
	      && exact_log2 (INTVAL (op1)) > 0)
	    return gen_rtx_AND (mode, op0, GEN_INT (INTVAL (op1) - 1));

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

	case MOD:
	  if ((op0 == const0_rtx || op1 == const1_rtx)
	      && ! side_effects_p (op0) && ! side_effects_p (op1))
	    return const0_rtx;
	  break;

	case ROTATERT:
	case ROTATE:
	  /* Rotating ~0 always results in ~0.  */
	  if (GET_CODE (op0) == CONST_INT && width <= HOST_BITS_PER_WIDE_INT
	      && INTVAL (op0) == GET_MODE_MASK (mode)
	      && ! side_effects_p (op1))
	    return op0;

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

	case ASHIFT:
	case ASHIFTRT:
	case LSHIFTRT:
	  if (op1 == const0_rtx)
	    return op0;
	  if (op0 == const0_rtx && ! side_effects_p (op1))
	    return op0;
	  break;

	case SMIN:
	  if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (op1) == CONST_INT 
	      && INTVAL (op1) == (HOST_WIDE_INT) 1 << (width -1)
	      && ! side_effects_p (op0))
	    return op1;
	  else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
	    return op0;
	  break;
	   
	case SMAX:
	  if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (op1) == CONST_INT
	      && (INTVAL (op1)
		  == (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode) >> 1)
	      && ! side_effects_p (op0))
	    return op1;
	  else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
	    return op0;
	  break;

	case UMIN:
	  if (op1 == const0_rtx && ! side_effects_p (op0))
	    return op1;
	  else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
	    return op0;
	  break;
	    
	case UMAX:
	  if (op1 == constm1_rtx && ! side_effects_p (op0))
	    return op1;
	  else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
	    return op0;
	  break;

	default:
	  abort ();
	}
      
      return 0;
    }

  /* Get the integer argument values in two forms:
     zero-extended in ARG0, ARG1 and sign-extended in ARG0S, ARG1S.  */

  arg0 = INTVAL (op0);
  arg1 = INTVAL (op1);

  if (width < HOST_BITS_PER_WIDE_INT)
    {
      arg0 &= ((HOST_WIDE_INT) 1 << width) - 1;
      arg1 &= ((HOST_WIDE_INT) 1 << width) - 1;

      arg0s = arg0;
      if (arg0s & ((HOST_WIDE_INT) 1 << (width - 1)))
	arg0s |= ((HOST_WIDE_INT) (-1) << width);

      arg1s = arg1;
      if (arg1s & ((HOST_WIDE_INT) 1 << (width - 1)))
	arg1s |= ((HOST_WIDE_INT) (-1) << width);
    }
  else
    {
      arg0s = arg0;
      arg1s = arg1;
    }

  /* Compute the value of the arithmetic.  */

  switch (code)
    {
    case PLUS:
      val = arg0s + arg1s;
      break;

    case MINUS:
      val = arg0s - arg1s;
      break;

    case MULT:
      val = arg0s * arg1s;
      break;

    case DIV:
      if (arg1s == 0)
	return 0;
      val = arg0s / arg1s;
      break;

    case MOD:
      if (arg1s == 0)
	return 0;
      val = arg0s % arg1s;
      break;

    case UDIV:
      if (arg1 == 0)
	return 0;
      val = (unsigned HOST_WIDE_INT) arg0 / arg1;
      break;

    case UMOD:
      if (arg1 == 0)
	return 0;
      val = (unsigned HOST_WIDE_INT) arg0 % arg1;
      break;

    case AND:
      val = arg0 & arg1;
      break;

    case IOR:
      val = arg0 | arg1;
      break;

    case XOR:
      val = arg0 ^ arg1;
      break;

    case LSHIFTRT:
      /* If shift count is undefined, don't fold it; let the machine do
	 what it wants.  But truncate it if the machine will do that.  */
      if (arg1 < 0)
	return 0;

#ifdef SHIFT_COUNT_TRUNCATED
      if (SHIFT_COUNT_TRUNCATED)
	arg1 %= width;
#endif

      val = ((unsigned HOST_WIDE_INT) arg0) >> arg1;
      break;

    case ASHIFT:
      if (arg1 < 0)
	return 0;

#ifdef SHIFT_COUNT_TRUNCATED
      if (SHIFT_COUNT_TRUNCATED)
	arg1 %= width;
#endif

      val = ((unsigned HOST_WIDE_INT) arg0) << arg1;
      break;

    case ASHIFTRT:
      if (arg1 < 0)
	return 0;

#ifdef SHIFT_COUNT_TRUNCATED
      if (SHIFT_COUNT_TRUNCATED)
	arg1 %= width;
#endif

      val = arg0s >> arg1;

      /* Bootstrap compiler may not have sign extended the right shift.
	 Manually extend the sign to insure bootstrap cc matches gcc.  */
      if (arg0s < 0 && arg1 > 0)
	val |= ((HOST_WIDE_INT) -1) << (HOST_BITS_PER_WIDE_INT - arg1);

      break;

    case ROTATERT:
      if (arg1 < 0)
	return 0;

      arg1 %= width;
      val = ((((unsigned HOST_WIDE_INT) arg0) << (width - arg1))
	     | (((unsigned HOST_WIDE_INT) arg0) >> arg1));
      break;

    case ROTATE:
      if (arg1 < 0)
	return 0;

      arg1 %= width;
      val = ((((unsigned HOST_WIDE_INT) arg0) << arg1)
	     | (((unsigned HOST_WIDE_INT) arg0) >> (width - arg1)));
      break;

    case COMPARE:
      /* Do nothing here.  */
      return 0;

    case SMIN:
      val = arg0s <= arg1s ? arg0s : arg1s;
      break;

    case UMIN:
      val = ((unsigned HOST_WIDE_INT) arg0
	     <= (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
      break;

    case SMAX:
      val = arg0s > arg1s ? arg0s : arg1s;
      break;

    case UMAX:
      val = ((unsigned HOST_WIDE_INT) arg0
	     > (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
      break;

    default:
      abort ();
    }

  /* Clear the bits that don't belong in our mode, unless they and our sign
     bit are all one.  So we get either a reasonable negative value or a
     reasonable unsigned value for this mode.  */
  if (width < HOST_BITS_PER_WIDE_INT
      && ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
	  != ((HOST_WIDE_INT) (-1) << (width - 1))))
    val &= ((HOST_WIDE_INT) 1 << width) - 1;

  /* If this would be an entire word for the target, but is not for
     the host, then sign-extend on the host so that the number will look
     the same way on the host that it would on the target.

     For example, when building a 64 bit alpha hosted 32 bit sparc
     targeted compiler, then we want the 32 bit unsigned value -1 to be
     represented as a 64 bit value -1, and not as 0x00000000ffffffff.
     The later confuses the sparc backend.  */

  if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
      && (val & ((HOST_WIDE_INT) 1 << (width - 1))))
    val |= ((HOST_WIDE_INT) (-1) << width);

  return GEN_INT (val);
}

/* Simplify a PLUS or MINUS, at least one of whose operands may be another
   PLUS or MINUS.

   Rather than test for specific case, we do this by a brute-force method
   and do all possible simplifications until no more changes occur.  Then
   we rebuild the operation.  */

static rtx
simplify_plus_minus (code, mode, op0, op1)
     enum rtx_code code;
     enum machine_mode mode;
     rtx op0, op1;
{
  rtx ops[8];
  int negs[8];
  rtx result, tem;
  int n_ops = 2, input_ops = 2, input_consts = 0, n_consts = 0;
  int first = 1, negate = 0, changed;
  int i, j;

  bzero ((char *) ops, sizeof ops);
  
  /* Set up the two operands and then expand them until nothing has been
     changed.  If we run out of room in our array, give up; this should
     almost never happen.  */

  ops[0] = op0, ops[1] = op1, negs[0] = 0, negs[1] = (code == MINUS);

  changed = 1;
  while (changed)
    {
      changed = 0;

      for (i = 0; i < n_ops; i++)
	switch (GET_CODE (ops[i]))
	  {
	  case PLUS:
	  case MINUS:
	    if (n_ops == 7)
	      return 0;

	    ops[n_ops] = XEXP (ops[i], 1);
	    negs[n_ops++] = GET_CODE (ops[i]) == MINUS ? !negs[i] : negs[i];
	    ops[i] = XEXP (ops[i], 0);
	    input_ops++;
	    changed = 1;
	    break;

	  case NEG:
	    ops[i] = XEXP (ops[i], 0);
	    negs[i] = ! negs[i];
	    changed = 1;
	    break;

	  case CONST:
	    ops[i] = XEXP (ops[i], 0);
	    input_consts++;
	    changed = 1;
	    break;

	  case NOT:
	    /* ~a -> (-a - 1) */
	    if (n_ops != 7)
	      {
		ops[n_ops] = constm1_rtx;
		negs[n_ops++] = negs[i];
		ops[i] = XEXP (ops[i], 0);
		negs[i] = ! negs[i];
		changed = 1;
	      }
	    break;

	  case CONST_INT:
	    if (negs[i])
	      ops[i] = GEN_INT (- INTVAL (ops[i])), negs[i] = 0, changed = 1;
	    break;

	  default:
	    break;
	  }
    }

  /* If we only have two operands, we can't do anything.  */
  if (n_ops <= 2)
    return 0;

  /* Now simplify each pair of operands until nothing changes.  The first
     time through just simplify constants against each other.  */

  changed = 1;
  while (changed)
    {
      changed = first;

      for (i = 0; i < n_ops - 1; i++)
	for (j = i + 1; j < n_ops; j++)
	  if (ops[i] != 0 && ops[j] != 0
	      && (! first || (CONSTANT_P (ops[i]) && CONSTANT_P (ops[j]))))
	    {
	      rtx lhs = ops[i], rhs = ops[j];
	      enum rtx_code ncode = PLUS;

	      if (negs[i] && ! negs[j])
		lhs = ops[j], rhs = ops[i], ncode = MINUS;
	      else if (! negs[i] && negs[j])
		ncode = MINUS;

	      tem = simplify_binary_operation (ncode, mode, lhs, rhs);
	      if (tem)
		{
		  ops[i] = tem, ops[j] = 0;
		  negs[i] = negs[i] && negs[j];
		  if (GET_CODE (tem) == NEG)
		    ops[i] = XEXP (tem, 0), negs[i] = ! negs[i];

		  if (GET_CODE (ops[i]) == CONST_INT && negs[i])
		    ops[i] = GEN_INT (- INTVAL (ops[i])), negs[i] = 0;
		  changed = 1;
		}
	    }

      first = 0;
    }

  /* Pack all the operands to the lower-numbered entries and give up if
     we didn't reduce the number of operands we had.  Make sure we
     count a CONST as two operands.  If we have the same number of
     operands, but have made more CONSTs than we had, this is also
     an improvement, so accept it.  */

  for (i = 0, j = 0; j < n_ops; j++)
    if (ops[j] != 0)
      {
	ops[i] = ops[j], negs[i++] = negs[j];
	if (GET_CODE (ops[j]) == CONST)
	  n_consts++;
      }

  if (i + n_consts > input_ops
      || (i + n_consts == input_ops && n_consts <= input_consts))
    return 0;

  n_ops = i;

  /* If we have a CONST_INT, put it last.  */
  for (i = 0; i < n_ops - 1; i++)
    if (GET_CODE (ops[i]) == CONST_INT)
      {
	tem = ops[n_ops - 1], ops[n_ops - 1] = ops[i] , ops[i] = tem;
	j = negs[n_ops - 1], negs[n_ops - 1] = negs[i], negs[i] = j;
      }

  /* Put a non-negated operand first.  If there aren't any, make all
     operands positive and negate the whole thing later.  */
  for (i = 0; i < n_ops && negs[i]; i++)
    ;

  if (i == n_ops)
    {
      for (i = 0; i < n_ops; i++)
	negs[i] = 0;
      negate = 1;
    }
  else if (i != 0)
    {
      tem = ops[0], ops[0] = ops[i], ops[i] = tem;
      j = negs[0], negs[0] = negs[i], negs[i] = j;
    }

  /* Now make the result by performing the requested operations.  */
  result = ops[0];
  for (i = 1; i < n_ops; i++)
    result = cse_gen_binary (negs[i] ? MINUS : PLUS, mode, result, ops[i]);

  return negate ? gen_rtx_NEG (mode, result) : result;
}

/* Make a binary operation by properly ordering the operands and 
   seeing if the expression folds.  */

static rtx
cse_gen_binary (code, mode, op0, op1)
     enum rtx_code code;
     enum machine_mode mode;
     rtx op0, op1;
{
  rtx tem;

  /* Put complex operands first and constants second if commutative.  */
  if (GET_RTX_CLASS (code) == 'c'
      && ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT)
	  || (GET_RTX_CLASS (GET_CODE (op0)) == 'o'
	      && GET_RTX_CLASS (GET_CODE (op1)) != 'o')
	  || (GET_CODE (op0) == SUBREG
	      && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o'
	      && GET_RTX_CLASS (GET_CODE (op1)) != 'o')))
    tem = op0, op0 = op1, op1 = tem;

  /* If this simplifies, do it.  */
  tem = simplify_binary_operation (code, mode, op0, op1);

  if (tem)
    return tem;

  /* Handle addition and subtraction of CONST_INT specially.  Otherwise,
     just form the operation.  */

  if (code == PLUS && GET_CODE (op1) == CONST_INT
      && GET_MODE (op0) != VOIDmode)
    return plus_constant (op0, INTVAL (op1));
  else if (code == MINUS && GET_CODE (op1) == CONST_INT
	   && GET_MODE (op0) != VOIDmode)
    return plus_constant (op0, - INTVAL (op1));
  else
    return gen_rtx_fmt_ee (code, mode, op0, op1);
}

struct cfc_args
{
  /* Input */
  rtx op0, op1;
  /* Output */
  int equal, op0lt, op1lt;
};

static void
check_fold_consts (data)
  PTR data;
{
  struct cfc_args * args = (struct cfc_args *) data;
  REAL_VALUE_TYPE d0, d1;

  REAL_VALUE_FROM_CONST_DOUBLE (d0, args->op0);
  REAL_VALUE_FROM_CONST_DOUBLE (d1, args->op1);
  args->equal = REAL_VALUES_EQUAL (d0, d1);
  args->op0lt = REAL_VALUES_LESS (d0, d1);
  args->op1lt = REAL_VALUES_LESS (d1, d0);
}

/* Like simplify_binary_operation except used for relational operators.
   MODE is the mode of the operands, not that of the result.  If MODE
   is VOIDmode, both operands must also be VOIDmode and we compare the
   operands in "infinite precision".

   If no simplification is possible, this function returns zero.  Otherwise,
   it returns either const_true_rtx or const0_rtx.  */

rtx
simplify_relational_operation (code, mode, op0, op1)
     enum rtx_code code;
     enum machine_mode mode;
     rtx op0, op1;
{
  int equal, op0lt, op0ltu, op1lt, op1ltu;
  rtx tem;

  /* If op0 is a compare, extract the comparison arguments from it.  */
  if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
    op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);

  /* We can't simplify MODE_CC values since we don't know what the
     actual comparison is.  */
  if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC
#ifdef HAVE_cc0
      || op0 == cc0_rtx
#endif
      )
    return 0;

  /* For integer comparisons of A and B maybe we can simplify A - B and can
     then simplify a comparison of that with zero.  If A and B are both either
     a register or a CONST_INT, this can't help; testing for these cases will
     prevent infinite recursion here and speed things up.

     If CODE is an unsigned comparison, then we can never do this optimization,
     because it gives an incorrect result if the subtraction wraps around zero.
     ANSI C defines unsigned operations such that they never overflow, and
     thus such cases can not be ignored.  */

  if (INTEGRAL_MODE_P (mode) && op1 != const0_rtx
      && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == CONST_INT)
	    && (GET_CODE (op1) == REG || GET_CODE (op1) == CONST_INT))
      && 0 != (tem = simplify_binary_operation (MINUS, mode, op0, op1))
      && code != GTU && code != GEU && code != LTU && code != LEU)
    return simplify_relational_operation (signed_condition (code),
					  mode, tem, const0_rtx);

  /* For non-IEEE floating-point, if the two operands are equal, we know the
     result.  */
  if (rtx_equal_p (op0, op1)
      && (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
	  || ! FLOAT_MODE_P (GET_MODE (op0)) || flag_fast_math))
    equal = 1, op0lt = 0, op0ltu = 0, op1lt = 0, op1ltu = 0;

  /* If the operands are floating-point constants, see if we can fold
     the result.  */
#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
  else if (GET_CODE (op0) == CONST_DOUBLE && GET_CODE (op1) == CONST_DOUBLE
	   && GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
    {
      struct cfc_args args;

      /* Setup input for check_fold_consts() */
      args.op0 = op0;
      args.op1 = op1;
      
      if (do_float_handler(check_fold_consts, (PTR) &args) == 0)
	/* We got an exception from check_fold_consts() */
	return 0;

      /* Receive output from check_fold_consts() */
      equal = args.equal;
      op0lt = op0ltu = args.op0lt;
      op1lt = op1ltu = args.op1lt;
    }
#endif  /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */

  /* Otherwise, see if the operands are both integers.  */
  else if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
	   && (GET_CODE (op0) == CONST_DOUBLE || GET_CODE (op0) == CONST_INT)
	   && (GET_CODE (op1) == CONST_DOUBLE || GET_CODE (op1) == CONST_INT))
    {
      int width = GET_MODE_BITSIZE (mode);
      HOST_WIDE_INT l0s, h0s, l1s, h1s;
      unsigned HOST_WIDE_INT l0u, h0u, l1u, h1u;

      /* Get the two words comprising each integer constant.  */
      if (GET_CODE (op0) == CONST_DOUBLE)
	{
	  l0u = l0s = CONST_DOUBLE_LOW (op0);
	  h0u = h0s = CONST_DOUBLE_HIGH (op0);
	}
      else
	{
	  l0u = l0s = INTVAL (op0);
	  h0u = h0s = l0s < 0 ? -1 : 0;
	}
	  
      if (GET_CODE (op1) == CONST_DOUBLE)
	{
	  l1u = l1s = CONST_DOUBLE_LOW (op1);
	  h1u = h1s = CONST_DOUBLE_HIGH (op1);
	}
      else
	{
	  l1u = l1s = INTVAL (op1);
	  h1u = h1s = l1s < 0 ? -1 : 0;
	}

      /* If WIDTH is nonzero and smaller than HOST_BITS_PER_WIDE_INT,
	 we have to sign or zero-extend the values.  */
      if (width != 0 && width <= HOST_BITS_PER_WIDE_INT)
	h0u = h1u = 0, h0s = l0s < 0 ? -1 : 0, h1s = l1s < 0 ? -1 : 0;

      if (width != 0 && width < HOST_BITS_PER_WIDE_INT)
	{
	  l0u &= ((HOST_WIDE_INT) 1 << width) - 1;
	  l1u &= ((HOST_WIDE_INT) 1 << width) - 1;

	  if (l0s & ((HOST_WIDE_INT) 1 << (width - 1)))
	    l0s |= ((HOST_WIDE_INT) (-1) << width);

	  if (l1s & ((HOST_WIDE_INT) 1 << (width - 1)))
	    l1s |= ((HOST_WIDE_INT) (-1) << width);
	}

      equal = (h0u == h1u && l0u == l1u);
      op0lt = (h0s < h1s || (h0s == h1s && l0s < l1s));
      op1lt = (h1s < h0s || (h1s == h0s && l1s < l0s));
      op0ltu = (h0u < h1u || (h0u == h1u && l0u < l1u));
      op1ltu = (h1u < h0u || (h1u == h0u && l1u < l0u));
    }

  /* Otherwise, there are some code-specific tests we can make.  */
  else
    {
      switch (code)
	{
	case EQ:
	  /* References to the frame plus a constant or labels cannot
	     be zero, but a SYMBOL_REF can due to #pragma weak.  */
	  if (((NONZERO_BASE_PLUS_P (op0) && op1 == const0_rtx)
	       || GET_CODE (op0) == LABEL_REF)
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
	      /* On some machines, the ap reg can be 0 sometimes.  */
	      && op0 != arg_pointer_rtx
#endif
		)
	    return const0_rtx;
	  break;

	case NE:
	  if (((NONZERO_BASE_PLUS_P (op0) && op1 == const0_rtx)
	       || GET_CODE (op0) == LABEL_REF)
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
	      && op0 != arg_pointer_rtx
#endif
	      )
	    return const_true_rtx;
	  break;

	case GEU:
	  /* Unsigned values are never negative.  */
	  if (op1 == const0_rtx)
	    return const_true_rtx;
	  break;

	case LTU:
	  if (op1 == const0_rtx)
	    return const0_rtx;
	  break;

	case LEU:
	  /* Unsigned values are never greater than the largest
	     unsigned value.  */
	  if (GET_CODE (op1) == CONST_INT
	      && INTVAL (op1) == GET_MODE_MASK (mode)
	    && INTEGRAL_MODE_P (mode))
	  return const_true_rtx;
	  break;

	case GTU:
	  if (GET_CODE (op1) == CONST_INT
	      && INTVAL (op1) == GET_MODE_MASK (mode)
	      && INTEGRAL_MODE_P (mode))
	    return const0_rtx;
	  break;
	  
	default:
	  break;
	}

      return 0;
    }

  /* If we reach here, EQUAL, OP0LT, OP0LTU, OP1LT, and OP1LTU are set
     as appropriate.  */
  switch (code)
    {
    case EQ:
      return equal ? const_true_rtx : const0_rtx;
    case NE:
      return ! equal ? const_true_rtx : const0_rtx;
    case LT:
      return op0lt ? const_true_rtx : const0_rtx;
    case GT:
      return op1lt ? const_true_rtx : const0_rtx;
    case LTU:
      return op0ltu ? const_true_rtx : const0_rtx;
    case GTU:
      return op1ltu ? const_true_rtx : const0_rtx;
    case LE:
      return equal || op0lt ? const_true_rtx : const0_rtx;
    case GE:
      return equal || op1lt ? const_true_rtx : const0_rtx;
    case LEU:
      return equal || op0ltu ? const_true_rtx : const0_rtx;
    case GEU:
      return equal || op1ltu ? const_true_rtx : const0_rtx;
    default:
      abort ();
    }
}

/* Simplify CODE, an operation with result mode MODE and three operands,
   OP0, OP1, and OP2.  OP0_MODE was the mode of OP0 before it became
   a constant.  Return 0 if no simplifications is possible.  */

rtx
simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
     enum rtx_code code;
     enum machine_mode mode, op0_mode;
     rtx op0, op1, op2;
{
  int width = GET_MODE_BITSIZE (mode);

  /* VOIDmode means "infinite" precision.  */
  if (width == 0)
    width = HOST_BITS_PER_WIDE_INT;

  switch (code)
    {
    case SIGN_EXTRACT:
    case ZERO_EXTRACT:
      if (GET_CODE (op0) == CONST_INT
	  && GET_CODE (op1) == CONST_INT
	  && GET_CODE (op2) == CONST_INT
	  && INTVAL (op1) + INTVAL (op2) <= GET_MODE_BITSIZE (op0_mode)
	  && width <= HOST_BITS_PER_WIDE_INT)
	{
	  /* Extracting a bit-field from a constant */
	  HOST_WIDE_INT val = INTVAL (op0);

	  if (BITS_BIG_ENDIAN)
	    val >>= (GET_MODE_BITSIZE (op0_mode)
		     - INTVAL (op2) - INTVAL (op1));
	  else
	    val >>= INTVAL (op2);

	  if (HOST_BITS_PER_WIDE_INT != INTVAL (op1))
	    {
	      /* First zero-extend.  */
	      val &= ((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1;
	      /* If desired, propagate sign bit.  */
	      if (code == SIGN_EXTRACT
		  && (val & ((HOST_WIDE_INT) 1 << (INTVAL (op1) - 1))))
		val |= ~ (((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1);
	    }

	  /* Clear the bits that don't belong in our mode,
	     unless they and our sign bit are all one.
	     So we get either a reasonable negative value or a reasonable
	     unsigned value for this mode.  */
	  if (width < HOST_BITS_PER_WIDE_INT
	      && ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
		  != ((HOST_WIDE_INT) (-1) << (width - 1))))
	    val &= ((HOST_WIDE_INT) 1 << width) - 1;

	  return GEN_INT (val);
	}
      break;

    case IF_THEN_ELSE:
      if (GET_CODE (op0) == CONST_INT)
	return op0 != const0_rtx ? op1 : op2;

      /* Convert a == b ? b : a to "a".  */
      if (GET_CODE (op0) == NE && ! side_effects_p (op0)
	  && rtx_equal_p (XEXP (op0, 0), op1)
	  && rtx_equal_p (XEXP (op0, 1), op2))
	return op1;
      else if (GET_CODE (op0) == EQ && ! side_effects_p (op0)
	  && rtx_equal_p (XEXP (op0, 1), op1)
	  && rtx_equal_p (XEXP (op0, 0), op2))
	return op2;
      else if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && ! side_effects_p (op0))
	{
	  rtx temp;
	  temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
						XEXP (op0, 0), XEXP (op0, 1));
	  /* See if any simplifications were possible.  */
	  if (temp == const0_rtx)
	    return op2;
	  else if (temp == const1_rtx)
	    return op1;
	}
      break;

    default:
      abort ();
    }

  return 0;
}

/* 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 (x, insn)
     rtx x;
     rtx insn;    
{
  register enum rtx_code code;
  register enum machine_mode mode;
  register char *fmt;
  register 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 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.  */
      if (insn && GET_CODE (insn) == JUMP_INSN)
	{
	  rtx next = next_nonnote_insn (insn);

	  if (next && GET_CODE (next) == CODE_LABEL
	      && NEXT_INSN (next) != 0
	      && GET_CODE (NEXT_INSN (next)) == JUMP_INSN
	      && (GET_CODE (PATTERN (NEXT_INSN (next))) == ADDR_VEC
		  || GET_CODE (PATTERN (NEXT_INSN (next))) == ADDR_DIFF_VEC))
	    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 = 0;

	  if (GET_MODE_CLASS (mode) == MODE_INT
	      && GET_MODE_SIZE (mode) == UNITS_PER_WORD
	      && GET_MODE (SUBREG_REG (x)) != VOIDmode)
	    new = operand_subword (folded_arg0, SUBREG_WORD (x), 0,
				   GET_MODE (SUBREG_REG (x)));
	  if (new == 0 && subreg_lowpart_p (x))
	    new = gen_lowpart_if_possible (mode, folded_arg0);
	  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)
		{
		  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));

      {
	/* 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))
	    && GET_MODE (addr) == qty_mode[REG_QTY (REGNO (addr))]
	    && qty_const[REG_QTY (REGNO (addr))] != 0)
	  addr = qty_const[REG_QTY (REGNO (addr))];

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

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

    case ASM_OPERANDS:
      for (i = XVECLEN (x, 3) - 1; i >= 0; i--)
	validate_change (insn, &XVECEXP (x, 3, i),
			 fold_rtx (XVECEXP (x, 3, 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;

	/* 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))
		&& qty_const[REG_QTY (REGNO (arg))] != 0
		&& GET_CODE (qty_const[REG_QTY (REGNO (arg))]) != REG
		&& GET_CODE (qty_const[REG_QTY (REGNO (arg))]) != PLUS)
	      const_arg
		= gen_lowpart_if_possible (GET_MODE (arg),
					   qty_const[REG_QTY (REGNO (arg))]);
	    break;

	  case CONST:
	  case CONST_INT:
	  case SYMBOL_REF:
	  case LABEL_REF:
	  case CONST_DOUBLE:
	    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 (const_arg) > COST (folded_arg))
	  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;
	  }

	replacements[0] = cheap_arg, replacements[1] = expensive_arg;
	for (j = 0;
	     j < 2 && replacements[j]
	     && COST (replacements[j]) < COST (XEXP (x, i));
	     j++)
	  {
	    if (validate_change (insn, &XEXP (x, i), replacements[j], 0))
	      break;

	    if (code == NE || code == EQ || GET_RTX_CLASS (code) == 'c')
	      {
		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')
    {
      if (must_swap || (const_arg0
	  		&& (const_arg1 == 0
	      		    || (GET_CODE (const_arg0) == CONST_INT
			        && GET_CODE (const_arg1) != CONST_INT))))
	{
	  register 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 '<':
      /* 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 = const_true_rtx, false = const0_rtx;
	  enum machine_mode mode_arg1;

#ifdef FLOAT_STORE_FLAG_VALUE
	  if (GET_MODE_CLASS (mode) == MODE_FLOAT)
	    {
	      true = CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE,
						   mode);
	      false = 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)
	    {
	      /* Is FOLDED_ARG0 frame-pointer plus a constant?  Or
		 non-explicit constant?  These aren't zero, but we
		 don't know their sign.  */
	      if (const_arg1 == const0_rtx
		  && (NONZERO_BASE_PLUS_P (folded_arg0)
#if 0  /* Sad to say, on sysvr4, #pragma weak can make a symbol address
	  come out as 0.  */
		      || GET_CODE (folded_arg0) == SYMBOL_REF
#endif
		      || GET_CODE (folded_arg0) == LABEL_REF
		      || GET_CODE (folded_arg0) == CONST))
		{
		  if (code == EQ)
		    return false;
		  else if (code == NE)
		    return true;
		}

	      /* See if the two operands are the same.  We don't do this
		 for IEEE floating-point since we can't assume x == x
		 since x might be a NaN.  */

	      if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
		   || ! FLOAT_MODE_P (mode_arg0) || flag_fast_math)
		  && (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)
					 % NBUCKETS), mode_arg0))
			  && (p1 = lookup (folded_arg1,
					   (safe_hash (folded_arg1, mode_arg0)
					    % NBUCKETS), mode_arg0))
			  && p0->first_same_value == p1->first_same_value)))
		return ((code == EQ || code == LE || code == GE
			 || code == LEU || code == GEU)
			? true : false);

	      /* 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))
		      && (comparison_dominates_p (qty_comparison_code[qty], code)
			  || (comparison_dominates_p (qty_comparison_code[qty],
						      reverse_condition (code))
			      && ! FLOAT_MODE_P (mode_arg0)))
		      && (rtx_equal_p (qty_comparison_const[qty], folded_arg1)
			  || (const_arg1
			      && rtx_equal_p (qty_comparison_const[qty],
					      const_arg1))
			  || (GET_CODE (folded_arg1) == REG
			      && (REG_QTY (REGNO (folded_arg1))
				  == qty_comparison_qty[qty]))))
		    return (comparison_dominates_p (qty_comparison_code[qty],
						    code)
			    ? true : false);
		}
	    }
	}

      /* 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 = const_true_rtx, false = const0_rtx;

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

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

      new = simplify_relational_operation (code, mode_arg0,
					   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)
	new = ((new == const0_rtx) ? CONST0_RTX (mode)
	       : CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE, 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
	     chosing 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
	      && - INTVAL (const_arg1) >= 0
	      && 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) % NBUCKETS,
			  mode);

	      if (p)
		for (p = p->first_same_value; p; p = p->next_same_value)
		  if (GET_CODE (p->exp) == REG)
		    return cse_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 DIV:       case UDIV:
	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 && INTVAL (const_arg1) == INTVAL (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 == DIV, we want MULT.  */

	      associate_code
		= (code == MULT || code == DIV || code == UDIV ? MULT
		   : is_shift || code == PLUS || 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 cse_gen_binary (code, mode, y, 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':
      /* Always eliminate CONSTANT_P_RTX at this stage. */
      if (code == CONSTANT_P_RTX)
	return (const_arg0 ? const1_rtx : 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 (x)
     rtx x;
{
  if (GET_CODE (x) == REG
      && REGNO_QTY_VALID_P (REGNO (x))
      && qty_const[REG_QTY (REGNO (x))])
    x = gen_lowpart_if_possible (GET_MODE (x), qty_const[REG_QTY (REGNO (x))]);

  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)) % NBUCKETS, 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 (mode, x)
     enum machine_mode mode;
     register 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.  */
      register 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 = gen_rtx_MEM (mode, plus_constant (XEXP (x, 0), offset));
      if (! memory_address_p (mode, XEXP (new, 0)))
	return 0;
      RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
      MEM_COPY_ATTRIBUTES (new, x);
      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 (insn, taken)
     rtx insn;
     int taken;
{
  int cond_known_true;
  rtx op0, op1;
  enum machine_mode mode, mode0, mode1;
  int reversed_nonequality = 0;
  enum rtx_code code;

  /* Ensure this is the right kind of insn.  */
  if (! condjump_p (insn) || simplejump_p (insn))
    return;

  /* See if this jump condition is known true or false.  */
  if (taken)
    cond_known_true = (XEXP (SET_SRC (PATTERN (insn)), 2) == pc_rtx);
  else
    cond_known_true = (XEXP (SET_SRC (PATTERN (insn)), 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 (PATTERN (insn)), 0));
  op0 = fold_rtx (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0), insn);
  op1 = fold_rtx (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 1), insn);

  code = find_comparison_args (code, &op0, &op1, &mode0, &mode1);
  if (! cond_known_true)
    {
      reversed_nonequality = (code != EQ && code != NE);
      code = reverse_condition (code);
    }

  /* 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 (code, mode, op0, op1, reversed_nonequality)
     enum rtx_code code;
     enum machine_mode mode;
     rtx op0, op1;
     int reversed_nonequality;
{
  unsigned op0_hash, op1_hash;
  int op0_in_memory, op0_in_struct, op1_in_memory, op1_in_struct;
  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;
  hash_arg_in_struct = 0;
  op0_hash = HASH (op0, mode);
  op0_in_memory = hash_arg_in_memory;
  op0_in_struct = hash_arg_in_struct;

  if (do_not_record)
    return;

  do_not_record = 0;
  hash_arg_in_memory = 0;
  hash_arg_in_struct = 0;
  op1_hash = HASH (op1, mode);
  op1_in_memory = hash_arg_in_memory;
  op1_in_struct = hash_arg_in_struct;
  
  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)))
    {
      /* 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_PTR, 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_PTR, op0_hash, mode);
	  op0_elt->in_memory = op0_in_memory;
	  op0_elt->in_struct = op0_in_struct;
	}

      qty_comparison_code[REG_QTY (REGNO (op0))] = 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_PTR, 0))
		{
		  rehash_using_reg (op1);
		  op1_hash = HASH (op1, mode);
		}

	      op1_elt = insert (op1, NULL_PTR, op1_hash, mode);
	      op1_elt->in_memory = op1_in_memory;
	      op1_elt->in_struct = op1_in_struct;
	    }

	  qty_comparison_qty[REG_QTY (REGNO (op0))] = REG_QTY (REGNO (op1));
	  qty_comparison_const[REG_QTY (REGNO (op0))] = 0;
	}
      else
	{
	  qty_comparison_qty[REG_QTY (REGNO (op0))] = -1;
	  qty_comparison_const[REG_QTY (REGNO (op0))] = op1;
	}

      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_PTR, 0))
	{
	  rehash_using_reg (op0);
	  op0_hash = HASH (op0, mode);
	}

      op0_elt = insert (op0, NULL_PTR, op0_hash, mode);
      op0_elt->in_memory = op0_in_memory;
      op0_elt->in_struct = op0_in_struct;
    }

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

      op1_elt = insert (op1, NULL_PTR, op1_hash, mode);
      op1_elt->in_memory = op1_in_memory;
      op1_elt->in_struct = op1_in_struct;
    }

  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;
  /* Place where the pointer to the INNER_DEST was found.  */
  rtx *inner_dest_loc;
  /* Nonzero if the SET_SRC is in memory.  */ 
  char src_in_memory;
  /* Nonzero if the SET_SRC is in a structure.  */ 
  char src_in_struct;
  /* 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.  */
  enum machine_mode mode;
  /* A constant equivalent for SET_SRC, if any.  */
  rtx src_const;
  /* 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 (insn, libcall_insn)
     rtx insn;
     rtx libcall_insn;
{
  register rtx x = PATTERN (insn);
  register int i;
  rtx tem;
  register 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;
  int src_eqv_in_memory;
  int src_eqv_in_struct;
  unsigned src_eqv_hash;

  struct set *sets;

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

  if (GET_CODE (x) == SET)
    {
      sets = (struct set *) 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)
    {
      register int lim = XVECLEN (x, 0);

      sets = (struct set *) 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++)
	{
	  register 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++)
	{
	  register 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 = canon_reg (XEXP (tem, 0), NULL_RTX);

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

      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_n_dups[insn_code] > 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++)
    {
      register rtx src, dest;
      register rtx src_folded;
      register 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 = 10000, src_eqv_cost = 10000, src_folded_cost = 10000;
      int src_related_cost = 10000, src_elt_cost = 10000;
      /* Set non-zero 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;
	  hash_arg_in_struct = 0;
	  src_eqv = fold_rtx (src_eqv, insn);
	  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;
	  src_eqv_in_struct = hash_arg_in_struct;
	}

      /* 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;
      hash_arg_in_struct = 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_in_struct = hash_arg_in_struct;

      /* If SRC is a MEM, there is a REG_EQUIV note for SRC, and DEST is
	 a pseudo that is set more than once, 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, src) != 0
	  && GET_CODE (dest) == REG
	  && REGNO (dest) >= FIRST_PSEUDO_REGISTER
	  && REG_N_SETS (REGNO (dest)) != 1)
	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 non-zero, points to a class of expressions
         equivalent to the source of this SET and SRC, SRC_EQV, SRC_FOLDED,
	 and SRC_RELATED, if non-zero, 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 = -1;
	  else
	    src_cost = COST (src);
	}

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

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

      if (src_related)
	{
	  if (rtx_equal_p (src_related, dest))
	    src_related_cost = -1;
	  else
	    src_related_cost = 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 = -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, old_src;

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

          /* 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_cost <= src_cost
	      && src_folded_cost <= src_eqv_cost
	      && src_folded_cost <= src_related_cost
	      && src_folded_cost <= src_elt_cost)
	    {
	      trial = src_folded, src_folded_cost = 10000;
	      if (src_folded_force_flag)
		trial = force_const_mem (mode, trial);
	    }
          else if (src_cost <= src_eqv_cost
	           && src_cost <= src_related_cost
	           && src_cost <= src_elt_cost)
	    trial = src, src_cost = 10000;
          else if (src_eqv_cost <= src_related_cost
	           && src_eqv_cost <= src_elt_cost)
	    trial = copy_rtx (src_eqv_here), src_eqv_cost = 10000;
          else if (src_related_cost <= src_elt_cost)
	    trial = copy_rtx (src_related), src_related_cost = 10000;
          else
	    {
	      trial = copy_rtx (elt->exp);
	      elt = elt->next_same_value;
	      src_elt_cost = 10000;
	    }

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

	     Tablejump insns contain a USE of the table, so simply replacing
	     the operand with the constant won't match.  This is simply an
	     unconditional branch, however, and is therefore valid.  Just
	     insert the substitution here and we will delete and re-emit
	     the insn later.  */

	  /* Keep track of the original SET_SRC so that we can fix notes
	     on libcall instructions.  */
 	  old_src = SET_SRC (sets[i].rtl);

	  if (n_sets == 1 && dest == pc_rtx
	      && (trial == pc_rtx
		  || (GET_CODE (trial) == LABEL_REF
		      && ! condjump_p (insn))))
	    {
	      /* If TRIAL is a label in front of a jump table, we are
		 really falling through the switch (this is how casesi
		 insns work), so we must branch around the table.  */
	      if (GET_CODE (trial) == CODE_LABEL
		  && NEXT_INSN (trial) != 0
		  && GET_CODE (NEXT_INSN (trial)) == JUMP_INSN
		  && (GET_CODE (PATTERN (NEXT_INSN (trial))) == ADDR_DIFF_VEC
		      || GET_CODE (PATTERN (NEXT_INSN (trial))) == ADDR_VEC))

		trial = gen_rtx_LABEL_REF (Pmode, get_label_after (trial));

	      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))
	    {
	      /* 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 (old_src) == REG
		      || GET_CODE (old_src) == SUBREG
		      ||  GET_CODE (old_src) == MEM))
		replace_rtx (REG_NOTES (libcall_insn), old_src, 
			     canon_reg (SET_SRC (sets[i].rtl), insn));

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

	      validate_change (insn, &SET_SRC (sets[i].rtl),
			       canon_reg (SET_SRC (sets[i].rtl), insn),
			       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)
		   && ! (GET_CODE (trial) == CONST
			 && GET_CODE (XEXP (trial, 0)) == TRUNCATE)
		   && (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 = 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))
	  && qty_mode[REG_QTY (REGNO (dest))] == GET_MODE (dest)
	  && qty_first_reg[REG_QTY (REGNO (dest))] != 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.  */
	  && (GET_CODE (sets[i].src) != REG
	      || REGNO (sets[i].src) >= FIRST_PSEUDO_REGISTER))
	/* We can't call canon_reg here because it won't do anything if
	   SRC is a hard register.  */
	{
	  int first = qty_first_reg[REG_QTY (REGNO (src))];
	  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)
        {
          do_not_record = 0;
          hash_arg_in_memory = 0;
          hash_arg_in_struct = 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_in_struct = hash_arg_in_struct;
          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))
	{
	  tem = find_reg_note (insn, REG_EQUAL, NULL_RTX);
	  
	  /* Make sure that the rtx is not shared with any other insn.  */
	  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.  */
	  if (tem)
	    XEXP (tem, 0) = src_const;
	  else
	    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL,
						  src_const, REG_NOTES (insn));

          /* If storing a constant value in a register that
	     previously held the constant value 0,
	     record this fact with a REG_WAS_0 note on this insn.

	     Note that the *register* is required to have previously held 0,
	     not just any register in the quantity and we must point to the
	     insn that set that register to zero.

	     Rather than track each register individually, we just see if
	     the last set for this quantity was for this register.  */

	  if (REGNO_QTY_VALID_P (REGNO (dest))
	      && qty_const[REG_QTY (REGNO (dest))] == const0_rtx)
	    {
	      /* See if we previously had a REG_WAS_0 note.  */
	      rtx note = find_reg_note (insn, REG_WAS_0, NULL_RTX);
	      rtx const_insn = qty_const_insn[REG_QTY (REGNO (dest))];

	      if ((tem = single_set (const_insn)) != 0
		  && rtx_equal_p (SET_DEST (tem), dest))
		{
		  if (note)
		    XEXP (note, 0) = const_insn;
		  else
		    REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_WAS_0,
							  const_insn,
							  REG_NOTES (insn));
		}
	    }
	}

      /* Now deal with the destination.  */
      do_not_record = 0;
      sets[i].inner_dest_loc = &SET_DEST (sets[0].rtl);

      /* 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)
	{
	  sets[i].inner_dest_loc = &XEXP (dest, 0);
	  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_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC
	       || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC)
	      && 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)
	{
	  PUT_CODE (insn, NOTE);
	  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
	  NOTE_SOURCE_FILE (insn) = 0;
	  cse_jumps_altered = 1;
	  /* One less use of the label this insn used to jump to.  */
	  if (JUMP_LABEL (insn) != 0)
	    --LABEL_NUSES (JUMP_LABEL (insn));
	  /* 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.  So we see if we can follow
	 it.  If it was a computed branch, delete it and re-emit.  */
      else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF)
	{
	  rtx p;

	  /* If this is not in the format for a simple branch and
	     we are the only SET in it, re-emit it.  */
	  if (! simplejump_p (insn) && n_sets == 1)
	    {
	      rtx new = emit_jump_insn_before (gen_jump (XEXP (src, 0)), insn);
	      JUMP_LABEL (new) = XEXP (src, 0);
	      LABEL_NUSES (XEXP (src, 0))++;
	      delete_insn (insn);
	      insn = new;
	    }
	  else
	    /* Otherwise, force rerecognition, since it probably had
	       a different pattern before.
	       This shouldn't really be necessary, since whatever
	       changed the source value above should have done this.
	       Until the right place is found, might as well do this here.  */
	    INSN_CODE (insn) = -1;

	  /* Now that we've converted this jump to an unconditional jump,
	     there is dead code after it.  Delete the dead code until we
	     reach a BARRIER, the end of the function, or a label.  Do
	     not delete NOTEs except for NOTE_INSN_DELETED since later
	     phases assume these notes are retained.  */

	  p = insn;

	  while (NEXT_INSN (p) != 0
		 && GET_CODE (NEXT_INSN (p)) != BARRIER
		 && GET_CODE (NEXT_INSN (p)) != CODE_LABEL)
	    {
	      if (GET_CODE (NEXT_INSN (p)) != NOTE
		  || NOTE_LINE_NUMBER (NEXT_INSN (p)) == NOTE_INSN_DELETED)
		delete_insn (NEXT_INSN (p));
	      else
		p = NEXT_INSN (p);
	    }

	  /* If we don't have a BARRIER immediately after INSN, put one there.
	     Much code assumes that there are no NOTEs between a JUMP_INSN and
	     BARRIER.  */

	  if (NEXT_INSN (insn) == 0
	      || GET_CODE (NEXT_INSN (insn)) != BARRIER)
	    emit_barrier_before (NEXT_INSN (insn));

	  /* We might have two BARRIERs separated by notes.  Delete the second
	     one if so.  */

	  if (p != insn && NEXT_INSN (p) != 0
	      && GET_CODE (NEXT_INSN (p)) == BARRIER)
	    delete_insn (NEXT_INSN (p));

	  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
	      || GET_CODE (dest) == MEM)
	    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)))
    {
      register struct table_elt *elt;
      register 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;
      elt->in_struct = src_eqv_in_struct;
      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.  */
	    register struct table_elt *classp = src_eqv_elt;
	    register rtx src = sets[i].src;
	    register rtx dest = SET_DEST (sets[i].rtl);
	    enum machine_mode mode
	      = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src);

	    /* Don't put a hard register source into the table if this is
	       the last insn of a libcall.  */
	    if (sets[i].src_elt == 0
		&& (GET_CODE (src) != REG
		    || REGNO (src) >= FIRST_PSEUDO_REGISTER
		    || ! find_reg_note (insn, REG_RETVAL, NULL_RTX)))
	      {
		register 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;
		elt->in_struct = sets[i].src_in_struct;
		sets[i].src_elt = classp = elt;
	      }

	    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_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.  */
	register 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
	    || GET_CODE (dest) == MEM)
	  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 NBUCKETS 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 .  */
	      register int regno = REGNO (x);
	      register int endregno
		= regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
			   : HARD_REGNO_NREGS (regno, GET_MODE (x)));
	      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.  */
	  {
	    register 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)
      {
	register rtx dest = SET_DEST (sets[i].rtl);
	rtx inner_dest = sets[i].inner_dest;
	register 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 (elt->in_memory)
	  {
	    /* This implicitly assumes a whole struct
	       need not have MEM_IN_STRUCT_P.
	       But a whole struct is *supposed* to have MEM_IN_STRUCT_P.  */
	    elt->in_struct = (MEM_IN_STRUCT_P (sets[i].inner_dest)
			      || sets[i].inner_dest != SET_DEST (sets[i].rtl));
	  }

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

		/* Ignore invalid entries.  */
		if (GET_CODE (elt->exp) != REG
		    && ! exp_equiv_p (elt->exp, elt->exp, 1, 0))
		  continue;

		new_src = gen_lowpart_if_possible (new_mode, elt->exp);
		if (new_src == 0)
		  new_src = gen_rtx_SUBREG (new_mode, elt->exp, 0);

		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;
		    src_elt->in_struct = elt->in_struct;
		  }
		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)))
      && (qty_first_reg[REG_QTY (REGNO (SET_SRC (sets[0].rtl)))]
	  == REGNO (SET_DEST (sets[0].rtl)))
      && ! find_reg_note (insn, REG_RETVAL, NULL_RTX))
    {
      rtx prev = PREV_INSN (insn);
      while (prev && GET_CODE (prev) == NOTE)
	prev = PREV_INSN (prev);

      if (prev && GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SET
	  && SET_DEST (PATTERN (prev)) == SET_SRC (sets[0].rtl))
	{
	  rtx dest = SET_DEST (sets[0].rtl);
	  rtx note = find_reg_note (prev, REG_EQUIV, NULL_RTX);

	  validate_change (prev, & SET_DEST (PATTERN (prev)), dest, 1);
	  validate_change (insn, & SET_DEST (sets[0].rtl),
			   SET_SRC (sets[0].rtl), 1);
	  validate_change (insn, & SET_SRC (sets[0].rtl), dest, 1);
	  apply_change_group ();

	  /* If REG1 was equivalent to a constant, REG0 is not.  */
	  if (note)
	    PUT_REG_NOTE_KIND (note, REG_EQUAL);

	  /* If there was a REG_WAS_0 note on PREV, remove it.  Move
	     any REG_WAS_0 note on INSN to PREV.  */
	  note = find_reg_note (prev, REG_WAS_0, NULL_RTX);
	  if (note)
	    remove_note (prev, note);

	  note = find_reg_note (insn, REG_WAS_0, NULL_RTX);
	  if (note)
	    {
	      remove_note (insn, note);
	      XEXP (note, 1) = REG_NOTES (prev);
	      REG_NOTES (prev) = note;
	    }

	  /* If INSN has a REG_EQUAL note, and this note mentions REG0,
	     then we must delete it, because the value in REG0 has changed.  */
	  note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
	  if (note && reg_mentioned_p (dest, 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))
    {
      PUT_CODE (prev_insn, NOTE);
      NOTE_LINE_NUMBER (prev_insn) = NOTE_INSN_DELETED;
      NOTE_SOURCE_FILE (prev_insn) = 0;
    }

  prev_insn_cc0 = this_insn_cc0;
  prev_insn_cc0_mode = this_insn_cc0_mode;
#endif

  prev_insn = insn;
}

/* Remove from the hash table all expressions that reference memory.  */
static void
invalidate_memory ()
{
  register int i;
  register struct table_elt *p, *next;

  for (i = 0; i < NBUCKETS; i++)
    for (p = table[i]; p; p = next)
      {
	next = p->next_same_hash;
	if (p->in_memory)
	  remove_from_table (p, i);
      }
}

/* XXX ??? The name of this function bears little resemblance to
   what this function actually does.  FIXME.  */
static int
note_mem_written (addr)
     register rtx addr;
{
  /* Pushing or popping the stack invalidates just the stack pointer.  */
  if ((GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC
       || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC)
      && 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)++;

      /* 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 (x)
     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)
    {
      register int i;
      for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
	{
	  register 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 (x, object)
     rtx x;
     rtx object;
{
  enum rtx_code code = GET_CODE (x);
  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 PC:
    case CC0:
    case LO_SUM:
      return x;

    case MEM:
      XEXP (x, 0) = cse_process_notes (XEXP (x, 0), x);
      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))
	  && qty_const[i] != 0
	  && (CONSTANT_P (qty_const[i])
	      || GET_CODE (qty_const[i]) == REG))
	{
	  rtx new = gen_lowpart_if_possible (GET_MODE (x), qty_const[i]);
	  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 (loop_start)
     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 (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
	  && (GET_CODE (PATTERN (insn)) == SET
	      || GET_CODE (PATTERN (insn)) == CLOBBER))
	cse_set_around_loop (PATTERN (insn), insn, loop_start);
      else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
	       && 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 (dest, set)
     rtx set;
     rtx dest;
{
  enum rtx_code code = GET_CODE (dest);

  if (code == MEM
      && ! note_mem_written (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))))
    {
      invalidate_memory ();
      return;
    }

  if (GET_CODE (set) == CLOBBER
#ifdef HAVE_cc0
      || dest == cc0_rtx
#endif
      || 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 (start)
     rtx start;
{
  rtx insn;

  for (insn = start; insn && GET_CODE (insn) != CODE_LABEL;
       insn = NEXT_INSN (insn))
    {
      if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
	continue;

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

      invalidate_from_clobbers (PATTERN (insn));
      note_stores (PATTERN (insn), invalidate_skipped_set);
    }
}

/* Used for communication between the following two routines; contains a
   value to be checked for modification.  */

static rtx cse_check_loop_start_value;

/* If modifying X will modify the value in CSE_CHECK_LOOP_START_VALUE,
   indicate that fact by setting CSE_CHECK_LOOP_START_VALUE to 0.  */

static void
cse_check_loop_start (x, set)
     rtx x;
     rtx set ATTRIBUTE_UNUSED;
{
  if (cse_check_loop_start_value == 0
      || 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 = 0;
}

/* 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 (x, insn, loop_start)
     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;

		    cse_check_loop_start_value = SET_SRC (x);
		    for (q = p; q != loop_start; q = NEXT_INSN (q))
		      if (GET_RTX_CLASS (GET_CODE (q)) == 'i')
			note_stores (PATTERN (q), cse_check_loop_start);

		    /* 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
			&& 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
			  emit_insn_after (move, p);
		      }
		    break;
		  }
	    }
    }

  /* Now invalidate anything modified by X.  */
  note_mem_written (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 non-zero
   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 non-zero.

   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 (insn, data, follow_jumps, after_loop, skip_blocks)
     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 = GET_RTX_CLASS (GET_CODE (insn)) == 'i' ? 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 non-zero.  */
  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--;
    }

  /* 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 (GET_CODE (p) == NOTE
	  && NOTE_LINE_NUMBER (p) == NOTE_INSN_SETJMP)
	break;

      /* A PARALLEL can have lots of SETs in it,
	 especially if it is really an ASM_OPERANDS.  */
      if (GET_RTX_CLASS (GET_CODE (p)) == 'i'
	  && 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 < PATHLENGTH - 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
	         || NOTE_LINE_NUMBER (q) == NOTE_INSN_SETJMP)
	        && (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)
	    {
	      register 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 (f, nregs, after_loop, file)
     rtx f;
     int nregs;
     int after_loop;
     FILE *file;
{
  struct cse_basic_block_data val;
  register rtx insn = f;
  register int i;

  cse_jumps_altered = 0;
  recorded_label_ref = 0;
  constant_pool_entries_cost = 0;
  val.path_size = 0;

  init_recog ();
  init_alias_analysis ();

  max_reg = nregs;

  max_insn_uid = get_max_uid ();

  reg_next_eqv = (int *) alloca (nregs * sizeof (int));
  reg_prev_eqv = (int *) alloca (nregs * sizeof (int));

#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

  /* Discard all the free elements of the previous function
     since they are allocated in the temporarily obstack.  */
  bzero ((char *) table, sizeof table);
  free_element_chain = 0;
  n_elements_made = 0;

  /* Find the largest uid.  */

  max_uid = get_max_uid ();
  uid_cuid = (int *) alloca ((max_uid + 1) * sizeof (int));
  bzero ((char *) uid_cuid, (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;
    }

  /* Initialize which registers are clobbered by calls.  */

  CLEAR_HARD_REG_SET (regs_invalidated_by_call);

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if ((call_used_regs[i]
	 /* Used to check !fixed_regs[i] here, but that isn't safe;
	    fixed regs are still call-clobbered, and sched can get
	    confused if they can "live across calls".

	    The frame pointer is always preserved across calls.  The arg
	    pointer is if it is fixed.  The stack pointer usually is, unless
	    RETURN_POPS_ARGS, in which case an explicit CLOBBER
	    will be present.  If we are generating PIC code, the PIC offset
	    table register is preserved across calls.  */

	 && i != STACK_POINTER_REGNUM
	 && i != FRAME_POINTER_REGNUM
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
	 && i != HARD_FRAME_POINTER_REGNUM
#endif
#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
	 && ! (i == ARG_POINTER_REGNUM && fixed_regs[i])
#endif
#if defined (PIC_OFFSET_TABLE_REGNUM) && !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED)
	 && ! (i == PIC_OFFSET_TABLE_REGNUM && flag_pic)
#endif
	 )
	|| global_regs[i])
      SET_HARD_REG_BIT (regs_invalidated_by_call, i);

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

      max_qty += max_reg;

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

#ifdef USE_C_ALLOCA
      alloca (0);
#endif
    }

  /* Tell refers_to_mem_p that qty_const info is not available.  */
  qty_const = 0;

  if (max_elements_made < n_elements_made)
    max_elements_made = n_elements_made;

  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 non-zero 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 (from, to, next_branch, around_loop)
     register rtx from, to;
     struct branch_path *next_branch;
     int around_loop;
{
  register rtx insn;
  int to_usage = 0;
  rtx libcall_insn = NULL_RTX;
  int num_insns = 0;

  /* Each of these arrays is undefined before max_reg, so only allocate
     the space actually needed and adjust the start below.  */

  qty_first_reg = (int *) alloca ((max_qty - max_reg) * sizeof (int));
  qty_last_reg = (int *) alloca ((max_qty - max_reg) * sizeof (int));
  qty_mode= (enum machine_mode *) alloca ((max_qty - max_reg) * sizeof (enum machine_mode));
  qty_const = (rtx *) alloca ((max_qty - max_reg) * sizeof (rtx));
  qty_const_insn = (rtx *) alloca ((max_qty - max_reg) * sizeof (rtx));
  qty_comparison_code
    = (enum rtx_code *) alloca ((max_qty - max_reg) * sizeof (enum rtx_code));
  qty_comparison_qty = (int *) alloca ((max_qty - max_reg) * sizeof (int));
  qty_comparison_const = (rtx *) alloca ((max_qty - max_reg) * sizeof (rtx));

  qty_first_reg -= max_reg;
  qty_last_reg -= max_reg;
  qty_mode -= max_reg;
  qty_const -= max_reg;
  qty_const_insn -= max_reg;
  qty_comparison_code -= max_reg;
  qty_comparison_qty -= max_reg;
  qty_comparison_const -= max_reg;

  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))
    {
      register 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 or 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;
#endif
	      prev_insn = insn;
	      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 ((p = find_reg_note (insn, REG_LIBCALL, NULL_RTX)))
	    libcall_insn = XEXP (p, 0);
	  else if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
	    libcall_insn = NULL_RTX;

	  cse_insn (insn, libcall_insn);
	}

      /* 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 (simplejump_p (insn))
	{
	  if (to == 0)
	    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 (LABEL_NUSES (to) == 0)
	    insn = delete_insn (to);

	  /* If TO was the last insn in the function, we are done.  */
	  if (insn == 0)
	    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)
	    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;
	  cse_end_of_basic_block (insn, &val, 0, 0, 0);

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

  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 (PREV_INSN (to)) == JUMP_INSN
      && JUMP_LABEL (PREV_INSN (to)) != 0
      && LABEL_NUSES (JUMP_LABEL (PREV_INSN (to))) == 1)
    cse_around_loop (JUMP_LABEL (PREV_INSN (to)));

  return to ? NEXT_INSN (to) : 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.  

   Don't count a usage of DEST, which is the SET_DEST of a SET which 
   contains X in its SET_SRC.  This is because such a SET does not
   modify the liveness of DEST.  */

static void
count_reg_usage (x, counts, dest, incr)
     rtx x;
     int *counts;
     rtx dest;
     int incr;
{
  enum rtx_code code;
  char *fmt;
  int i, j;

  if (x == 0)
    return;

  switch (code = GET_CODE (x))
    {
    case REG:
      if (x != dest)
	counts[REGNO (x)] += incr;
      return;

    case PC:
    case CC0:
    case CONST:
    case CONST_INT:
    case CONST_DOUBLE:
    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, NULL_RTX, 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, NULL_RTX, incr);

      /* If SRC has side-effects, then we can't delete this insn, so the
	 usage of SET_DEST inside SRC counts.

	 ??? Strictly-speaking, we might be preserving this insn
	 because some other SET has side-effects, but that's hard
	 to do and can't happen now.  */
      count_reg_usage (SET_SRC (x), counts,
		       side_effects_p (SET_SRC (x)) ? NULL_RTX : SET_DEST (x),
		       incr);
      return;

    case CALL_INSN:
      count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, NULL_RTX, incr);

      /* ... falls through ...  */
    case INSN:
    case JUMP_INSN:
      count_reg_usage (PATTERN (x), counts, NULL_RTX, incr);

      /* Things used in a REG_EQUAL note aren't dead since loop may try to
	 use them.  */

      count_reg_usage (REG_NOTES (x), counts, NULL_RTX, incr);
      return;

    case EXPR_LIST:
    case INSN_LIST:
      if (REG_NOTE_KIND (x) == REG_EQUAL
	  || (REG_NOTE_KIND (x) != REG_NONNEG && GET_CODE (XEXP (x,0)) == USE))
	count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr);
      count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr);
      return;
      
    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, dest, incr);
      else if (fmt[i] == 'E')
	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	  count_reg_usage (XVECEXP (x, i, j), counts, dest, incr);
    }
}

/* 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.  */

void
delete_trivially_dead_insns (insns, nreg)
     rtx insns;
     int nreg;
{
  int *counts = (int *) alloca (nreg * sizeof (int));
  rtx insn, prev;
#ifdef HAVE_cc0
  rtx tem;
#endif
  int i;
  int in_libcall = 0, dead_libcall = 0;

  /* First count the number of times each register is used.  */
  bzero ((char *) counts, sizeof (int) * nreg);
  for (insn = next_real_insn (insns); insn; insn = next_real_insn (insn))
    count_reg_usage (insn, counts, NULL_RTX, 1);

  /* 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.  */
  for (insn = prev_real_insn (get_last_insn ()); insn; insn = prev)
    {
      int live_insn = 0;
      rtx note;

      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 = 0;

	  /* 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)
	    {
	      rtx set = single_set (insn);
	      if (set
		  && validate_change (insn, &SET_SRC (set), XEXP (note, 0), 0))
		{
		  remove_note (insn,
			       find_reg_note (insn, REG_RETVAL, NULL_RTX));
		  dead_libcall = 1;
		}
	    }
	}
      else if (in_libcall)
	live_insn = ! dead_libcall;
      else if (GET_CODE (PATTERN (insn)) == SET)
	{
	  if (GET_CODE (SET_DEST (PATTERN (insn))) == REG
	      && SET_DEST (PATTERN (insn)) == SET_SRC (PATTERN (insn)))
	    ;

#ifdef HAVE_cc0
	  else if (GET_CODE (SET_DEST (PATTERN (insn))) == CC0
		   && ! side_effects_p (SET_SRC (PATTERN (insn)))
		   && ((tem = next_nonnote_insn (insn)) == 0
		       || GET_RTX_CLASS (GET_CODE (tem)) != 'i'
		       || ! reg_referenced_p (cc0_rtx, PATTERN (tem))))
	    ;
#endif
	  else if (GET_CODE (SET_DEST (PATTERN (insn))) != REG
		   || REGNO (SET_DEST (PATTERN (insn))) < FIRST_PSEUDO_REGISTER
		   || counts[REGNO (SET_DEST (PATTERN (insn)))] != 0
		   || side_effects_p (SET_SRC (PATTERN (insn))))
	    live_insn = 1;
	}
      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 (GET_CODE (SET_DEST (elt)) == REG
		    && SET_DEST (elt) == SET_SRC (elt))
		  ;

#ifdef HAVE_cc0
		else if (GET_CODE (SET_DEST (elt)) == CC0
			 && ! side_effects_p (SET_SRC (elt))
			 && ((tem = next_nonnote_insn (insn)) == 0
			     || GET_RTX_CLASS (GET_CODE (tem)) != 'i'
			     || ! reg_referenced_p (cc0_rtx, PATTERN (tem))))
		  ;
#endif
		else if (GET_CODE (SET_DEST (elt)) != REG
			 || REGNO (SET_DEST (elt)) < FIRST_PSEUDO_REGISTER
			 || counts[REGNO (SET_DEST (elt))] != 0
			 || side_effects_p (SET_SRC (elt)))
		  live_insn = 1;
	      }
	    else if (GET_CODE (elt) != CLOBBER && GET_CODE (elt) != USE)
	      live_insn = 1;
	  }
      else
	live_insn = 1;

      /* 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, NULL_RTX, -1);
	  delete_insn (insn);
	}

      if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
	{
	  in_libcall = 0;
	  dead_libcall = 0;
	}
    }
}
