cse.c revision 90075
118334Speter/* Common subexpression elimination for GNU compiler.
290075Sobrien   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
390075Sobrien   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
418334Speter
590075SobrienThis file is part of GCC.
618334Speter
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1118334Speter
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
1990075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
2090075Sobrien02111-1307, USA.  */
2118334Speter
2218334Speter#include "config.h"
2350397Sobrien/* stdio.h must precede rtl.h for FFS.  */
2450397Sobrien#include "system.h"
2518334Speter
2618334Speter#include "rtl.h"
2790075Sobrien#include "tm_p.h"
2818334Speter#include "regs.h"
2918334Speter#include "hard-reg-set.h"
3090075Sobrien#include "basic-block.h"
3118334Speter#include "flags.h"
3218334Speter#include "real.h"
3318334Speter#include "insn-config.h"
3418334Speter#include "recog.h"
3590075Sobrien#include "function.h"
3650397Sobrien#include "expr.h"
3750397Sobrien#include "toplev.h"
3850397Sobrien#include "output.h"
3990075Sobrien#include "ggc.h"
4018334Speter
4118334Speter/* The basic idea of common subexpression elimination is to go
4218334Speter   through the code, keeping a record of expressions that would
4318334Speter   have the same value at the current scan point, and replacing
4418334Speter   expressions encountered with the cheapest equivalent expression.
4518334Speter
4618334Speter   It is too complicated to keep track of the different possibilities
4756385Sobrien   when control paths merge in this code; so, at each label, we forget all
4856385Sobrien   that is known and start fresh.  This can be described as processing each
4956385Sobrien   extended basic block separately.  We have a separate pass to perform
5056385Sobrien   global CSE.
5118334Speter
5256385Sobrien   Note CSE can turn a conditional or computed jump into a nop or
5356385Sobrien   an unconditional jump.  When this occurs we arrange to run the jump
5456385Sobrien   optimizer after CSE to delete the unreachable code.
5556385Sobrien
5618334Speter   We use two data structures to record the equivalent expressions:
5790075Sobrien   a hash table for most expressions, and a vector of "quantity
5890075Sobrien   numbers" to record equivalent (pseudo) registers.
5918334Speter
6018334Speter   The use of the special data structure for registers is desirable
6118334Speter   because it is faster.  It is possible because registers references
6218334Speter   contain a fairly small number, the register number, taken from
6318334Speter   a contiguously allocated series, and two register references are
6418334Speter   identical if they have the same number.  General expressions
6518334Speter   do not have any such thing, so the only way to retrieve the
6618334Speter   information recorded on an expression other than a register
6718334Speter   is to keep it in a hash table.
6818334Speter
6918334SpeterRegisters and "quantity numbers":
7090075Sobrien
7118334Speter   At the start of each basic block, all of the (hardware and pseudo)
7218334Speter   registers used in the function are given distinct quantity
7318334Speter   numbers to indicate their contents.  During scan, when the code
7418334Speter   copies one register into another, we copy the quantity number.
7518334Speter   When a register is loaded in any other way, we allocate a new
7618334Speter   quantity number to describe the value generated by this operation.
7718334Speter   `reg_qty' records what quantity a register is currently thought
7818334Speter   of as containing.
7918334Speter
8018334Speter   All real quantity numbers are greater than or equal to `max_reg'.
8118334Speter   If register N has not been assigned a quantity, reg_qty[N] will equal N.
8218334Speter
8390075Sobrien   Quantity numbers below `max_reg' do not exist and none of the `qty_table'
8490075Sobrien   entries should be referenced with an index below `max_reg'.
8518334Speter
8618334Speter   We also maintain a bidirectional chain of registers for each
8790075Sobrien   quantity number.  The `qty_table` members `first_reg' and `last_reg',
8890075Sobrien   and `reg_eqv_table' members `next' and `prev' hold these chains.
8918334Speter
9018334Speter   The first register in a chain is the one whose lifespan is least local.
9118334Speter   Among equals, it is the one that was seen first.
9218334Speter   We replace any equivalent register with that one.
9318334Speter
9418334Speter   If two registers have the same quantity number, it must be true that
9590075Sobrien   REG expressions with qty_table `mode' must be in the hash table for both
9618334Speter   registers and must be in the same class.
9718334Speter
9818334Speter   The converse is not true.  Since hard registers may be referenced in
9918334Speter   any mode, two REG expressions might be equivalent in the hash table
10018334Speter   but not have the same quantity number if the quantity number of one
10118334Speter   of the registers is not the same mode as those expressions.
10290075Sobrien
10318334SpeterConstants and quantity numbers
10418334Speter
10518334Speter   When a quantity has a known constant value, that value is stored
10690075Sobrien   in the appropriate qty_table `const_rtx'.  This is in addition to
10718334Speter   putting the constant in the hash table as is usual for non-regs.
10818334Speter
10918334Speter   Whether a reg or a constant is preferred is determined by the configuration
11018334Speter   macro CONST_COSTS and will often depend on the constant value.  In any
11118334Speter   event, expressions containing constants can be simplified, by fold_rtx.
11218334Speter
11318334Speter   When a quantity has a known nearly constant value (such as an address
11490075Sobrien   of a stack slot), that value is stored in the appropriate qty_table
11590075Sobrien   `const_rtx'.
11618334Speter
11718334Speter   Integer constants don't have a machine mode.  However, cse
11818334Speter   determines the intended machine mode from the destination
11918334Speter   of the instruction that moves the constant.  The machine mode
12018334Speter   is recorded in the hash table along with the actual RTL
12118334Speter   constant expression so that different modes are kept separate.
12218334Speter
12318334SpeterOther expressions:
12418334Speter
12518334Speter   To record known equivalences among expressions in general
12618334Speter   we use a hash table called `table'.  It has a fixed number of buckets
12718334Speter   that contain chains of `struct table_elt' elements for expressions.
12818334Speter   These chains connect the elements whose expressions have the same
12918334Speter   hash codes.
13018334Speter
13118334Speter   Other chains through the same elements connect the elements which
13218334Speter   currently have equivalent values.
13318334Speter
13418334Speter   Register references in an expression are canonicalized before hashing
13590075Sobrien   the expression.  This is done using `reg_qty' and qty_table `first_reg'.
13618334Speter   The hash code of a register reference is computed using the quantity
13718334Speter   number, not the register number.
13818334Speter
13918334Speter   When the value of an expression changes, it is necessary to remove from the
14018334Speter   hash table not just that expression but all expressions whose values
14118334Speter   could be different as a result.
14218334Speter
14318334Speter     1. If the value changing is in memory, except in special cases
14418334Speter     ANYTHING referring to memory could be changed.  That is because
14518334Speter     nobody knows where a pointer does not point.
14618334Speter     The function `invalidate_memory' removes what is necessary.
14718334Speter
14818334Speter     The special cases are when the address is constant or is
14918334Speter     a constant plus a fixed register such as the frame pointer
15018334Speter     or a static chain pointer.  When such addresses are stored in,
15118334Speter     we can tell exactly which other such addresses must be invalidated
15218334Speter     due to overlap.  `invalidate' does this.
15318334Speter     All expressions that refer to non-constant
15418334Speter     memory addresses are also invalidated.  `invalidate_memory' does this.
15518334Speter
15618334Speter     2. If the value changing is a register, all expressions
15718334Speter     containing references to that register, and only those,
15818334Speter     must be removed.
15918334Speter
16018334Speter   Because searching the entire hash table for expressions that contain
16118334Speter   a register is very slow, we try to figure out when it isn't necessary.
16218334Speter   Precisely, this is necessary only when expressions have been
16318334Speter   entered in the hash table using this register, and then the value has
16418334Speter   changed, and then another expression wants to be added to refer to
16518334Speter   the register's new value.  This sequence of circumstances is rare
16618334Speter   within any one basic block.
16718334Speter
16818334Speter   The vectors `reg_tick' and `reg_in_table' are used to detect this case.
16918334Speter   reg_tick[i] is incremented whenever a value is stored in register i.
17018334Speter   reg_in_table[i] holds -1 if no references to register i have been
17118334Speter   entered in the table; otherwise, it contains the value reg_tick[i] had
17218334Speter   when the references were entered.  If we want to enter a reference
17318334Speter   and reg_in_table[i] != reg_tick[i], we must scan and remove old references.
17418334Speter   Until we want to enter a new entry, the mere fact that the two vectors
17518334Speter   don't match makes the entries be ignored if anyone tries to match them.
17618334Speter
17718334Speter   Registers themselves are entered in the hash table as well as in
17818334Speter   the equivalent-register chains.  However, the vectors `reg_tick'
17918334Speter   and `reg_in_table' do not apply to expressions which are simple
18018334Speter   register references.  These expressions are removed from the table
18118334Speter   immediately when they become invalid, and this can be done even if
18218334Speter   we do not immediately search for all the expressions that refer to
18318334Speter   the register.
18418334Speter
18518334Speter   A CLOBBER rtx in an instruction invalidates its operand for further
18618334Speter   reuse.  A CLOBBER or SET rtx whose operand is a MEM:BLK
18718334Speter   invalidates everything that resides in memory.
18818334Speter
18918334SpeterRelated expressions:
19018334Speter
19118334Speter   Constant expressions that differ only by an additive integer
19218334Speter   are called related.  When a constant expression is put in
19318334Speter   the table, the related expression with no constant term
19418334Speter   is also entered.  These are made to point at each other
19518334Speter   so that it is possible to find out if there exists any
19618334Speter   register equivalent to an expression related to a given expression.  */
19790075Sobrien
19818334Speter/* One plus largest register number used in this function.  */
19918334Speter
20018334Speterstatic int max_reg;
20118334Speter
20250397Sobrien/* One plus largest instruction UID used in this function at time of
20350397Sobrien   cse_main call.  */
20450397Sobrien
20550397Sobrienstatic int max_insn_uid;
20650397Sobrien
20790075Sobrien/* Length of qty_table vector.  We know in advance we will not need
20890075Sobrien   a quantity number this big.  */
20918334Speter
21018334Speterstatic int max_qty;
21118334Speter
21218334Speter/* Next quantity number to be allocated.
21318334Speter   This is 1 + the largest number needed so far.  */
21418334Speter
21518334Speterstatic int next_qty;
21618334Speter
21790075Sobrien/* Per-qty information tracking.
21818334Speter
21990075Sobrien   `first_reg' and `last_reg' track the head and tail of the
22090075Sobrien   chain of registers which currently contain this quantity.
22118334Speter
22290075Sobrien   `mode' contains the machine mode of this quantity.
22318334Speter
22490075Sobrien   `const_rtx' holds the rtx of the constant value of this
22590075Sobrien   quantity, if known.  A summations of the frame/arg pointer
22690075Sobrien   and a constant can also be entered here.  When this holds
22790075Sobrien   a known value, `const_insn' is the insn which stored the
22890075Sobrien   constant value.
22918334Speter
23090075Sobrien   `comparison_{code,const,qty}' are used to track when a
23190075Sobrien   comparison between a quantity and some constant or register has
23290075Sobrien   been passed.  In such a case, we know the results of the comparison
23390075Sobrien   in case we see it again.  These members record a comparison that
23490075Sobrien   is known to be true.  `comparison_code' holds the rtx code of such
23590075Sobrien   a comparison, else it is set to UNKNOWN and the other two
23690075Sobrien   comparison members are undefined.  `comparison_const' holds
23790075Sobrien   the constant being compared against, or zero if the comparison
23890075Sobrien   is not against a constant.  `comparison_qty' holds the quantity
23990075Sobrien   being compared against when the result is known.  If the comparison
24090075Sobrien   is not with a register, `comparison_qty' is -1.  */
24118334Speter
24290075Sobrienstruct qty_table_elem
24390075Sobrien{
24490075Sobrien  rtx const_rtx;
24590075Sobrien  rtx const_insn;
24690075Sobrien  rtx comparison_const;
24790075Sobrien  int comparison_qty;
24890075Sobrien  unsigned int first_reg, last_reg;
24990075Sobrien  enum machine_mode mode;
25090075Sobrien  enum rtx_code comparison_code;
25190075Sobrien};
25218334Speter
25390075Sobrien/* The table of all qtys, indexed by qty number.  */
25490075Sobrienstatic struct qty_table_elem *qty_table;
25518334Speter
25618334Speter#ifdef HAVE_cc0
25718334Speter/* For machines that have a CC0, we do not record its value in the hash
25818334Speter   table since its use is guaranteed to be the insn immediately following
25918334Speter   its definition and any other insn is presumed to invalidate it.
26018334Speter
26118334Speter   Instead, we store below the value last assigned to CC0.  If it should
26218334Speter   happen to be a constant, it is stored in preference to the actual
26318334Speter   assigned value.  In case it is a constant, we store the mode in which
26418334Speter   the constant should be interpreted.  */
26518334Speter
26618334Speterstatic rtx prev_insn_cc0;
26718334Speterstatic enum machine_mode prev_insn_cc0_mode;
26818334Speter#endif
26918334Speter
27018334Speter/* Previous actual insn.  0 if at first insn of basic block.  */
27118334Speter
27218334Speterstatic rtx prev_insn;
27318334Speter
27418334Speter/* Insn being scanned.  */
27518334Speter
27618334Speterstatic rtx this_insn;
27718334Speter
27850397Sobrien/* Index by register number, gives the number of the next (or
27950397Sobrien   previous) register in the chain of registers sharing the same
28018334Speter   value.
28118334Speter
28218334Speter   Or -1 if this register is at the end of the chain.
28318334Speter
28490075Sobrien   If reg_qty[N] == N, reg_eqv_table[N].next is undefined.  */
28518334Speter
28690075Sobrien/* Per-register equivalence chain.  */
28790075Sobrienstruct reg_eqv_elem
28890075Sobrien{
28990075Sobrien  int next, prev;
29090075Sobrien};
29118334Speter
29290075Sobrien/* The table of all register equivalence chains.  */
29390075Sobrienstatic struct reg_eqv_elem *reg_eqv_table;
29418334Speter
29590075Sobrienstruct cse_reg_info
29690075Sobrien{
29790075Sobrien  /* Next in hash chain.  */
29890075Sobrien  struct cse_reg_info *hash_next;
29990075Sobrien
30090075Sobrien  /* The next cse_reg_info structure in the free or used list.  */
30190075Sobrien  struct cse_reg_info *next;
30290075Sobrien
30390075Sobrien  /* Search key */
30490075Sobrien  unsigned int regno;
30590075Sobrien
30690075Sobrien  /* The quantity number of the register's current contents.  */
30790075Sobrien  int reg_qty;
30890075Sobrien
30990075Sobrien  /* The number of times the register has been altered in the current
31090075Sobrien     basic block.  */
31190075Sobrien  int reg_tick;
31290075Sobrien
31352284Sobrien  /* The REG_TICK value at which rtx's containing this register are
31452284Sobrien     valid in the hash table.  If this does not equal the current
31552284Sobrien     reg_tick value, such expressions existing in the hash table are
31652284Sobrien     invalid.  */
31752284Sobrien  int reg_in_table;
31852284Sobrien};
31918334Speter
32052284Sobrien/* A free list of cse_reg_info entries.  */
32152284Sobrienstatic struct cse_reg_info *cse_reg_info_free_list;
32218334Speter
32390075Sobrien/* A used list of cse_reg_info entries.  */
32490075Sobrienstatic struct cse_reg_info *cse_reg_info_used_list;
32590075Sobrienstatic struct cse_reg_info *cse_reg_info_used_list_end;
32690075Sobrien
32752284Sobrien/* A mapping from registers to cse_reg_info data structures.  */
32890075Sobrien#define REGHASH_SHIFT	7
32990075Sobrien#define REGHASH_SIZE	(1 << REGHASH_SHIFT)
33090075Sobrien#define REGHASH_MASK	(REGHASH_SIZE - 1)
33190075Sobrienstatic struct cse_reg_info *reg_hash[REGHASH_SIZE];
33252284Sobrien
33390075Sobrien#define REGHASH_FN(REGNO)	\
33490075Sobrien	(((REGNO) ^ ((REGNO) >> REGHASH_SHIFT)) & REGHASH_MASK)
33590075Sobrien
33652284Sobrien/* The last lookup we did into the cse_reg_info_tree.  This allows us
33752284Sobrien   to cache repeated lookups.  */
33890075Sobrienstatic unsigned int cached_regno;
33952284Sobrienstatic struct cse_reg_info *cached_cse_reg_info;
34052284Sobrien
34190075Sobrien/* A HARD_REG_SET containing all the hard registers for which there is
34218334Speter   currently a REG expression in the hash table.  Note the difference
34318334Speter   from the above variables, which indicate if the REG is mentioned in some
34418334Speter   expression in the table.  */
34518334Speter
34618334Speterstatic HARD_REG_SET hard_regs_in_table;
34718334Speter
34818334Speter/* CUID of insn that starts the basic block currently being cse-processed.  */
34918334Speter
35018334Speterstatic int cse_basic_block_start;
35118334Speter
35218334Speter/* CUID of insn that ends the basic block currently being cse-processed.  */
35318334Speter
35418334Speterstatic int cse_basic_block_end;
35518334Speter
35618334Speter/* Vector mapping INSN_UIDs to cuids.
35718334Speter   The cuids are like uids but increase monotonically always.
35818334Speter   We use them to see whether a reg is used outside a given basic block.  */
35918334Speter
36018334Speterstatic int *uid_cuid;
36118334Speter
36218334Speter/* Highest UID in UID_CUID.  */
36318334Speterstatic int max_uid;
36418334Speter
36518334Speter/* Get the cuid of an insn.  */
36618334Speter
36718334Speter#define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])
36818334Speter
36990075Sobrien/* Nonzero if this pass has made changes, and therefore it's
37090075Sobrien   worthwhile to run the garbage collector.  */
37190075Sobrien
37290075Sobrienstatic int cse_altered;
37390075Sobrien
37418334Speter/* Nonzero if cse has altered conditional jump insns
37518334Speter   in such a way that jump optimization should be redone.  */
37618334Speter
37718334Speterstatic int cse_jumps_altered;
37818334Speter
37990075Sobrien/* Nonzero if we put a LABEL_REF into the hash table for an INSN without a
38090075Sobrien   REG_LABEL, we have to rerun jump after CSE to put in the note.  */
38118334Speterstatic int recorded_label_ref;
38218334Speter
38318334Speter/* canon_hash stores 1 in do_not_record
38418334Speter   if it notices a reference to CC0, PC, or some other volatile
38518334Speter   subexpression.  */
38618334Speter
38718334Speterstatic int do_not_record;
38818334Speter
38918334Speter#ifdef LOAD_EXTEND_OP
39018334Speter
39118334Speter/* Scratch rtl used when looking for load-extended copy of a MEM.  */
39218334Speterstatic rtx memory_extend_rtx;
39318334Speter#endif
39418334Speter
39518334Speter/* canon_hash stores 1 in hash_arg_in_memory
39618334Speter   if it notices a reference to memory within the expression being hashed.  */
39718334Speter
39818334Speterstatic int hash_arg_in_memory;
39918334Speter
40018334Speter/* The hash table contains buckets which are chains of `struct table_elt's,
40118334Speter   each recording one expression's information.
40218334Speter   That expression is in the `exp' field.
40318334Speter
40490075Sobrien   The canon_exp field contains a canonical (from the point of view of
40590075Sobrien   alias analysis) version of the `exp' field.
40690075Sobrien
40718334Speter   Those elements with the same hash code are chained in both directions
40818334Speter   through the `next_same_hash' and `prev_same_hash' fields.
40918334Speter
41018334Speter   Each set of expressions with equivalent values
41118334Speter   are on a two-way chain through the `next_same_value'
41218334Speter   and `prev_same_value' fields, and all point with
41318334Speter   the `first_same_value' field at the first element in
41418334Speter   that chain.  The chain is in order of increasing cost.
41518334Speter   Each element's cost value is in its `cost' field.
41618334Speter
41718334Speter   The `in_memory' field is nonzero for elements that
41818334Speter   involve any reference to memory.  These elements are removed
41918334Speter   whenever a write is done to an unidentified location in memory.
42018334Speter   To be safe, we assume that a memory address is unidentified unless
42118334Speter   the address is either a symbol constant or a constant plus
42218334Speter   the frame pointer or argument pointer.
42318334Speter
42418334Speter   The `related_value' field is used to connect related expressions
42518334Speter   (that differ by adding an integer).
42618334Speter   The related expressions are chained in a circular fashion.
42718334Speter   `related_value' is zero for expressions for which this
42818334Speter   chain is not useful.
42918334Speter
43018334Speter   The `cost' field stores the cost of this element's expression.
43190075Sobrien   The `regcost' field stores the value returned by approx_reg_cost for
43290075Sobrien   this element's expression.
43318334Speter
43418334Speter   The `is_const' flag is set if the element is a constant (including
43518334Speter   a fixed address).
43618334Speter
43718334Speter   The `flag' field is used as a temporary during some search routines.
43818334Speter
43918334Speter   The `mode' field is usually the same as GET_MODE (`exp'), but
44018334Speter   if `exp' is a CONST_INT and has no machine mode then the `mode'
44118334Speter   field is the mode it was being used as.  Each constant is
44218334Speter   recorded separately for each mode it is used with.  */
44318334Speter
44418334Speterstruct table_elt
44518334Speter{
44618334Speter  rtx exp;
44790075Sobrien  rtx canon_exp;
44818334Speter  struct table_elt *next_same_hash;
44918334Speter  struct table_elt *prev_same_hash;
45018334Speter  struct table_elt *next_same_value;
45118334Speter  struct table_elt *prev_same_value;
45218334Speter  struct table_elt *first_same_value;
45318334Speter  struct table_elt *related_value;
45418334Speter  int cost;
45590075Sobrien  int regcost;
45618334Speter  enum machine_mode mode;
45718334Speter  char in_memory;
45818334Speter  char is_const;
45918334Speter  char flag;
46018334Speter};
46118334Speter
46218334Speter/* We don't want a lot of buckets, because we rarely have very many
46318334Speter   things stored in the hash table, and a lot of buckets slows
46418334Speter   down a lot of loops that happen frequently.  */
46590075Sobrien#define HASH_SHIFT	5
46690075Sobrien#define HASH_SIZE	(1 << HASH_SHIFT)
46790075Sobrien#define HASH_MASK	(HASH_SIZE - 1)
46818334Speter
46918334Speter/* Compute hash code of X in mode M.  Special-case case where X is a pseudo
47018334Speter   register (hard registers may require `do_not_record' to be set).  */
47118334Speter
47218334Speter#define HASH(X, M)	\
47390075Sobrien ((GET_CODE (X) == REG && REGNO (X) >= FIRST_PSEUDO_REGISTER	\
47490075Sobrien  ? (((unsigned) REG << 7) + (unsigned) REG_QTY (REGNO (X)))	\
47590075Sobrien  : canon_hash (X, M)) & HASH_MASK)
47618334Speter
47790075Sobrien/* Determine whether register number N is considered a fixed register for the
47890075Sobrien   purpose of approximating register costs.
47918334Speter   It is desirable to replace other regs with fixed regs, to reduce need for
48018334Speter   non-fixed hard regs.
48190075Sobrien   A reg wins if it is either the frame pointer or designated as fixed.  */
48218334Speter#define FIXED_REGNO_P(N)  \
48318334Speter  ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \
48418334Speter   || fixed_regs[N] || global_regs[N])
48518334Speter
48618334Speter/* Compute cost of X, as stored in the `cost' field of a table_elt.  Fixed
48718334Speter   hard registers and pointers into the frame are the cheapest with a cost
48818334Speter   of 0.  Next come pseudos with a cost of one and other hard registers with
48918334Speter   a cost of 2.  Aside from these special cases, call `rtx_cost'.  */
49018334Speter
49118334Speter#define CHEAP_REGNO(N) \
49218334Speter  ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM 	\
49318334Speter   || (N) == STACK_POINTER_REGNUM || (N) == ARG_POINTER_REGNUM	     	\
49418334Speter   || ((N) >= FIRST_VIRTUAL_REGISTER && (N) <= LAST_VIRTUAL_REGISTER) 	\
49518334Speter   || ((N) < FIRST_PSEUDO_REGISTER					\
49618334Speter       && FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS))
49718334Speter
49890075Sobrien#define COST(X) (GET_CODE (X) == REG ? 0 : notreg_cost (X, SET))
49990075Sobrien#define COST_IN(X,OUTER) (GET_CODE (X) == REG ? 0 : notreg_cost (X, OUTER))
50018334Speter
50152284Sobrien/* Get the info associated with register N.  */
50252284Sobrien
50352284Sobrien#define GET_CSE_REG_INFO(N) 			\
50452284Sobrien  (((N) == cached_regno && cached_cse_reg_info)	\
50552284Sobrien   ? cached_cse_reg_info : get_cse_reg_info ((N)))
50652284Sobrien
50752284Sobrien/* Get the number of times this register has been updated in this
50852284Sobrien   basic block.  */
50952284Sobrien
51090075Sobrien#define REG_TICK(N) ((GET_CSE_REG_INFO (N))->reg_tick)
51152284Sobrien
51252284Sobrien/* Get the point at which REG was recorded in the table.  */
51352284Sobrien
51452284Sobrien#define REG_IN_TABLE(N) ((GET_CSE_REG_INFO (N))->reg_in_table)
51552284Sobrien
51652284Sobrien/* Get the quantity number for REG.  */
51752284Sobrien
51852284Sobrien#define REG_QTY(N) ((GET_CSE_REG_INFO (N))->reg_qty)
51952284Sobrien
52018334Speter/* Determine if the quantity number for register X represents a valid index
52190075Sobrien   into the qty_table.  */
52218334Speter
52390075Sobrien#define REGNO_QTY_VALID_P(N) (REG_QTY (N) != (int) (N))
52418334Speter
52590075Sobrienstatic struct table_elt *table[HASH_SIZE];
52650397Sobrien
52718334Speter/* Chain of `struct table_elt's made so far for this function
52818334Speter   but currently removed from the table.  */
52918334Speter
53018334Speterstatic struct table_elt *free_element_chain;
53118334Speter
53218334Speter/* Number of `struct table_elt' structures made so far for this function.  */
53318334Speter
53418334Speterstatic int n_elements_made;
53518334Speter
53618334Speter/* Maximum value `n_elements_made' has had so far in this compilation
53718334Speter   for functions previously processed.  */
53818334Speter
53918334Speterstatic int max_elements_made;
54018334Speter
54190075Sobrien/* Surviving equivalence class when two equivalence classes are merged
54218334Speter   by recording the effects of a jump in the last insn.  Zero if the
54318334Speter   last insn was not a conditional jump.  */
54418334Speter
54518334Speterstatic struct table_elt *last_jump_equiv_class;
54618334Speter
54718334Speter/* Set to the cost of a constant pool reference if one was found for a
54818334Speter   symbolic constant.  If this was found, it means we should try to
54918334Speter   convert constants into constant pool entries if they don't fit in
55018334Speter   the insn.  */
55118334Speter
55218334Speterstatic int constant_pool_entries_cost;
55318334Speter
55418334Speter/* Define maximum length of a branch path.  */
55518334Speter
55618334Speter#define PATHLENGTH	10
55718334Speter
55818334Speter/* This data describes a block that will be processed by cse_basic_block.  */
55918334Speter
56090075Sobrienstruct cse_basic_block_data
56190075Sobrien{
56218334Speter  /* Lowest CUID value of insns in block.  */
56318334Speter  int low_cuid;
56418334Speter  /* Highest CUID value of insns in block.  */
56518334Speter  int high_cuid;
56618334Speter  /* Total number of SETs in block.  */
56718334Speter  int nsets;
56818334Speter  /* Last insn in the block.  */
56918334Speter  rtx last;
57018334Speter  /* Size of current branch path, if any.  */
57118334Speter  int path_size;
57218334Speter  /* Current branch path, indicating which branches will be taken.  */
57390075Sobrien  struct branch_path
57490075Sobrien    {
57590075Sobrien      /* The branch insn.  */
57690075Sobrien      rtx branch;
57790075Sobrien      /* Whether it should be taken or not.  AROUND is the same as taken
57890075Sobrien	 except that it is used when the destination label is not preceded
57918334Speter       by a BARRIER.  */
58090075Sobrien      enum taken {TAKEN, NOT_TAKEN, AROUND} status;
58190075Sobrien    } path[PATHLENGTH];
58218334Speter};
58318334Speter
58418334Speter/* Nonzero if X has the form (PLUS frame-pointer integer).  We check for
58518334Speter   virtual regs here because the simplify_*_operation routines are called
58690075Sobrien   by integrate.c, which is called before virtual register instantiation.
58718334Speter
58890075Sobrien   ?!? FIXED_BASE_PLUS_P and NONZERO_BASE_PLUS_P need to move into
58990075Sobrien   a header file so that their definitions can be shared with the
59090075Sobrien   simplification routines in simplify-rtx.c.  Until then, do not
59190075Sobrien   change these macros without also changing the copy in simplify-rtx.c.  */
59290075Sobrien
59318334Speter#define FIXED_BASE_PLUS_P(X)					\
59418334Speter  ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx	\
59590075Sobrien   || ((X) == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM])\
59618334Speter   || (X) == virtual_stack_vars_rtx				\
59718334Speter   || (X) == virtual_incoming_args_rtx				\
59818334Speter   || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
59918334Speter       && (XEXP (X, 0) == frame_pointer_rtx			\
60018334Speter	   || XEXP (X, 0) == hard_frame_pointer_rtx		\
60190075Sobrien	   || ((X) == arg_pointer_rtx				\
60290075Sobrien	       && fixed_regs[ARG_POINTER_REGNUM])		\
60318334Speter	   || XEXP (X, 0) == virtual_stack_vars_rtx		\
60450397Sobrien	   || XEXP (X, 0) == virtual_incoming_args_rtx))	\
60550397Sobrien   || GET_CODE (X) == ADDRESSOF)
60618334Speter
60718334Speter/* Similar, but also allows reference to the stack pointer.
60818334Speter
60918334Speter   This used to include FIXED_BASE_PLUS_P, however, we can't assume that
61018334Speter   arg_pointer_rtx by itself is nonzero, because on at least one machine,
61118334Speter   the i960, the arg pointer is zero when it is unused.  */
61218334Speter
61318334Speter#define NONZERO_BASE_PLUS_P(X)					\
61418334Speter  ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx	\
61518334Speter   || (X) == virtual_stack_vars_rtx				\
61618334Speter   || (X) == virtual_incoming_args_rtx				\
61718334Speter   || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
61818334Speter       && (XEXP (X, 0) == frame_pointer_rtx			\
61918334Speter	   || XEXP (X, 0) == hard_frame_pointer_rtx		\
62090075Sobrien	   || ((X) == arg_pointer_rtx				\
62190075Sobrien	       && fixed_regs[ARG_POINTER_REGNUM])		\
62218334Speter	   || XEXP (X, 0) == virtual_stack_vars_rtx		\
62318334Speter	   || XEXP (X, 0) == virtual_incoming_args_rtx))	\
62418334Speter   || (X) == stack_pointer_rtx					\
62518334Speter   || (X) == virtual_stack_dynamic_rtx				\
62618334Speter   || (X) == virtual_outgoing_args_rtx				\
62718334Speter   || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
62818334Speter       && (XEXP (X, 0) == stack_pointer_rtx			\
62918334Speter	   || XEXP (X, 0) == virtual_stack_dynamic_rtx		\
63050397Sobrien	   || XEXP (X, 0) == virtual_outgoing_args_rtx))	\
63150397Sobrien   || GET_CODE (X) == ADDRESSOF)
63218334Speter
63390075Sobrienstatic int notreg_cost		PARAMS ((rtx, enum rtx_code));
63490075Sobrienstatic int approx_reg_cost_1	PARAMS ((rtx *, void *));
63590075Sobrienstatic int approx_reg_cost	PARAMS ((rtx));
63690075Sobrienstatic int preferrable		PARAMS ((int, int, int, int));
63790075Sobrienstatic void new_basic_block	PARAMS ((void));
63890075Sobrienstatic void make_new_qty	PARAMS ((unsigned int, enum machine_mode));
63990075Sobrienstatic void make_regs_eqv	PARAMS ((unsigned int, unsigned int));
64090075Sobrienstatic void delete_reg_equiv	PARAMS ((unsigned int));
64190075Sobrienstatic int mention_regs		PARAMS ((rtx));
64290075Sobrienstatic int insert_regs		PARAMS ((rtx, struct table_elt *, int));
64390075Sobrienstatic void remove_from_table	PARAMS ((struct table_elt *, unsigned));
64490075Sobrienstatic struct table_elt *lookup	PARAMS ((rtx, unsigned, enum machine_mode)),
64590075Sobrien       *lookup_for_remove PARAMS ((rtx, unsigned, enum machine_mode));
64690075Sobrienstatic rtx lookup_as_function	PARAMS ((rtx, enum rtx_code));
64790075Sobrienstatic struct table_elt *insert PARAMS ((rtx, struct table_elt *, unsigned,
64890075Sobrien					 enum machine_mode));
64990075Sobrienstatic void merge_equiv_classes PARAMS ((struct table_elt *,
65090075Sobrien					 struct table_elt *));
65190075Sobrienstatic void invalidate		PARAMS ((rtx, enum machine_mode));
65290075Sobrienstatic int cse_rtx_varies_p	PARAMS ((rtx, int));
65390075Sobrienstatic void remove_invalid_refs	PARAMS ((unsigned int));
65490075Sobrienstatic void remove_invalid_subreg_refs	PARAMS ((unsigned int, unsigned int,
65590075Sobrien						 enum machine_mode));
65690075Sobrienstatic void rehash_using_reg	PARAMS ((rtx));
65790075Sobrienstatic void invalidate_memory	PARAMS ((void));
65890075Sobrienstatic void invalidate_for_call	PARAMS ((void));
65990075Sobrienstatic rtx use_related_value	PARAMS ((rtx, struct table_elt *));
66090075Sobrienstatic unsigned canon_hash	PARAMS ((rtx, enum machine_mode));
66190075Sobrienstatic unsigned canon_hash_string PARAMS ((const char *));
66290075Sobrienstatic unsigned safe_hash	PARAMS ((rtx, enum machine_mode));
66390075Sobrienstatic int exp_equiv_p		PARAMS ((rtx, rtx, int, int));
66490075Sobrienstatic rtx canon_reg		PARAMS ((rtx, rtx));
66590075Sobrienstatic void find_best_addr	PARAMS ((rtx, rtx *, enum machine_mode));
66690075Sobrienstatic enum rtx_code find_comparison_args PARAMS ((enum rtx_code, rtx *, rtx *,
66790075Sobrien						   enum machine_mode *,
66890075Sobrien						   enum machine_mode *));
66990075Sobrienstatic rtx fold_rtx		PARAMS ((rtx, rtx));
67090075Sobrienstatic rtx equiv_constant	PARAMS ((rtx));
67190075Sobrienstatic void record_jump_equiv	PARAMS ((rtx, int));
67290075Sobrienstatic void record_jump_cond	PARAMS ((enum rtx_code, enum machine_mode,
67390075Sobrien					 rtx, rtx, int));
67490075Sobrienstatic void cse_insn		PARAMS ((rtx, rtx));
67590075Sobrienstatic int addr_affects_sp_p	PARAMS ((rtx));
67690075Sobrienstatic void invalidate_from_clobbers PARAMS ((rtx));
67790075Sobrienstatic rtx cse_process_notes	PARAMS ((rtx, rtx));
67890075Sobrienstatic void cse_around_loop	PARAMS ((rtx));
67990075Sobrienstatic void invalidate_skipped_set PARAMS ((rtx, rtx, void *));
68090075Sobrienstatic void invalidate_skipped_block PARAMS ((rtx));
68190075Sobrienstatic void cse_check_loop_start PARAMS ((rtx, rtx, void *));
68290075Sobrienstatic void cse_set_around_loop	PARAMS ((rtx, rtx, rtx));
68390075Sobrienstatic rtx cse_basic_block	PARAMS ((rtx, rtx, struct branch_path *, int));
68490075Sobrienstatic void count_reg_usage	PARAMS ((rtx, int *, rtx, int));
68590075Sobrienstatic int check_for_label_ref	PARAMS ((rtx *, void *));
68690075Sobrienextern void dump_class          PARAMS ((struct table_elt*));
68790075Sobrienstatic struct cse_reg_info * get_cse_reg_info PARAMS ((unsigned int));
68890075Sobrienstatic int check_dependence	PARAMS ((rtx *, void *));
68918334Speter
69090075Sobrienstatic void flush_hash_table	PARAMS ((void));
69190075Sobrienstatic bool insn_live_p		PARAMS ((rtx, int *));
69290075Sobrienstatic bool set_live_p		PARAMS ((rtx, rtx, int *));
69390075Sobrienstatic bool dead_libcall_p	PARAMS ((rtx));
69418334Speter
69552284Sobrien/* Dump the expressions in the equivalence class indicated by CLASSP.
69652284Sobrien   This function is used only for debugging.  */
69752284Sobrienvoid
69852284Sobriendump_class (classp)
69952284Sobrien     struct table_elt *classp;
70052284Sobrien{
70152284Sobrien  struct table_elt *elt;
70252284Sobrien
70352284Sobrien  fprintf (stderr, "Equivalence chain for ");
70452284Sobrien  print_rtl (stderr, classp->exp);
70552284Sobrien  fprintf (stderr, ": \n");
70690075Sobrien
70752284Sobrien  for (elt = classp->first_same_value; elt; elt = elt->next_same_value)
70852284Sobrien    {
70952284Sobrien      print_rtl (stderr, elt->exp);
71052284Sobrien      fprintf (stderr, "\n");
71152284Sobrien    }
71252284Sobrien}
71352284Sobrien
71490075Sobrien/* Subroutine of approx_reg_cost; called through for_each_rtx.  */
71518334Speter
71690075Sobrienstatic int
71790075Sobrienapprox_reg_cost_1 (xp, data)
71890075Sobrien     rtx *xp;
71990075Sobrien     void *data;
72090075Sobrien{
72190075Sobrien  rtx x = *xp;
72290075Sobrien  regset set = (regset) data;
72390075Sobrien
72490075Sobrien  if (x && GET_CODE (x) == REG)
72590075Sobrien    SET_REGNO_REG_SET (set, REGNO (x));
72690075Sobrien  return 0;
72790075Sobrien}
72890075Sobrien
72990075Sobrien/* Return an estimate of the cost of the registers used in an rtx.
73090075Sobrien   This is mostly the number of different REG expressions in the rtx;
73190075Sobrien   however for some exceptions like fixed registers we use a cost of
73290075Sobrien   0.  If any other hard register reference occurs, return MAX_COST.  */
73390075Sobrien
73490075Sobrienstatic int
73590075Sobrienapprox_reg_cost (x)
73690075Sobrien     rtx x;
73790075Sobrien{
73890075Sobrien  regset_head set;
73990075Sobrien  int i;
74090075Sobrien  int cost = 0;
74190075Sobrien  int hardregs = 0;
74290075Sobrien
74390075Sobrien  INIT_REG_SET (&set);
74490075Sobrien  for_each_rtx (&x, approx_reg_cost_1, (void *)&set);
74590075Sobrien
74690075Sobrien  EXECUTE_IF_SET_IN_REG_SET
74790075Sobrien    (&set, 0, i,
74890075Sobrien     {
74990075Sobrien       if (! CHEAP_REGNO (i))
75090075Sobrien	 {
75190075Sobrien	   if (i < FIRST_PSEUDO_REGISTER)
75290075Sobrien	     hardregs++;
75390075Sobrien
75490075Sobrien	   cost += i < FIRST_PSEUDO_REGISTER ? 2 : 1;
75590075Sobrien	 }
75690075Sobrien     });
75790075Sobrien
75890075Sobrien  CLEAR_REG_SET (&set);
75990075Sobrien  return hardregs && SMALL_REGISTER_CLASSES ? MAX_COST : cost;
76090075Sobrien}
76190075Sobrien
76290075Sobrien/* Return a negative value if an rtx A, whose costs are given by COST_A
76390075Sobrien   and REGCOST_A, is more desirable than an rtx B.
76490075Sobrien   Return a positive value if A is less desirable, or 0 if the two are
76590075Sobrien   equally good.  */
76690075Sobrienstatic int
76790075Sobrienpreferrable (cost_a, regcost_a, cost_b, regcost_b)
76890075Sobrien     int cost_a, regcost_a, cost_b, regcost_b;
76990075Sobrien{
77090075Sobrien  /* First, get rid of a cases involving expressions that are entirely
77190075Sobrien     unwanted.  */
77290075Sobrien  if (cost_a != cost_b)
77390075Sobrien    {
77490075Sobrien      if (cost_a == MAX_COST)
77590075Sobrien	return 1;
77690075Sobrien      if (cost_b == MAX_COST)
77790075Sobrien	return -1;
77890075Sobrien    }
77990075Sobrien
78090075Sobrien  /* Avoid extending lifetimes of hardregs.  */
78190075Sobrien  if (regcost_a != regcost_b)
78290075Sobrien    {
78390075Sobrien      if (regcost_a == MAX_COST)
78490075Sobrien	return 1;
78590075Sobrien      if (regcost_b == MAX_COST)
78690075Sobrien	return -1;
78790075Sobrien    }
78890075Sobrien
78990075Sobrien  /* Normal operation costs take precedence.  */
79090075Sobrien  if (cost_a != cost_b)
79190075Sobrien    return cost_a - cost_b;
79290075Sobrien  /* Only if these are identical consider effects on register pressure.  */
79390075Sobrien  if (regcost_a != regcost_b)
79490075Sobrien    return regcost_a - regcost_b;
79590075Sobrien  return 0;
79690075Sobrien}
79790075Sobrien
79850397Sobrien/* Internal function, to compute cost when X is not a register; called
79950397Sobrien   from COST macro to keep it simple.  */
80050397Sobrien
80150397Sobrienstatic int
80290075Sobriennotreg_cost (x, outer)
80350397Sobrien     rtx x;
80490075Sobrien     enum rtx_code outer;
80550397Sobrien{
80650397Sobrien  return ((GET_CODE (x) == SUBREG
80750397Sobrien	   && GET_CODE (SUBREG_REG (x)) == REG
80850397Sobrien	   && GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
80950397Sobrien	   && GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_INT
81050397Sobrien	   && (GET_MODE_SIZE (GET_MODE (x))
81150397Sobrien	       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
81250397Sobrien	   && subreg_lowpart_p (x)
81350397Sobrien	   && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (x)),
81450397Sobrien				     GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))))
81590075Sobrien	  ? 0
81690075Sobrien	  : rtx_cost (x, outer) * 2);
81750397Sobrien}
81850397Sobrien
81990075Sobrien/* Return an estimate of the cost of computing rtx X.
82090075Sobrien   One use is in cse, to decide which expression to keep in the hash table.
82190075Sobrien   Another is in rtl generation, to pick the cheapest way to multiply.
82290075Sobrien   Other uses like the latter are expected in the future.  */
82318334Speter
82418334Speterint
82518334Speterrtx_cost (x, outer_code)
82618334Speter     rtx x;
82752284Sobrien     enum rtx_code outer_code ATTRIBUTE_UNUSED;
82818334Speter{
82990075Sobrien  int i, j;
83090075Sobrien  enum rtx_code code;
83190075Sobrien  const char *fmt;
83290075Sobrien  int total;
83318334Speter
83418334Speter  if (x == 0)
83518334Speter    return 0;
83618334Speter
83718334Speter  /* Compute the default costs of certain things.
83818334Speter     Note that RTX_COSTS can override the defaults.  */
83918334Speter
84018334Speter  code = GET_CODE (x);
84118334Speter  switch (code)
84218334Speter    {
84318334Speter    case MULT:
84418334Speter      /* Count multiplication by 2**n as a shift,
84518334Speter	 because if we are considering it, we would output it as a shift.  */
84618334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
84718334Speter	  && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
84818334Speter	total = 2;
84918334Speter      else
85018334Speter	total = COSTS_N_INSNS (5);
85118334Speter      break;
85218334Speter    case DIV:
85318334Speter    case UDIV:
85418334Speter    case MOD:
85518334Speter    case UMOD:
85618334Speter      total = COSTS_N_INSNS (7);
85718334Speter      break;
85818334Speter    case USE:
85918334Speter      /* Used in loop.c and combine.c as a marker.  */
86018334Speter      total = 0;
86118334Speter      break;
86218334Speter    default:
86390075Sobrien      total = COSTS_N_INSNS (1);
86418334Speter    }
86518334Speter
86618334Speter  switch (code)
86718334Speter    {
86818334Speter    case REG:
86990075Sobrien      return 0;
87018334Speter
87118334Speter    case SUBREG:
87218334Speter      /* If we can't tie these modes, make this expensive.  The larger
87318334Speter	 the mode, the more expensive it is.  */
87418334Speter      if (! MODES_TIEABLE_P (GET_MODE (x), GET_MODE (SUBREG_REG (x))))
87518334Speter	return COSTS_N_INSNS (2
87618334Speter			      + GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD);
87790075Sobrien      break;
87890075Sobrien
87918334Speter#ifdef RTX_COSTS
88018334Speter      RTX_COSTS (x, code, outer_code);
88190075Sobrien#endif
88250397Sobrien#ifdef CONST_COSTS
88318334Speter      CONST_COSTS (x, code, outer_code);
88450397Sobrien#endif
88550397Sobrien
88650397Sobrien    default:
88750397Sobrien#ifdef DEFAULT_RTX_COSTS
88890075Sobrien      DEFAULT_RTX_COSTS (x, code, outer_code);
88950397Sobrien#endif
89050397Sobrien      break;
89118334Speter    }
89218334Speter
89318334Speter  /* Sum the costs of the sub-rtx's, plus cost of this operation,
89418334Speter     which is already in total.  */
89518334Speter
89618334Speter  fmt = GET_RTX_FORMAT (code);
89718334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
89818334Speter    if (fmt[i] == 'e')
89918334Speter      total += rtx_cost (XEXP (x, i), code);
90018334Speter    else if (fmt[i] == 'E')
90118334Speter      for (j = 0; j < XVECLEN (x, i); j++)
90218334Speter	total += rtx_cost (XVECEXP (x, i, j), code);
90318334Speter
90418334Speter  return total;
90518334Speter}
90618334Speter
90790075Sobrien/* Return cost of address expression X.
90890075Sobrien   Expect that X is properly formed address reference.  */
90990075Sobrien
91090075Sobrienint
91190075Sobrienaddress_cost (x, mode)
91290075Sobrien     rtx x;
91390075Sobrien     enum machine_mode mode;
91490075Sobrien{
91590075Sobrien  /* The ADDRESS_COST macro does not deal with ADDRESSOF nodes.  But,
91690075Sobrien     during CSE, such nodes are present.  Using an ADDRESSOF node which
91790075Sobrien     refers to the address of a REG is a good thing because we can then
91890075Sobrien     turn (MEM (ADDRESSSOF (REG))) into just plain REG.  */
91990075Sobrien
92090075Sobrien  if (GET_CODE (x) == ADDRESSOF && REG_P (XEXP ((x), 0)))
92190075Sobrien    return -1;
92290075Sobrien
92390075Sobrien  /* We may be asked for cost of various unusual addresses, such as operands
92490075Sobrien     of push instruction.  It is not worthwhile to complicate writing
92590075Sobrien     of ADDRESS_COST macro by such cases.  */
92690075Sobrien
92790075Sobrien  if (!memory_address_p (mode, x))
92890075Sobrien    return 1000;
92990075Sobrien#ifdef ADDRESS_COST
93090075Sobrien  return ADDRESS_COST (x);
93190075Sobrien#else
93290075Sobrien  return rtx_cost (x, MEM);
93390075Sobrien#endif
93490075Sobrien}
93590075Sobrien
93690075Sobrien
93752284Sobrienstatic struct cse_reg_info *
93852284Sobrienget_cse_reg_info (regno)
93990075Sobrien     unsigned int regno;
94052284Sobrien{
94190075Sobrien  struct cse_reg_info **hash_head = &reg_hash[REGHASH_FN (regno)];
94290075Sobrien  struct cse_reg_info *p;
94352284Sobrien
94490075Sobrien  for (p = *hash_head; p != NULL; p = p->hash_next)
94590075Sobrien    if (p->regno == regno)
94690075Sobrien      break;
94790075Sobrien
94890075Sobrien  if (p == NULL)
94952284Sobrien    {
95052284Sobrien      /* Get a new cse_reg_info structure.  */
95190075Sobrien      if (cse_reg_info_free_list)
95252284Sobrien	{
95390075Sobrien	  p = cse_reg_info_free_list;
95490075Sobrien	  cse_reg_info_free_list = p->next;
95552284Sobrien	}
95652284Sobrien      else
95790075Sobrien	p = (struct cse_reg_info *) xmalloc (sizeof (struct cse_reg_info));
95852284Sobrien
95990075Sobrien      /* Insert into hash table.  */
96090075Sobrien      p->hash_next = *hash_head;
96190075Sobrien      *hash_head = p;
96290075Sobrien
96352284Sobrien      /* Initialize it.  */
96490075Sobrien      p->reg_tick = 1;
96590075Sobrien      p->reg_in_table = -1;
96690075Sobrien      p->reg_qty = regno;
96790075Sobrien      p->regno = regno;
96890075Sobrien      p->next = cse_reg_info_used_list;
96990075Sobrien      cse_reg_info_used_list = p;
97090075Sobrien      if (!cse_reg_info_used_list_end)
97190075Sobrien	cse_reg_info_used_list_end = p;
97252284Sobrien    }
97352284Sobrien
97452284Sobrien  /* Cache this lookup; we tend to be looking up information about the
97552284Sobrien     same register several times in a row.  */
97652284Sobrien  cached_regno = regno;
97790075Sobrien  cached_cse_reg_info = p;
97852284Sobrien
97990075Sobrien  return p;
98052284Sobrien}
98152284Sobrien
98218334Speter/* Clear the hash table and initialize each register with its own quantity,
98318334Speter   for a new basic block.  */
98418334Speter
98518334Speterstatic void
98618334Speternew_basic_block ()
98718334Speter{
98890075Sobrien  int i;
98918334Speter
99018334Speter  next_qty = max_reg;
99118334Speter
99290075Sobrien  /* Clear out hash table state for this pass.  */
99390075Sobrien
99490075Sobrien  memset ((char *) reg_hash, 0, sizeof reg_hash);
99590075Sobrien
99690075Sobrien  if (cse_reg_info_used_list)
99752284Sobrien    {
99890075Sobrien      cse_reg_info_used_list_end->next = cse_reg_info_free_list;
99990075Sobrien      cse_reg_info_free_list = cse_reg_info_used_list;
100090075Sobrien      cse_reg_info_used_list = cse_reg_info_used_list_end = 0;
100152284Sobrien    }
100290075Sobrien  cached_cse_reg_info = 0;
100318334Speter
100418334Speter  CLEAR_HARD_REG_SET (hard_regs_in_table);
100518334Speter
100618334Speter  /* The per-quantity values used to be initialized here, but it is
100718334Speter     much faster to initialize each as it is made in `make_new_qty'.  */
100818334Speter
100990075Sobrien  for (i = 0; i < HASH_SIZE; i++)
101018334Speter    {
101190075Sobrien      struct table_elt *first;
101290075Sobrien
101390075Sobrien      first = table[i];
101490075Sobrien      if (first != NULL)
101518334Speter	{
101690075Sobrien	  struct table_elt *last = first;
101790075Sobrien
101890075Sobrien	  table[i] = NULL;
101990075Sobrien
102090075Sobrien	  while (last->next_same_hash != NULL)
102190075Sobrien	    last = last->next_same_hash;
102290075Sobrien
102390075Sobrien	  /* Now relink this hash entire chain into
102490075Sobrien	     the free element list.  */
102590075Sobrien
102690075Sobrien	  last->next_same_hash = free_element_chain;
102790075Sobrien	  free_element_chain = first;
102818334Speter	}
102918334Speter    }
103018334Speter
103118334Speter  prev_insn = 0;
103218334Speter
103318334Speter#ifdef HAVE_cc0
103418334Speter  prev_insn_cc0 = 0;
103518334Speter#endif
103618334Speter}
103718334Speter
103890075Sobrien/* Say that register REG contains a quantity in mode MODE not in any
103990075Sobrien   register before and initialize that quantity.  */
104018334Speter
104118334Speterstatic void
104290075Sobrienmake_new_qty (reg, mode)
104390075Sobrien     unsigned int reg;
104490075Sobrien     enum machine_mode mode;
104518334Speter{
104690075Sobrien  int q;
104790075Sobrien  struct qty_table_elem *ent;
104890075Sobrien  struct reg_eqv_elem *eqv;
104918334Speter
105018334Speter  if (next_qty >= max_qty)
105118334Speter    abort ();
105218334Speter
105352284Sobrien  q = REG_QTY (reg) = next_qty++;
105490075Sobrien  ent = &qty_table[q];
105590075Sobrien  ent->first_reg = reg;
105690075Sobrien  ent->last_reg = reg;
105790075Sobrien  ent->mode = mode;
105890075Sobrien  ent->const_rtx = ent->const_insn = NULL_RTX;
105990075Sobrien  ent->comparison_code = UNKNOWN;
106018334Speter
106190075Sobrien  eqv = &reg_eqv_table[reg];
106290075Sobrien  eqv->next = eqv->prev = -1;
106318334Speter}
106418334Speter
106518334Speter/* Make reg NEW equivalent to reg OLD.
106618334Speter   OLD is not changing; NEW is.  */
106718334Speter
106818334Speterstatic void
106918334Spetermake_regs_eqv (new, old)
107090075Sobrien     unsigned int new, old;
107118334Speter{
107290075Sobrien  unsigned int lastr, firstr;
107390075Sobrien  int q = REG_QTY (old);
107490075Sobrien  struct qty_table_elem *ent;
107518334Speter
107690075Sobrien  ent = &qty_table[q];
107790075Sobrien
107818334Speter  /* Nothing should become eqv until it has a "non-invalid" qty number.  */
107918334Speter  if (! REGNO_QTY_VALID_P (old))
108018334Speter    abort ();
108118334Speter
108252284Sobrien  REG_QTY (new) = q;
108390075Sobrien  firstr = ent->first_reg;
108490075Sobrien  lastr = ent->last_reg;
108518334Speter
108618334Speter  /* Prefer fixed hard registers to anything.  Prefer pseudo regs to other
108718334Speter     hard regs.  Among pseudos, if NEW will live longer than any other reg
108818334Speter     of the same qty, and that is beyond the current basic block,
108918334Speter     make it the new canonical replacement for this qty.  */
109018334Speter  if (! (firstr < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (firstr))
109118334Speter      /* Certain fixed registers might be of the class NO_REGS.  This means
109218334Speter	 that not only can they not be allocated by the compiler, but
109318334Speter	 they cannot be used in substitutions or canonicalizations
109418334Speter	 either.  */
109518334Speter      && (new >= FIRST_PSEUDO_REGISTER || REGNO_REG_CLASS (new) != NO_REGS)
109618334Speter      && ((new < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (new))
109718334Speter	  || (new >= FIRST_PSEUDO_REGISTER
109818334Speter	      && (firstr < FIRST_PSEUDO_REGISTER
109950397Sobrien		  || ((uid_cuid[REGNO_LAST_UID (new)] > cse_basic_block_end
110050397Sobrien		       || (uid_cuid[REGNO_FIRST_UID (new)]
110118334Speter			   < cse_basic_block_start))
110250397Sobrien		      && (uid_cuid[REGNO_LAST_UID (new)]
110350397Sobrien			  > uid_cuid[REGNO_LAST_UID (firstr)]))))))
110418334Speter    {
110590075Sobrien      reg_eqv_table[firstr].prev = new;
110690075Sobrien      reg_eqv_table[new].next = firstr;
110790075Sobrien      reg_eqv_table[new].prev = -1;
110890075Sobrien      ent->first_reg = new;
110918334Speter    }
111018334Speter  else
111118334Speter    {
111218334Speter      /* If NEW is a hard reg (known to be non-fixed), insert at end.
111318334Speter	 Otherwise, insert before any non-fixed hard regs that are at the
111418334Speter	 end.  Registers of class NO_REGS cannot be used as an
111518334Speter	 equivalent for anything.  */
111690075Sobrien      while (lastr < FIRST_PSEUDO_REGISTER && reg_eqv_table[lastr].prev >= 0
111718334Speter	     && (REGNO_REG_CLASS (lastr) == NO_REGS || ! FIXED_REGNO_P (lastr))
111818334Speter	     && new >= FIRST_PSEUDO_REGISTER)
111990075Sobrien	lastr = reg_eqv_table[lastr].prev;
112090075Sobrien      reg_eqv_table[new].next = reg_eqv_table[lastr].next;
112190075Sobrien      if (reg_eqv_table[lastr].next >= 0)
112290075Sobrien	reg_eqv_table[reg_eqv_table[lastr].next].prev = new;
112318334Speter      else
112490075Sobrien	qty_table[q].last_reg = new;
112590075Sobrien      reg_eqv_table[lastr].next = new;
112690075Sobrien      reg_eqv_table[new].prev = lastr;
112718334Speter    }
112818334Speter}
112918334Speter
113018334Speter/* Remove REG from its equivalence class.  */
113118334Speter
113218334Speterstatic void
113318334Speterdelete_reg_equiv (reg)
113490075Sobrien     unsigned int reg;
113518334Speter{
113690075Sobrien  struct qty_table_elem *ent;
113790075Sobrien  int q = REG_QTY (reg);
113890075Sobrien  int p, n;
113918334Speter
114018334Speter  /* If invalid, do nothing.  */
114190075Sobrien  if (q == (int) reg)
114218334Speter    return;
114318334Speter
114490075Sobrien  ent = &qty_table[q];
114518334Speter
114690075Sobrien  p = reg_eqv_table[reg].prev;
114790075Sobrien  n = reg_eqv_table[reg].next;
114890075Sobrien
114918334Speter  if (n != -1)
115090075Sobrien    reg_eqv_table[n].prev = p;
115118334Speter  else
115290075Sobrien    ent->last_reg = p;
115318334Speter  if (p != -1)
115490075Sobrien    reg_eqv_table[p].next = n;
115518334Speter  else
115690075Sobrien    ent->first_reg = n;
115718334Speter
115852284Sobrien  REG_QTY (reg) = reg;
115918334Speter}
116018334Speter
116118334Speter/* Remove any invalid expressions from the hash table
116218334Speter   that refer to any of the registers contained in expression X.
116318334Speter
116418334Speter   Make sure that newly inserted references to those registers
116518334Speter   as subexpressions will be considered valid.
116618334Speter
116718334Speter   mention_regs is not called when a register itself
116818334Speter   is being stored in the table.
116918334Speter
117018334Speter   Return 1 if we have done something that may have changed the hash code
117118334Speter   of X.  */
117218334Speter
117318334Speterstatic int
117418334Spetermention_regs (x)
117518334Speter     rtx x;
117618334Speter{
117790075Sobrien  enum rtx_code code;
117890075Sobrien  int i, j;
117990075Sobrien  const char *fmt;
118090075Sobrien  int changed = 0;
118118334Speter
118218334Speter  if (x == 0)
118318334Speter    return 0;
118418334Speter
118518334Speter  code = GET_CODE (x);
118618334Speter  if (code == REG)
118718334Speter    {
118890075Sobrien      unsigned int regno = REGNO (x);
118990075Sobrien      unsigned int endregno
119018334Speter	= regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
119118334Speter		   : HARD_REGNO_NREGS (regno, GET_MODE (x)));
119290075Sobrien      unsigned int i;
119318334Speter
119418334Speter      for (i = regno; i < endregno; i++)
119518334Speter	{
119652284Sobrien	  if (REG_IN_TABLE (i) >= 0 && REG_IN_TABLE (i) != REG_TICK (i))
119718334Speter	    remove_invalid_refs (i);
119818334Speter
119952284Sobrien	  REG_IN_TABLE (i) = REG_TICK (i);
120018334Speter	}
120118334Speter
120218334Speter      return 0;
120318334Speter    }
120418334Speter
120552284Sobrien  /* If this is a SUBREG, we don't want to discard other SUBREGs of the same
120652284Sobrien     pseudo if they don't use overlapping words.  We handle only pseudos
120752284Sobrien     here for simplicity.  */
120852284Sobrien  if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG
120952284Sobrien      && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
121052284Sobrien    {
121190075Sobrien      unsigned int i = REGNO (SUBREG_REG (x));
121252284Sobrien
121352284Sobrien      if (REG_IN_TABLE (i) >= 0 && REG_IN_TABLE (i) != REG_TICK (i))
121452284Sobrien	{
121552284Sobrien	  /* If reg_tick has been incremented more than once since
121652284Sobrien	     reg_in_table was last set, that means that the entire
121752284Sobrien	     register has been set before, so discard anything memorized
121890075Sobrien	     for the entire register, including all SUBREG expressions.  */
121952284Sobrien	  if (REG_IN_TABLE (i) != REG_TICK (i) - 1)
122052284Sobrien	    remove_invalid_refs (i);
122152284Sobrien	  else
122290075Sobrien	    remove_invalid_subreg_refs (i, SUBREG_BYTE (x), GET_MODE (x));
122352284Sobrien	}
122452284Sobrien
122552284Sobrien      REG_IN_TABLE (i) = REG_TICK (i);
122652284Sobrien      return 0;
122752284Sobrien    }
122852284Sobrien
122918334Speter  /* If X is a comparison or a COMPARE and either operand is a register
123018334Speter     that does not have a quantity, give it one.  This is so that a later
123118334Speter     call to record_jump_equiv won't cause X to be assigned a different
123218334Speter     hash code and not found in the table after that call.
123318334Speter
123418334Speter     It is not necessary to do this here, since rehash_using_reg can
123518334Speter     fix up the table later, but doing this here eliminates the need to
123618334Speter     call that expensive function in the most common case where the only
123718334Speter     use of the register is in the comparison.  */
123818334Speter
123918334Speter  if (code == COMPARE || GET_RTX_CLASS (code) == '<')
124018334Speter    {
124118334Speter      if (GET_CODE (XEXP (x, 0)) == REG
124218334Speter	  && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))))
124390075Sobrien	if (insert_regs (XEXP (x, 0), NULL, 0))
124418334Speter	  {
124518334Speter	    rehash_using_reg (XEXP (x, 0));
124618334Speter	    changed = 1;
124718334Speter	  }
124818334Speter
124918334Speter      if (GET_CODE (XEXP (x, 1)) == REG
125018334Speter	  && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))))
125190075Sobrien	if (insert_regs (XEXP (x, 1), NULL, 0))
125218334Speter	  {
125318334Speter	    rehash_using_reg (XEXP (x, 1));
125418334Speter	    changed = 1;
125518334Speter	  }
125618334Speter    }
125718334Speter
125818334Speter  fmt = GET_RTX_FORMAT (code);
125918334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
126018334Speter    if (fmt[i] == 'e')
126118334Speter      changed |= mention_regs (XEXP (x, i));
126218334Speter    else if (fmt[i] == 'E')
126318334Speter      for (j = 0; j < XVECLEN (x, i); j++)
126418334Speter	changed |= mention_regs (XVECEXP (x, i, j));
126518334Speter
126618334Speter  return changed;
126718334Speter}
126818334Speter
126918334Speter/* Update the register quantities for inserting X into the hash table
127018334Speter   with a value equivalent to CLASSP.
127118334Speter   (If the class does not contain a REG, it is irrelevant.)
127218334Speter   If MODIFIED is nonzero, X is a destination; it is being modified.
127318334Speter   Note that delete_reg_equiv should be called on a register
127418334Speter   before insert_regs is done on that register with MODIFIED != 0.
127518334Speter
127618334Speter   Nonzero value means that elements of reg_qty have changed
127718334Speter   so X's hash code may be different.  */
127818334Speter
127918334Speterstatic int
128018334Speterinsert_regs (x, classp, modified)
128118334Speter     rtx x;
128218334Speter     struct table_elt *classp;
128318334Speter     int modified;
128418334Speter{
128518334Speter  if (GET_CODE (x) == REG)
128618334Speter    {
128790075Sobrien      unsigned int regno = REGNO (x);
128890075Sobrien      int qty_valid;
128918334Speter
129018334Speter      /* If REGNO is in the equivalence table already but is of the
129118334Speter	 wrong mode for that equivalence, don't do anything here.  */
129218334Speter
129390075Sobrien      qty_valid = REGNO_QTY_VALID_P (regno);
129490075Sobrien      if (qty_valid)
129590075Sobrien	{
129690075Sobrien	  struct qty_table_elem *ent = &qty_table[REG_QTY (regno)];
129718334Speter
129890075Sobrien	  if (ent->mode != GET_MODE (x))
129990075Sobrien	    return 0;
130090075Sobrien	}
130190075Sobrien
130290075Sobrien      if (modified || ! qty_valid)
130318334Speter	{
130418334Speter	  if (classp)
130518334Speter	    for (classp = classp->first_same_value;
130618334Speter		 classp != 0;
130718334Speter		 classp = classp->next_same_value)
130818334Speter	      if (GET_CODE (classp->exp) == REG
130918334Speter		  && GET_MODE (classp->exp) == GET_MODE (x))
131018334Speter		{
131118334Speter		  make_regs_eqv (regno, REGNO (classp->exp));
131218334Speter		  return 1;
131318334Speter		}
131418334Speter
131590075Sobrien	  /* Mention_regs for a SUBREG checks if REG_TICK is exactly one larger
131690075Sobrien	     than REG_IN_TABLE to find out if there was only a single preceding
131790075Sobrien	     invalidation - for the SUBREG - or another one, which would be
131890075Sobrien	     for the full register.  However, if we find here that REG_TICK
131990075Sobrien	     indicates that the register is invalid, it means that it has
132090075Sobrien	     been invalidated in a separate operation.  The SUBREG might be used
132190075Sobrien	     now (then this is a recursive call), or we might use the full REG
132290075Sobrien	     now and a SUBREG of it later.  So bump up REG_TICK so that
132390075Sobrien	     mention_regs will do the right thing.  */
132490075Sobrien	  if (! modified
132590075Sobrien	      && REG_IN_TABLE (regno) >= 0
132690075Sobrien	      && REG_TICK (regno) == REG_IN_TABLE (regno) + 1)
132790075Sobrien	    REG_TICK (regno)++;
132890075Sobrien	  make_new_qty (regno, GET_MODE (x));
132918334Speter	  return 1;
133018334Speter	}
133118334Speter
133218334Speter      return 0;
133318334Speter    }
133418334Speter
133518334Speter  /* If X is a SUBREG, we will likely be inserting the inner register in the
133618334Speter     table.  If that register doesn't have an assigned quantity number at
133718334Speter     this point but does later, the insertion that we will be doing now will
133818334Speter     not be accessible because its hash code will have changed.  So assign
133918334Speter     a quantity number now.  */
134018334Speter
134118334Speter  else if (GET_CODE (x) == SUBREG && GET_CODE (SUBREG_REG (x)) == REG
134218334Speter	   && ! REGNO_QTY_VALID_P (REGNO (SUBREG_REG (x))))
134318334Speter    {
134490075Sobrien      insert_regs (SUBREG_REG (x), NULL, 0);
134552284Sobrien      mention_regs (x);
134618334Speter      return 1;
134718334Speter    }
134818334Speter  else
134918334Speter    return mention_regs (x);
135018334Speter}
135118334Speter
135218334Speter/* Look in or update the hash table.  */
135318334Speter
135418334Speter/* Remove table element ELT from use in the table.
135518334Speter   HASH is its hash code, made using the HASH macro.
135618334Speter   It's an argument because often that is known in advance
135718334Speter   and we save much time not recomputing it.  */
135818334Speter
135918334Speterstatic void
136018334Speterremove_from_table (elt, hash)
136190075Sobrien     struct table_elt *elt;
136218334Speter     unsigned hash;
136318334Speter{
136418334Speter  if (elt == 0)
136518334Speter    return;
136618334Speter
136718334Speter  /* Mark this element as removed.  See cse_insn.  */
136818334Speter  elt->first_same_value = 0;
136918334Speter
137018334Speter  /* Remove the table element from its equivalence class.  */
137190075Sobrien
137218334Speter  {
137390075Sobrien    struct table_elt *prev = elt->prev_same_value;
137490075Sobrien    struct table_elt *next = elt->next_same_value;
137518334Speter
137690075Sobrien    if (next)
137790075Sobrien      next->prev_same_value = prev;
137818334Speter
137918334Speter    if (prev)
138018334Speter      prev->next_same_value = next;
138118334Speter    else
138218334Speter      {
138390075Sobrien	struct table_elt *newfirst = next;
138418334Speter	while (next)
138518334Speter	  {
138618334Speter	    next->first_same_value = newfirst;
138718334Speter	    next = next->next_same_value;
138818334Speter	  }
138918334Speter      }
139018334Speter  }
139118334Speter
139218334Speter  /* Remove the table element from its hash bucket.  */
139318334Speter
139418334Speter  {
139590075Sobrien    struct table_elt *prev = elt->prev_same_hash;
139690075Sobrien    struct table_elt *next = elt->next_same_hash;
139718334Speter
139890075Sobrien    if (next)
139990075Sobrien      next->prev_same_hash = prev;
140018334Speter
140118334Speter    if (prev)
140218334Speter      prev->next_same_hash = next;
140318334Speter    else if (table[hash] == elt)
140418334Speter      table[hash] = next;
140518334Speter    else
140618334Speter      {
140718334Speter	/* This entry is not in the proper hash bucket.  This can happen
140818334Speter	   when two classes were merged by `merge_equiv_classes'.  Search
140918334Speter	   for the hash bucket that it heads.  This happens only very
141018334Speter	   rarely, so the cost is acceptable.  */
141190075Sobrien	for (hash = 0; hash < HASH_SIZE; hash++)
141218334Speter	  if (table[hash] == elt)
141318334Speter	    table[hash] = next;
141418334Speter      }
141518334Speter  }
141618334Speter
141718334Speter  /* Remove the table element from its related-value circular chain.  */
141818334Speter
141918334Speter  if (elt->related_value != 0 && elt->related_value != elt)
142018334Speter    {
142190075Sobrien      struct table_elt *p = elt->related_value;
142290075Sobrien
142318334Speter      while (p->related_value != elt)
142418334Speter	p = p->related_value;
142518334Speter      p->related_value = elt->related_value;
142618334Speter      if (p->related_value == p)
142718334Speter	p->related_value = 0;
142818334Speter    }
142918334Speter
143090075Sobrien  /* Now add it to the free element chain.  */
143190075Sobrien  elt->next_same_hash = free_element_chain;
143290075Sobrien  free_element_chain = elt;
143318334Speter}
143418334Speter
143518334Speter/* Look up X in the hash table and return its table element,
143618334Speter   or 0 if X is not in the table.
143718334Speter
143818334Speter   MODE is the machine-mode of X, or if X is an integer constant
143918334Speter   with VOIDmode then MODE is the mode with which X will be used.
144018334Speter
144118334Speter   Here we are satisfied to find an expression whose tree structure
144218334Speter   looks like X.  */
144318334Speter
144418334Speterstatic struct table_elt *
144518334Speterlookup (x, hash, mode)
144618334Speter     rtx x;
144718334Speter     unsigned hash;
144818334Speter     enum machine_mode mode;
144918334Speter{
145090075Sobrien  struct table_elt *p;
145118334Speter
145218334Speter  for (p = table[hash]; p; p = p->next_same_hash)
145318334Speter    if (mode == p->mode && ((x == p->exp && GET_CODE (x) == REG)
145418334Speter			    || exp_equiv_p (x, p->exp, GET_CODE (x) != REG, 0)))
145518334Speter      return p;
145618334Speter
145718334Speter  return 0;
145818334Speter}
145918334Speter
146018334Speter/* Like `lookup' but don't care whether the table element uses invalid regs.
146118334Speter   Also ignore discrepancies in the machine mode of a register.  */
146218334Speter
146318334Speterstatic struct table_elt *
146418334Speterlookup_for_remove (x, hash, mode)
146518334Speter     rtx x;
146618334Speter     unsigned hash;
146718334Speter     enum machine_mode mode;
146818334Speter{
146990075Sobrien  struct table_elt *p;
147018334Speter
147118334Speter  if (GET_CODE (x) == REG)
147218334Speter    {
147390075Sobrien      unsigned int regno = REGNO (x);
147490075Sobrien
147518334Speter      /* Don't check the machine mode when comparing registers;
147618334Speter	 invalidating (REG:SI 0) also invalidates (REG:DF 0).  */
147718334Speter      for (p = table[hash]; p; p = p->next_same_hash)
147818334Speter	if (GET_CODE (p->exp) == REG
147918334Speter	    && REGNO (p->exp) == regno)
148018334Speter	  return p;
148118334Speter    }
148218334Speter  else
148318334Speter    {
148418334Speter      for (p = table[hash]; p; p = p->next_same_hash)
148518334Speter	if (mode == p->mode && (x == p->exp || exp_equiv_p (x, p->exp, 0, 0)))
148618334Speter	  return p;
148718334Speter    }
148818334Speter
148918334Speter  return 0;
149018334Speter}
149118334Speter
149218334Speter/* Look for an expression equivalent to X and with code CODE.
149318334Speter   If one is found, return that expression.  */
149418334Speter
149518334Speterstatic rtx
149618334Speterlookup_as_function (x, code)
149718334Speter     rtx x;
149818334Speter     enum rtx_code code;
149918334Speter{
150090075Sobrien  struct table_elt *p
150190075Sobrien    = lookup (x, safe_hash (x, VOIDmode) & HASH_MASK, GET_MODE (x));
150290075Sobrien
150352284Sobrien  /* If we are looking for a CONST_INT, the mode doesn't really matter, as
150452284Sobrien     long as we are narrowing.  So if we looked in vain for a mode narrower
150552284Sobrien     than word_mode before, look for word_mode now.  */
150652284Sobrien  if (p == 0 && code == CONST_INT
150752284Sobrien      && GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (word_mode))
150852284Sobrien    {
150952284Sobrien      x = copy_rtx (x);
151052284Sobrien      PUT_MODE (x, word_mode);
151190075Sobrien      p = lookup (x, safe_hash (x, VOIDmode) & HASH_MASK, word_mode);
151252284Sobrien    }
151352284Sobrien
151418334Speter  if (p == 0)
151518334Speter    return 0;
151618334Speter
151718334Speter  for (p = p->first_same_value; p; p = p->next_same_value)
151890075Sobrien    if (GET_CODE (p->exp) == code
151990075Sobrien	/* Make sure this is a valid entry in the table.  */
152090075Sobrien	&& exp_equiv_p (p->exp, p->exp, 1, 0))
152190075Sobrien      return p->exp;
152290075Sobrien
152318334Speter  return 0;
152418334Speter}
152518334Speter
152618334Speter/* Insert X in the hash table, assuming HASH is its hash code
152718334Speter   and CLASSP is an element of the class it should go in
152818334Speter   (or 0 if a new class should be made).
152918334Speter   It is inserted at the proper position to keep the class in
153018334Speter   the order cheapest first.
153118334Speter
153218334Speter   MODE is the machine-mode of X, or if X is an integer constant
153318334Speter   with VOIDmode then MODE is the mode with which X will be used.
153418334Speter
153518334Speter   For elements of equal cheapness, the most recent one
153618334Speter   goes in front, except that the first element in the list
153718334Speter   remains first unless a cheaper element is added.  The order of
153818334Speter   pseudo-registers does not matter, as canon_reg will be called to
153918334Speter   find the cheapest when a register is retrieved from the table.
154018334Speter
154118334Speter   The in_memory field in the hash table element is set to 0.
154218334Speter   The caller must set it nonzero if appropriate.
154318334Speter
154418334Speter   You should call insert_regs (X, CLASSP, MODIFY) before calling here,
154518334Speter   and if insert_regs returns a nonzero value
154618334Speter   you must then recompute its hash code before calling here.
154718334Speter
154818334Speter   If necessary, update table showing constant values of quantities.  */
154918334Speter
155090075Sobrien#define CHEAPER(X, Y) \
155190075Sobrien (preferrable ((X)->cost, (X)->regcost, (Y)->cost, (Y)->regcost) < 0)
155218334Speter
155318334Speterstatic struct table_elt *
155418334Speterinsert (x, classp, hash, mode)
155590075Sobrien     rtx x;
155690075Sobrien     struct table_elt *classp;
155718334Speter     unsigned hash;
155818334Speter     enum machine_mode mode;
155918334Speter{
156090075Sobrien  struct table_elt *elt;
156118334Speter
156218334Speter  /* If X is a register and we haven't made a quantity for it,
156318334Speter     something is wrong.  */
156418334Speter  if (GET_CODE (x) == REG && ! REGNO_QTY_VALID_P (REGNO (x)))
156518334Speter    abort ();
156618334Speter
156718334Speter  /* If X is a hard register, show it is being put in the table.  */
156818334Speter  if (GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
156918334Speter    {
157090075Sobrien      unsigned int regno = REGNO (x);
157190075Sobrien      unsigned int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
157290075Sobrien      unsigned int i;
157318334Speter
157418334Speter      for (i = regno; i < endregno; i++)
157590075Sobrien	SET_HARD_REG_BIT (hard_regs_in_table, i);
157618334Speter    }
157718334Speter
157818334Speter  /* Put an element for X into the right hash bucket.  */
157918334Speter
158090075Sobrien  elt = free_element_chain;
158190075Sobrien  if (elt)
158290075Sobrien    free_element_chain = elt->next_same_hash;
158390075Sobrien  else
158490075Sobrien    {
158590075Sobrien      n_elements_made++;
158690075Sobrien      elt = (struct table_elt *) xmalloc (sizeof (struct table_elt));
158790075Sobrien    }
158890075Sobrien
158918334Speter  elt->exp = x;
159090075Sobrien  elt->canon_exp = NULL_RTX;
159118334Speter  elt->cost = COST (x);
159290075Sobrien  elt->regcost = approx_reg_cost (x);
159318334Speter  elt->next_same_value = 0;
159418334Speter  elt->prev_same_value = 0;
159518334Speter  elt->next_same_hash = table[hash];
159618334Speter  elt->prev_same_hash = 0;
159718334Speter  elt->related_value = 0;
159818334Speter  elt->in_memory = 0;
159918334Speter  elt->mode = mode;
160018334Speter  elt->is_const = (CONSTANT_P (x)
160118334Speter		   /* GNU C++ takes advantage of this for `this'
160218334Speter		      (and other const values).  */
160318334Speter		   || (RTX_UNCHANGING_P (x)
160418334Speter		       && GET_CODE (x) == REG
160518334Speter		       && REGNO (x) >= FIRST_PSEUDO_REGISTER)
160618334Speter		   || FIXED_BASE_PLUS_P (x));
160718334Speter
160818334Speter  if (table[hash])
160918334Speter    table[hash]->prev_same_hash = elt;
161018334Speter  table[hash] = elt;
161118334Speter
161218334Speter  /* Put it into the proper value-class.  */
161318334Speter  if (classp)
161418334Speter    {
161518334Speter      classp = classp->first_same_value;
161618334Speter      if (CHEAPER (elt, classp))
161718334Speter	/* Insert at the head of the class */
161818334Speter	{
161990075Sobrien	  struct table_elt *p;
162018334Speter	  elt->next_same_value = classp;
162118334Speter	  classp->prev_same_value = elt;
162218334Speter	  elt->first_same_value = elt;
162318334Speter
162418334Speter	  for (p = classp; p; p = p->next_same_value)
162518334Speter	    p->first_same_value = elt;
162618334Speter	}
162718334Speter      else
162818334Speter	{
162918334Speter	  /* Insert not at head of the class.  */
163018334Speter	  /* Put it after the last element cheaper than X.  */
163190075Sobrien	  struct table_elt *p, *next;
163290075Sobrien
163318334Speter	  for (p = classp; (next = p->next_same_value) && CHEAPER (next, elt);
163418334Speter	       p = next);
163590075Sobrien
163618334Speter	  /* Put it after P and before NEXT.  */
163718334Speter	  elt->next_same_value = next;
163818334Speter	  if (next)
163918334Speter	    next->prev_same_value = elt;
164090075Sobrien
164118334Speter	  elt->prev_same_value = p;
164218334Speter	  p->next_same_value = elt;
164318334Speter	  elt->first_same_value = classp;
164418334Speter	}
164518334Speter    }
164618334Speter  else
164718334Speter    elt->first_same_value = elt;
164818334Speter
164918334Speter  /* If this is a constant being set equivalent to a register or a register
165018334Speter     being set equivalent to a constant, note the constant equivalence.
165118334Speter
165218334Speter     If this is a constant, it cannot be equivalent to a different constant,
165318334Speter     and a constant is the only thing that can be cheaper than a register.  So
165418334Speter     we know the register is the head of the class (before the constant was
165518334Speter     inserted).
165618334Speter
165718334Speter     If this is a register that is not already known equivalent to a
165818334Speter     constant, we must check the entire class.
165918334Speter
166018334Speter     If this is a register that is already known equivalent to an insn,
166190075Sobrien     update the qtys `const_insn' to show that `this_insn' is the latest
166218334Speter     insn making that quantity equivalent to the constant.  */
166318334Speter
166418334Speter  if (elt->is_const && classp && GET_CODE (classp->exp) == REG
166518334Speter      && GET_CODE (x) != REG)
166618334Speter    {
166790075Sobrien      int exp_q = REG_QTY (REGNO (classp->exp));
166890075Sobrien      struct qty_table_elem *exp_ent = &qty_table[exp_q];
166990075Sobrien
167090075Sobrien      exp_ent->const_rtx = gen_lowpart_if_possible (exp_ent->mode, x);
167190075Sobrien      exp_ent->const_insn = this_insn;
167218334Speter    }
167318334Speter
167490075Sobrien  else if (GET_CODE (x) == REG
167590075Sobrien	   && classp
167690075Sobrien	   && ! qty_table[REG_QTY (REGNO (x))].const_rtx
167718334Speter	   && ! elt->is_const)
167818334Speter    {
167990075Sobrien      struct table_elt *p;
168018334Speter
168118334Speter      for (p = classp; p != 0; p = p->next_same_value)
168218334Speter	{
168318334Speter	  if (p->is_const && GET_CODE (p->exp) != REG)
168418334Speter	    {
168590075Sobrien	      int x_q = REG_QTY (REGNO (x));
168690075Sobrien	      struct qty_table_elem *x_ent = &qty_table[x_q];
168790075Sobrien
168890075Sobrien	      x_ent->const_rtx
168918334Speter		= gen_lowpart_if_possible (GET_MODE (x), p->exp);
169090075Sobrien	      x_ent->const_insn = this_insn;
169118334Speter	      break;
169218334Speter	    }
169318334Speter	}
169418334Speter    }
169518334Speter
169690075Sobrien  else if (GET_CODE (x) == REG
169790075Sobrien	   && qty_table[REG_QTY (REGNO (x))].const_rtx
169890075Sobrien	   && GET_MODE (x) == qty_table[REG_QTY (REGNO (x))].mode)
169990075Sobrien    qty_table[REG_QTY (REGNO (x))].const_insn = this_insn;
170018334Speter
170118334Speter  /* If this is a constant with symbolic value,
170218334Speter     and it has a term with an explicit integer value,
170318334Speter     link it up with related expressions.  */
170418334Speter  if (GET_CODE (x) == CONST)
170518334Speter    {
170618334Speter      rtx subexp = get_related_value (x);
170718334Speter      unsigned subhash;
170818334Speter      struct table_elt *subelt, *subelt_prev;
170918334Speter
171018334Speter      if (subexp != 0)
171118334Speter	{
171218334Speter	  /* Get the integer-free subexpression in the hash table.  */
171390075Sobrien	  subhash = safe_hash (subexp, mode) & HASH_MASK;
171418334Speter	  subelt = lookup (subexp, subhash, mode);
171518334Speter	  if (subelt == 0)
171690075Sobrien	    subelt = insert (subexp, NULL, subhash, mode);
171718334Speter	  /* Initialize SUBELT's circular chain if it has none.  */
171818334Speter	  if (subelt->related_value == 0)
171918334Speter	    subelt->related_value = subelt;
172018334Speter	  /* Find the element in the circular chain that precedes SUBELT.  */
172118334Speter	  subelt_prev = subelt;
172218334Speter	  while (subelt_prev->related_value != subelt)
172318334Speter	    subelt_prev = subelt_prev->related_value;
172418334Speter	  /* Put new ELT into SUBELT's circular chain just before SUBELT.
172518334Speter	     This way the element that follows SUBELT is the oldest one.  */
172618334Speter	  elt->related_value = subelt_prev->related_value;
172718334Speter	  subelt_prev->related_value = elt;
172818334Speter	}
172918334Speter    }
173018334Speter
173118334Speter  return elt;
173218334Speter}
173318334Speter
173418334Speter/* Given two equivalence classes, CLASS1 and CLASS2, put all the entries from
173518334Speter   CLASS2 into CLASS1.  This is done when we have reached an insn which makes
173618334Speter   the two classes equivalent.
173718334Speter
173818334Speter   CLASS1 will be the surviving class; CLASS2 should not be used after this
173918334Speter   call.
174018334Speter
174118334Speter   Any invalid entries in CLASS2 will not be copied.  */
174218334Speter
174318334Speterstatic void
174418334Spetermerge_equiv_classes (class1, class2)
174518334Speter     struct table_elt *class1, *class2;
174618334Speter{
174718334Speter  struct table_elt *elt, *next, *new;
174818334Speter
174918334Speter  /* Ensure we start with the head of the classes.  */
175018334Speter  class1 = class1->first_same_value;
175118334Speter  class2 = class2->first_same_value;
175218334Speter
175318334Speter  /* If they were already equal, forget it.  */
175418334Speter  if (class1 == class2)
175518334Speter    return;
175618334Speter
175718334Speter  for (elt = class2; elt; elt = next)
175818334Speter    {
175990075Sobrien      unsigned int hash;
176018334Speter      rtx exp = elt->exp;
176118334Speter      enum machine_mode mode = elt->mode;
176218334Speter
176318334Speter      next = elt->next_same_value;
176418334Speter
176518334Speter      /* Remove old entry, make a new one in CLASS1's class.
176618334Speter	 Don't do this for invalid entries as we cannot find their
176750397Sobrien	 hash code (it also isn't necessary).  */
176818334Speter      if (GET_CODE (exp) == REG || exp_equiv_p (exp, exp, 1, 0))
176918334Speter	{
177018334Speter	  hash_arg_in_memory = 0;
177118334Speter	  hash = HASH (exp, mode);
177290075Sobrien
177318334Speter	  if (GET_CODE (exp) == REG)
177418334Speter	    delete_reg_equiv (REGNO (exp));
177590075Sobrien
177618334Speter	  remove_from_table (elt, hash);
177718334Speter
177818334Speter	  if (insert_regs (exp, class1, 0))
177918334Speter	    {
178018334Speter	      rehash_using_reg (exp);
178118334Speter	      hash = HASH (exp, mode);
178218334Speter	    }
178318334Speter	  new = insert (exp, class1, hash, mode);
178418334Speter	  new->in_memory = hash_arg_in_memory;
178518334Speter	}
178618334Speter    }
178718334Speter}
178818334Speter
178952284Sobrien/* Flush the entire hash table.  */
179052284Sobrien
179152284Sobrienstatic void
179252284Sobrienflush_hash_table ()
179352284Sobrien{
179452284Sobrien  int i;
179552284Sobrien  struct table_elt *p;
179652284Sobrien
179790075Sobrien  for (i = 0; i < HASH_SIZE; i++)
179852284Sobrien    for (p = table[i]; p; p = table[i])
179952284Sobrien      {
180052284Sobrien	/* Note that invalidate can remove elements
180152284Sobrien	   after P in the current hash chain.  */
180252284Sobrien	if (GET_CODE (p->exp) == REG)
180352284Sobrien	  invalidate (p->exp, p->mode);
180452284Sobrien	else
180552284Sobrien	  remove_from_table (p, i);
180652284Sobrien      }
180752284Sobrien}
180890075Sobrien
180990075Sobrien/* Function called for each rtx to check whether true dependence exist.  */
181090075Sobrienstruct check_dependence_data
181190075Sobrien{
181290075Sobrien  enum machine_mode mode;
181390075Sobrien  rtx exp;
181490075Sobrien};
181552284Sobrien
181690075Sobrienstatic int
181790075Sobriencheck_dependence (x, data)
181890075Sobrien     rtx *x;
181990075Sobrien     void *data;
182090075Sobrien{
182190075Sobrien  struct check_dependence_data *d = (struct check_dependence_data *) data;
182290075Sobrien  if (*x && GET_CODE (*x) == MEM)
182390075Sobrien    return true_dependence (d->exp, d->mode, *x, cse_rtx_varies_p);
182490075Sobrien  else
182590075Sobrien    return 0;
182690075Sobrien}
182790075Sobrien
182890075Sobrien/* Remove from the hash table, or mark as invalid, all expressions whose
182990075Sobrien   values could be altered by storing in X.  X is a register, a subreg, or
183090075Sobrien   a memory reference with nonvarying address (because, when a memory
183190075Sobrien   reference with a varying address is stored in, all memory references are
183290075Sobrien   removed by invalidate_memory so specific invalidation is superfluous).
183390075Sobrien   FULL_MODE, if not VOIDmode, indicates that this much should be
183490075Sobrien   invalidated instead of just the amount indicated by the mode of X.  This
183590075Sobrien   is only used for bitfield stores into memory.
183652284Sobrien
183790075Sobrien   A nonvarying address may be just a register or just a symbol reference,
183890075Sobrien   or it may be either of those plus a numeric offset.  */
183918334Speter
184018334Speterstatic void
184118334Speterinvalidate (x, full_mode)
184218334Speter     rtx x;
184318334Speter     enum machine_mode full_mode;
184418334Speter{
184590075Sobrien  int i;
184690075Sobrien  struct table_elt *p;
184718334Speter
184890075Sobrien  switch (GET_CODE (x))
184918334Speter    {
185090075Sobrien    case REG:
185190075Sobrien      {
185290075Sobrien	/* If X is a register, dependencies on its contents are recorded
185390075Sobrien	   through the qty number mechanism.  Just change the qty number of
185490075Sobrien	   the register, mark it as invalid for expressions that refer to it,
185590075Sobrien	   and remove it itself.  */
185690075Sobrien	unsigned int regno = REGNO (x);
185790075Sobrien	unsigned int hash = HASH (x, GET_MODE (x));
185818334Speter
185990075Sobrien	/* Remove REGNO from any quantity list it might be on and indicate
186090075Sobrien	   that its value might have changed.  If it is a pseudo, remove its
186190075Sobrien	   entry from the hash table.
186218334Speter
186390075Sobrien	   For a hard register, we do the first two actions above for any
186490075Sobrien	   additional hard registers corresponding to X.  Then, if any of these
186590075Sobrien	   registers are in the table, we must remove any REG entries that
186690075Sobrien	   overlap these registers.  */
186718334Speter
186890075Sobrien	delete_reg_equiv (regno);
186990075Sobrien	REG_TICK (regno)++;
187018334Speter
187190075Sobrien	if (regno >= FIRST_PSEUDO_REGISTER)
187290075Sobrien	  {
187390075Sobrien	    /* Because a register can be referenced in more than one mode,
187490075Sobrien	       we might have to remove more than one table entry.  */
187590075Sobrien	    struct table_elt *elt;
187618334Speter
187790075Sobrien	    while ((elt = lookup_for_remove (x, hash, GET_MODE (x))))
187890075Sobrien	      remove_from_table (elt, hash);
187990075Sobrien	  }
188090075Sobrien	else
188190075Sobrien	  {
188290075Sobrien	    HOST_WIDE_INT in_table
188390075Sobrien	      = TEST_HARD_REG_BIT (hard_regs_in_table, regno);
188490075Sobrien	    unsigned int endregno
188590075Sobrien	      = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
188690075Sobrien	    unsigned int tregno, tendregno, rn;
188790075Sobrien	    struct table_elt *p, *next;
188818334Speter
188990075Sobrien	    CLEAR_HARD_REG_BIT (hard_regs_in_table, regno);
189018334Speter
189190075Sobrien	    for (rn = regno + 1; rn < endregno; rn++)
189290075Sobrien	      {
189390075Sobrien		in_table |= TEST_HARD_REG_BIT (hard_regs_in_table, rn);
189490075Sobrien		CLEAR_HARD_REG_BIT (hard_regs_in_table, rn);
189590075Sobrien		delete_reg_equiv (rn);
189690075Sobrien		REG_TICK (rn)++;
189790075Sobrien	      }
189818334Speter
189990075Sobrien	    if (in_table)
190090075Sobrien	      for (hash = 0; hash < HASH_SIZE; hash++)
190190075Sobrien		for (p = table[hash]; p; p = next)
190290075Sobrien		  {
190390075Sobrien		    next = p->next_same_hash;
190418334Speter
190590075Sobrien		    if (GET_CODE (p->exp) != REG
190690075Sobrien			|| REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
190790075Sobrien		      continue;
190818334Speter
190990075Sobrien		    tregno = REGNO (p->exp);
191090075Sobrien		    tendregno
191190075Sobrien		      = tregno + HARD_REGNO_NREGS (tregno, GET_MODE (p->exp));
191290075Sobrien		    if (tendregno > regno && tregno < endregno)
191390075Sobrien		      remove_from_table (p, hash);
191490075Sobrien		  }
191590075Sobrien	  }
191690075Sobrien      }
191718334Speter      return;
191818334Speter
191990075Sobrien    case SUBREG:
192018334Speter      invalidate (SUBREG_REG (x), VOIDmode);
192118334Speter      return;
192218334Speter
192390075Sobrien    case PARALLEL:
192490075Sobrien      for (i = XVECLEN (x, 0) - 1; i >= 0; --i)
192550397Sobrien	invalidate (XVECEXP (x, 0, i), VOIDmode);
192650397Sobrien      return;
192750397Sobrien
192890075Sobrien    case EXPR_LIST:
192990075Sobrien      /* This is part of a disjoint return value; extract the location in
193090075Sobrien	 question ignoring the offset.  */
193150397Sobrien      invalidate (XEXP (x, 0), VOIDmode);
193250397Sobrien      return;
193350397Sobrien
193490075Sobrien    case MEM:
193590075Sobrien      /* Calculate the canonical version of X here so that
193690075Sobrien	 true_dependence doesn't generate new RTL for X on each call.  */
193790075Sobrien      x = canon_rtx (x);
193818334Speter
193990075Sobrien      /* Remove all hash table elements that refer to overlapping pieces of
194090075Sobrien	 memory.  */
194190075Sobrien      if (full_mode == VOIDmode)
194290075Sobrien	full_mode = GET_MODE (x);
194318334Speter
194490075Sobrien      for (i = 0; i < HASH_SIZE; i++)
194590075Sobrien	{
194690075Sobrien	  struct table_elt *next;
194718334Speter
194890075Sobrien	  for (p = table[i]; p; p = next)
194990075Sobrien	    {
195090075Sobrien	      next = p->next_same_hash;
195190075Sobrien	      if (p->in_memory)
195290075Sobrien		{
195390075Sobrien		  struct check_dependence_data d;
195490075Sobrien
195590075Sobrien		  /* Just canonicalize the expression once;
195690075Sobrien		     otherwise each time we call invalidate
195790075Sobrien		     true_dependence will canonicalize the
195890075Sobrien		     expression again.  */
195990075Sobrien		  if (!p->canon_exp)
196090075Sobrien		    p->canon_exp = canon_rtx (p->exp);
196190075Sobrien		  d.exp = x;
196290075Sobrien		  d.mode = full_mode;
196390075Sobrien		  if (for_each_rtx (&p->canon_exp, check_dependence, &d))
196490075Sobrien		    remove_from_table (p, i);
196590075Sobrien		}
196690075Sobrien	    }
196718334Speter	}
196890075Sobrien      return;
196990075Sobrien
197090075Sobrien    default:
197190075Sobrien      abort ();
197218334Speter    }
197318334Speter}
197490075Sobrien
197518334Speter/* Remove all expressions that refer to register REGNO,
197618334Speter   since they are already invalid, and we are about to
197718334Speter   mark that register valid again and don't want the old
197818334Speter   expressions to reappear as valid.  */
197918334Speter
198018334Speterstatic void
198118334Speterremove_invalid_refs (regno)
198290075Sobrien     unsigned int regno;
198318334Speter{
198490075Sobrien  unsigned int i;
198590075Sobrien  struct table_elt *p, *next;
198618334Speter
198790075Sobrien  for (i = 0; i < HASH_SIZE; i++)
198818334Speter    for (p = table[i]; p; p = next)
198918334Speter      {
199018334Speter	next = p->next_same_hash;
199118334Speter	if (GET_CODE (p->exp) != REG
199290075Sobrien	    && refers_to_regno_p (regno, regno + 1, p->exp, (rtx*) 0))
199318334Speter	  remove_from_table (p, i);
199418334Speter      }
199518334Speter}
199652284Sobrien
199790075Sobrien/* Likewise for a subreg with subreg_reg REGNO, subreg_byte OFFSET,
199890075Sobrien   and mode MODE.  */
199952284Sobrienstatic void
200090075Sobrienremove_invalid_subreg_refs (regno, offset, mode)
200190075Sobrien     unsigned int regno;
200290075Sobrien     unsigned int offset;
200352284Sobrien     enum machine_mode mode;
200452284Sobrien{
200590075Sobrien  unsigned int i;
200690075Sobrien  struct table_elt *p, *next;
200790075Sobrien  unsigned int end = offset + (GET_MODE_SIZE (mode) - 1);
200852284Sobrien
200990075Sobrien  for (i = 0; i < HASH_SIZE; i++)
201052284Sobrien    for (p = table[i]; p; p = next)
201152284Sobrien      {
201290075Sobrien	rtx exp = p->exp;
201352284Sobrien	next = p->next_same_hash;
201490075Sobrien
201590075Sobrien	if (GET_CODE (exp) != REG
201652284Sobrien	    && (GET_CODE (exp) != SUBREG
201752284Sobrien		|| GET_CODE (SUBREG_REG (exp)) != REG
201852284Sobrien		|| REGNO (SUBREG_REG (exp)) != regno
201990075Sobrien		|| (((SUBREG_BYTE (exp)
202090075Sobrien		      + (GET_MODE_SIZE (GET_MODE (exp)) - 1)) >= offset)
202190075Sobrien		    && SUBREG_BYTE (exp) <= end))
202290075Sobrien	    && refers_to_regno_p (regno, regno + 1, p->exp, (rtx*) 0))
202352284Sobrien	  remove_from_table (p, i);
202452284Sobrien      }
202552284Sobrien}
202618334Speter
202718334Speter/* Recompute the hash codes of any valid entries in the hash table that
202818334Speter   reference X, if X is a register, or SUBREG_REG (X) if X is a SUBREG.
202918334Speter
203018334Speter   This is called when we make a jump equivalence.  */
203118334Speter
203218334Speterstatic void
203318334Speterrehash_using_reg (x)
203418334Speter     rtx x;
203518334Speter{
203652284Sobrien  unsigned int i;
203718334Speter  struct table_elt *p, *next;
203818334Speter  unsigned hash;
203918334Speter
204018334Speter  if (GET_CODE (x) == SUBREG)
204118334Speter    x = SUBREG_REG (x);
204218334Speter
204318334Speter  /* If X is not a register or if the register is known not to be in any
204418334Speter     valid entries in the table, we have no work to do.  */
204518334Speter
204618334Speter  if (GET_CODE (x) != REG
204752284Sobrien      || REG_IN_TABLE (REGNO (x)) < 0
204852284Sobrien      || REG_IN_TABLE (REGNO (x)) != REG_TICK (REGNO (x)))
204918334Speter    return;
205018334Speter
205118334Speter  /* Scan all hash chains looking for valid entries that mention X.
205218334Speter     If we find one and it is in the wrong hash chain, move it.  We can skip
205318334Speter     objects that are registers, since they are handled specially.  */
205418334Speter
205590075Sobrien  for (i = 0; i < HASH_SIZE; i++)
205618334Speter    for (p = table[i]; p; p = next)
205718334Speter      {
205818334Speter	next = p->next_same_hash;
205918334Speter	if (GET_CODE (p->exp) != REG && reg_mentioned_p (x, p->exp)
206018334Speter	    && exp_equiv_p (p->exp, p->exp, 1, 0)
206190075Sobrien	    && i != (hash = safe_hash (p->exp, p->mode) & HASH_MASK))
206218334Speter	  {
206318334Speter	    if (p->next_same_hash)
206418334Speter	      p->next_same_hash->prev_same_hash = p->prev_same_hash;
206518334Speter
206618334Speter	    if (p->prev_same_hash)
206718334Speter	      p->prev_same_hash->next_same_hash = p->next_same_hash;
206818334Speter	    else
206918334Speter	      table[i] = p->next_same_hash;
207018334Speter
207118334Speter	    p->next_same_hash = table[hash];
207218334Speter	    p->prev_same_hash = 0;
207318334Speter	    if (table[hash])
207418334Speter	      table[hash]->prev_same_hash = p;
207518334Speter	    table[hash] = p;
207618334Speter	  }
207718334Speter      }
207818334Speter}
207918334Speter
208018334Speter/* Remove from the hash table any expression that is a call-clobbered
208118334Speter   register.  Also update their TICK values.  */
208218334Speter
208318334Speterstatic void
208418334Speterinvalidate_for_call ()
208518334Speter{
208690075Sobrien  unsigned int regno, endregno;
208790075Sobrien  unsigned int i;
208818334Speter  unsigned hash;
208918334Speter  struct table_elt *p, *next;
209018334Speter  int in_table = 0;
209118334Speter
209218334Speter  /* Go through all the hard registers.  For each that is clobbered in
209318334Speter     a CALL_INSN, remove the register from quantity chains and update
209418334Speter     reg_tick if defined.  Also see if any of these registers is currently
209518334Speter     in the table.  */
209618334Speter
209718334Speter  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
209818334Speter    if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
209918334Speter      {
210018334Speter	delete_reg_equiv (regno);
210152284Sobrien	if (REG_TICK (regno) >= 0)
210252284Sobrien	  REG_TICK (regno)++;
210318334Speter
210418334Speter	in_table |= (TEST_HARD_REG_BIT (hard_regs_in_table, regno) != 0);
210518334Speter      }
210618334Speter
210718334Speter  /* In the case where we have no call-clobbered hard registers in the
210818334Speter     table, we are done.  Otherwise, scan the table and remove any
210918334Speter     entry that overlaps a call-clobbered register.  */
211018334Speter
211118334Speter  if (in_table)
211290075Sobrien    for (hash = 0; hash < HASH_SIZE; hash++)
211318334Speter      for (p = table[hash]; p; p = next)
211418334Speter	{
211518334Speter	  next = p->next_same_hash;
211618334Speter
211718334Speter	  if (GET_CODE (p->exp) != REG
211818334Speter	      || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
211918334Speter	    continue;
212018334Speter
212118334Speter	  regno = REGNO (p->exp);
212218334Speter	  endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (p->exp));
212318334Speter
212418334Speter	  for (i = regno; i < endregno; i++)
212518334Speter	    if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
212618334Speter	      {
212718334Speter		remove_from_table (p, hash);
212818334Speter		break;
212918334Speter	      }
213018334Speter	}
213118334Speter}
213218334Speter
213318334Speter/* Given an expression X of type CONST,
213418334Speter   and ELT which is its table entry (or 0 if it
213518334Speter   is not in the hash table),
213618334Speter   return an alternate expression for X as a register plus integer.
213718334Speter   If none can be found, return 0.  */
213818334Speter
213918334Speterstatic rtx
214018334Speteruse_related_value (x, elt)
214118334Speter     rtx x;
214218334Speter     struct table_elt *elt;
214318334Speter{
214490075Sobrien  struct table_elt *relt = 0;
214590075Sobrien  struct table_elt *p, *q;
214618334Speter  HOST_WIDE_INT offset;
214718334Speter
214818334Speter  /* First, is there anything related known?
214918334Speter     If we have a table element, we can tell from that.
215018334Speter     Otherwise, must look it up.  */
215118334Speter
215218334Speter  if (elt != 0 && elt->related_value != 0)
215318334Speter    relt = elt;
215418334Speter  else if (elt == 0 && GET_CODE (x) == CONST)
215518334Speter    {
215618334Speter      rtx subexp = get_related_value (x);
215718334Speter      if (subexp != 0)
215818334Speter	relt = lookup (subexp,
215990075Sobrien		       safe_hash (subexp, GET_MODE (subexp)) & HASH_MASK,
216018334Speter		       GET_MODE (subexp));
216118334Speter    }
216218334Speter
216318334Speter  if (relt == 0)
216418334Speter    return 0;
216518334Speter
216618334Speter  /* Search all related table entries for one that has an
216718334Speter     equivalent register.  */
216818334Speter
216918334Speter  p = relt;
217018334Speter  while (1)
217118334Speter    {
217218334Speter      /* This loop is strange in that it is executed in two different cases.
217318334Speter	 The first is when X is already in the table.  Then it is searching
217418334Speter	 the RELATED_VALUE list of X's class (RELT).  The second case is when
217518334Speter	 X is not in the table.  Then RELT points to a class for the related
217618334Speter	 value.
217718334Speter
217818334Speter	 Ensure that, whatever case we are in, that we ignore classes that have
217918334Speter	 the same value as X.  */
218018334Speter
218118334Speter      if (rtx_equal_p (x, p->exp))
218218334Speter	q = 0;
218318334Speter      else
218418334Speter	for (q = p->first_same_value; q; q = q->next_same_value)
218518334Speter	  if (GET_CODE (q->exp) == REG)
218618334Speter	    break;
218718334Speter
218818334Speter      if (q)
218918334Speter	break;
219018334Speter
219118334Speter      p = p->related_value;
219218334Speter
219318334Speter      /* We went all the way around, so there is nothing to be found.
219418334Speter	 Alternatively, perhaps RELT was in the table for some other reason
219518334Speter	 and it has no related values recorded.  */
219618334Speter      if (p == relt || p == 0)
219718334Speter	break;
219818334Speter    }
219918334Speter
220018334Speter  if (q == 0)
220118334Speter    return 0;
220218334Speter
220318334Speter  offset = (get_integer_term (x) - get_integer_term (p->exp));
220418334Speter  /* Note: OFFSET may be 0 if P->xexp and X are related by commutativity.  */
220518334Speter  return plus_constant (q->exp, offset);
220618334Speter}
220718334Speter
220890075Sobrien/* Hash a string.  Just add its bytes up.  */
220990075Sobrienstatic inline unsigned
221090075Sobriencanon_hash_string (ps)
221190075Sobrien     const char *ps;
221290075Sobrien{
221390075Sobrien  unsigned hash = 0;
221490075Sobrien  const unsigned char *p = (const unsigned char *)ps;
221590075Sobrien
221690075Sobrien  if (p)
221790075Sobrien    while (*p)
221890075Sobrien      hash += *p++;
221990075Sobrien
222090075Sobrien  return hash;
222190075Sobrien}
222290075Sobrien
222318334Speter/* Hash an rtx.  We are careful to make sure the value is never negative.
222418334Speter   Equivalent registers hash identically.
222518334Speter   MODE is used in hashing for CONST_INTs only;
222618334Speter   otherwise the mode of X is used.
222718334Speter
222818334Speter   Store 1 in do_not_record if any subexpression is volatile.
222918334Speter
223018334Speter   Store 1 in hash_arg_in_memory if X contains a MEM rtx
223118334Speter   which does not have the RTX_UNCHANGING_P bit set.
223218334Speter
223318334Speter   Note that cse_insn knows that the hash code of a MEM expression
223418334Speter   is just (int) MEM plus the hash code of the address.  */
223518334Speter
223618334Speterstatic unsigned
223718334Spetercanon_hash (x, mode)
223818334Speter     rtx x;
223918334Speter     enum machine_mode mode;
224018334Speter{
224190075Sobrien  int i, j;
224290075Sobrien  unsigned hash = 0;
224390075Sobrien  enum rtx_code code;
224490075Sobrien  const char *fmt;
224518334Speter
224618334Speter  /* repeat is used to turn tail-recursion into iteration.  */
224718334Speter repeat:
224818334Speter  if (x == 0)
224918334Speter    return hash;
225018334Speter
225118334Speter  code = GET_CODE (x);
225218334Speter  switch (code)
225318334Speter    {
225418334Speter    case REG:
225518334Speter      {
225690075Sobrien	unsigned int regno = REGNO (x);
225718334Speter
225818334Speter	/* On some machines, we can't record any non-fixed hard register,
225918334Speter	   because extending its life will cause reload problems.  We
226090075Sobrien	   consider ap, fp, and sp to be fixed for this purpose.
226152284Sobrien
226252284Sobrien	   We also consider CCmode registers to be fixed for this purpose;
226352284Sobrien	   failure to do so leads to failure to simplify 0<100 type of
226452284Sobrien	   conditionals.
226552284Sobrien
226690075Sobrien	   On all machines, we can't record any global registers.
226790075Sobrien	   Nor should we record any register that is in a small
226890075Sobrien	   class, as defined by CLASS_LIKELY_SPILLED_P.  */
226918334Speter
227018334Speter	if (regno < FIRST_PSEUDO_REGISTER
227118334Speter	    && (global_regs[regno]
227290075Sobrien		|| CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno))
227350397Sobrien		|| (SMALL_REGISTER_CLASSES
227450397Sobrien		    && ! fixed_regs[regno]
227590075Sobrien		    && x != frame_pointer_rtx
227690075Sobrien		    && x != hard_frame_pointer_rtx
227790075Sobrien		    && x != arg_pointer_rtx
227890075Sobrien		    && x != stack_pointer_rtx
227952284Sobrien		    && GET_MODE_CLASS (GET_MODE (x)) != MODE_CC)))
228018334Speter	  {
228118334Speter	    do_not_record = 1;
228218334Speter	    return 0;
228318334Speter	  }
228490075Sobrien
228552284Sobrien	hash += ((unsigned) REG << 7) + (unsigned) REG_QTY (regno);
228618334Speter	return hash;
228718334Speter      }
228818334Speter
228952284Sobrien    /* We handle SUBREG of a REG specially because the underlying
229052284Sobrien       reg changes its hash value with every value change; we don't
229152284Sobrien       want to have to forget unrelated subregs when one subreg changes.  */
229252284Sobrien    case SUBREG:
229352284Sobrien      {
229452284Sobrien	if (GET_CODE (SUBREG_REG (x)) == REG)
229552284Sobrien	  {
229652284Sobrien	    hash += (((unsigned) SUBREG << 7)
229790075Sobrien		     + REGNO (SUBREG_REG (x))
229890075Sobrien		     + (SUBREG_BYTE (x) / UNITS_PER_WORD));
229952284Sobrien	    return hash;
230052284Sobrien	  }
230152284Sobrien	break;
230252284Sobrien      }
230352284Sobrien
230418334Speter    case CONST_INT:
230518334Speter      {
230618334Speter	unsigned HOST_WIDE_INT tem = INTVAL (x);
230718334Speter	hash += ((unsigned) CONST_INT << 7) + (unsigned) mode + tem;
230818334Speter	return hash;
230918334Speter      }
231018334Speter
231118334Speter    case CONST_DOUBLE:
231218334Speter      /* This is like the general case, except that it only counts
231318334Speter	 the integers representing the constant.  */
231418334Speter      hash += (unsigned) code + (unsigned) GET_MODE (x);
231518334Speter      if (GET_MODE (x) != VOIDmode)
231618334Speter	for (i = 2; i < GET_RTX_LENGTH (CONST_DOUBLE); i++)
231718334Speter	  {
231890075Sobrien	    unsigned HOST_WIDE_INT tem = XWINT (x, i);
231918334Speter	    hash += tem;
232018334Speter	  }
232118334Speter      else
232218334Speter	hash += ((unsigned) CONST_DOUBLE_LOW (x)
232318334Speter		 + (unsigned) CONST_DOUBLE_HIGH (x));
232418334Speter      return hash;
232518334Speter
232618334Speter      /* Assume there is only one rtx object for any given label.  */
232718334Speter    case LABEL_REF:
232890075Sobrien      hash += ((unsigned) LABEL_REF << 7) + (unsigned long) XEXP (x, 0);
232918334Speter      return hash;
233018334Speter
233118334Speter    case SYMBOL_REF:
233290075Sobrien      hash += ((unsigned) SYMBOL_REF << 7) + (unsigned long) XSTR (x, 0);
233318334Speter      return hash;
233418334Speter
233518334Speter    case MEM:
233690075Sobrien      /* We don't record if marked volatile or if BLKmode since we don't
233790075Sobrien	 know the size of the move.  */
233890075Sobrien      if (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode)
233918334Speter	{
234018334Speter	  do_not_record = 1;
234118334Speter	  return 0;
234218334Speter	}
234350397Sobrien      if (! RTX_UNCHANGING_P (x) || FIXED_BASE_PLUS_P (XEXP (x, 0)))
234418334Speter	{
234518334Speter	  hash_arg_in_memory = 1;
234618334Speter	}
234718334Speter      /* Now that we have already found this special case,
234818334Speter	 might as well speed it up as much as possible.  */
234918334Speter      hash += (unsigned) MEM;
235018334Speter      x = XEXP (x, 0);
235118334Speter      goto repeat;
235218334Speter
235390075Sobrien    case USE:
235490075Sobrien      /* A USE that mentions non-volatile memory needs special
235590075Sobrien	 handling since the MEM may be BLKmode which normally
235690075Sobrien	 prevents an entry from being made.  Pure calls are
235790075Sobrien	 marked by a USE which mentions BLKmode memory.  */
235890075Sobrien      if (GET_CODE (XEXP (x, 0)) == MEM
235990075Sobrien	  && ! MEM_VOLATILE_P (XEXP (x, 0)))
236090075Sobrien	{
236190075Sobrien	  hash += (unsigned)USE;
236290075Sobrien	  x = XEXP (x, 0);
236390075Sobrien
236490075Sobrien	  if (! RTX_UNCHANGING_P (x) || FIXED_BASE_PLUS_P (XEXP (x, 0)))
236590075Sobrien	    hash_arg_in_memory = 1;
236690075Sobrien
236790075Sobrien	  /* Now that we have already found this special case,
236890075Sobrien	     might as well speed it up as much as possible.  */
236990075Sobrien	  hash += (unsigned) MEM;
237090075Sobrien	  x = XEXP (x, 0);
237190075Sobrien	  goto repeat;
237290075Sobrien	}
237390075Sobrien      break;
237490075Sobrien
237518334Speter    case PRE_DEC:
237618334Speter    case PRE_INC:
237718334Speter    case POST_DEC:
237818334Speter    case POST_INC:
237990075Sobrien    case PRE_MODIFY:
238090075Sobrien    case POST_MODIFY:
238118334Speter    case PC:
238218334Speter    case CC0:
238318334Speter    case CALL:
238418334Speter    case UNSPEC_VOLATILE:
238518334Speter      do_not_record = 1;
238618334Speter      return 0;
238718334Speter
238818334Speter    case ASM_OPERANDS:
238918334Speter      if (MEM_VOLATILE_P (x))
239018334Speter	{
239118334Speter	  do_not_record = 1;
239218334Speter	  return 0;
239318334Speter	}
239490075Sobrien      else
239590075Sobrien	{
239690075Sobrien	  /* We don't want to take the filename and line into account.  */
239790075Sobrien	  hash += (unsigned) code + (unsigned) GET_MODE (x)
239890075Sobrien	    + canon_hash_string (ASM_OPERANDS_TEMPLATE (x))
239990075Sobrien	    + canon_hash_string (ASM_OPERANDS_OUTPUT_CONSTRAINT (x))
240090075Sobrien	    + (unsigned) ASM_OPERANDS_OUTPUT_IDX (x);
240190075Sobrien
240290075Sobrien	  if (ASM_OPERANDS_INPUT_LENGTH (x))
240390075Sobrien	    {
240490075Sobrien	      for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
240590075Sobrien		{
240690075Sobrien		  hash += (canon_hash (ASM_OPERANDS_INPUT (x, i),
240790075Sobrien				       GET_MODE (ASM_OPERANDS_INPUT (x, i)))
240890075Sobrien			   + canon_hash_string (ASM_OPERANDS_INPUT_CONSTRAINT
240990075Sobrien						(x, i)));
241090075Sobrien		}
241190075Sobrien
241290075Sobrien	      hash += canon_hash_string (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0));
241390075Sobrien	      x = ASM_OPERANDS_INPUT (x, 0);
241490075Sobrien	      mode = GET_MODE (x);
241590075Sobrien	      goto repeat;
241690075Sobrien	    }
241790075Sobrien
241890075Sobrien	  return hash;
241990075Sobrien	}
242050397Sobrien      break;
242190075Sobrien
242250397Sobrien    default:
242350397Sobrien      break;
242418334Speter    }
242518334Speter
242618334Speter  i = GET_RTX_LENGTH (code) - 1;
242718334Speter  hash += (unsigned) code + (unsigned) GET_MODE (x);
242818334Speter  fmt = GET_RTX_FORMAT (code);
242918334Speter  for (; i >= 0; i--)
243018334Speter    {
243118334Speter      if (fmt[i] == 'e')
243218334Speter	{
243318334Speter	  rtx tem = XEXP (x, i);
243418334Speter
243518334Speter	  /* If we are about to do the last recursive call
243618334Speter	     needed at this level, change it into iteration.
243718334Speter	     This function  is called enough to be worth it.  */
243818334Speter	  if (i == 0)
243918334Speter	    {
244018334Speter	      x = tem;
244118334Speter	      goto repeat;
244218334Speter	    }
244318334Speter	  hash += canon_hash (tem, 0);
244418334Speter	}
244518334Speter      else if (fmt[i] == 'E')
244618334Speter	for (j = 0; j < XVECLEN (x, i); j++)
244718334Speter	  hash += canon_hash (XVECEXP (x, i, j), 0);
244818334Speter      else if (fmt[i] == 's')
244990075Sobrien	hash += canon_hash_string (XSTR (x, i));
245018334Speter      else if (fmt[i] == 'i')
245118334Speter	{
245290075Sobrien	  unsigned tem = XINT (x, i);
245318334Speter	  hash += tem;
245418334Speter	}
245590075Sobrien      else if (fmt[i] == '0' || fmt[i] == 't')
245690075Sobrien	/* Unused.  */
245790075Sobrien	;
245818334Speter      else
245918334Speter	abort ();
246018334Speter    }
246118334Speter  return hash;
246218334Speter}
246318334Speter
246418334Speter/* Like canon_hash but with no side effects.  */
246518334Speter
246618334Speterstatic unsigned
246718334Spetersafe_hash (x, mode)
246818334Speter     rtx x;
246918334Speter     enum machine_mode mode;
247018334Speter{
247118334Speter  int save_do_not_record = do_not_record;
247218334Speter  int save_hash_arg_in_memory = hash_arg_in_memory;
247318334Speter  unsigned hash = canon_hash (x, mode);
247418334Speter  hash_arg_in_memory = save_hash_arg_in_memory;
247518334Speter  do_not_record = save_do_not_record;
247618334Speter  return hash;
247718334Speter}
247818334Speter
247918334Speter/* Return 1 iff X and Y would canonicalize into the same thing,
248018334Speter   without actually constructing the canonicalization of either one.
248118334Speter   If VALIDATE is nonzero,
248218334Speter   we assume X is an expression being processed from the rtl
248318334Speter   and Y was found in the hash table.  We check register refs
248418334Speter   in Y for being marked as valid.
248518334Speter
248618334Speter   If EQUAL_VALUES is nonzero, we allow a register to match a constant value
248718334Speter   that is known to be in the register.  Ordinarily, we don't allow them
248818334Speter   to match, because letting them match would cause unpredictable results
248918334Speter   in all the places that search a hash table chain for an equivalent
249018334Speter   for a given value.  A possible equivalent that has different structure
249118334Speter   has its hash code computed from different data.  Whether the hash code
249250397Sobrien   is the same as that of the given value is pure luck.  */
249318334Speter
249418334Speterstatic int
249518334Speterexp_equiv_p (x, y, validate, equal_values)
249618334Speter     rtx x, y;
249718334Speter     int validate;
249818334Speter     int equal_values;
249918334Speter{
250090075Sobrien  int i, j;
250190075Sobrien  enum rtx_code code;
250290075Sobrien  const char *fmt;
250318334Speter
250418334Speter  /* Note: it is incorrect to assume an expression is equivalent to itself
250518334Speter     if VALIDATE is nonzero.  */
250618334Speter  if (x == y && !validate)
250718334Speter    return 1;
250818334Speter  if (x == 0 || y == 0)
250918334Speter    return x == y;
251018334Speter
251118334Speter  code = GET_CODE (x);
251218334Speter  if (code != GET_CODE (y))
251318334Speter    {
251418334Speter      if (!equal_values)
251518334Speter	return 0;
251618334Speter
251718334Speter      /* If X is a constant and Y is a register or vice versa, they may be
251818334Speter	 equivalent.  We only have to validate if Y is a register.  */
251918334Speter      if (CONSTANT_P (x) && GET_CODE (y) == REG
252090075Sobrien	  && REGNO_QTY_VALID_P (REGNO (y)))
252190075Sobrien	{
252290075Sobrien	  int y_q = REG_QTY (REGNO (y));
252390075Sobrien	  struct qty_table_elem *y_ent = &qty_table[y_q];
252418334Speter
252590075Sobrien	  if (GET_MODE (y) == y_ent->mode
252690075Sobrien	      && rtx_equal_p (x, y_ent->const_rtx)
252790075Sobrien	      && (! validate || REG_IN_TABLE (REGNO (y)) == REG_TICK (REGNO (y))))
252890075Sobrien	    return 1;
252990075Sobrien	}
253090075Sobrien
253118334Speter      if (CONSTANT_P (y) && code == REG
253290075Sobrien	  && REGNO_QTY_VALID_P (REGNO (x)))
253390075Sobrien	{
253490075Sobrien	  int x_q = REG_QTY (REGNO (x));
253590075Sobrien	  struct qty_table_elem *x_ent = &qty_table[x_q];
253618334Speter
253790075Sobrien	  if (GET_MODE (x) == x_ent->mode
253890075Sobrien	      && rtx_equal_p (y, x_ent->const_rtx))
253990075Sobrien	    return 1;
254090075Sobrien	}
254190075Sobrien
254218334Speter      return 0;
254318334Speter    }
254418334Speter
254518334Speter  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
254618334Speter  if (GET_MODE (x) != GET_MODE (y))
254718334Speter    return 0;
254818334Speter
254918334Speter  switch (code)
255018334Speter    {
255118334Speter    case PC:
255218334Speter    case CC0:
255390075Sobrien    case CONST_INT:
255418334Speter      return x == y;
255518334Speter
255618334Speter    case LABEL_REF:
255718334Speter      return XEXP (x, 0) == XEXP (y, 0);
255818334Speter
255918334Speter    case SYMBOL_REF:
256018334Speter      return XSTR (x, 0) == XSTR (y, 0);
256118334Speter
256218334Speter    case REG:
256318334Speter      {
256490075Sobrien	unsigned int regno = REGNO (y);
256590075Sobrien	unsigned int endregno
256618334Speter	  = regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
256718334Speter		     : HARD_REGNO_NREGS (regno, GET_MODE (y)));
256890075Sobrien	unsigned int i;
256918334Speter
257018334Speter	/* If the quantities are not the same, the expressions are not
257118334Speter	   equivalent.  If there are and we are not to validate, they
257218334Speter	   are equivalent.  Otherwise, ensure all regs are up-to-date.  */
257318334Speter
257452284Sobrien	if (REG_QTY (REGNO (x)) != REG_QTY (regno))
257518334Speter	  return 0;
257618334Speter
257718334Speter	if (! validate)
257818334Speter	  return 1;
257918334Speter
258018334Speter	for (i = regno; i < endregno; i++)
258152284Sobrien	  if (REG_IN_TABLE (i) != REG_TICK (i))
258218334Speter	    return 0;
258318334Speter
258418334Speter	return 1;
258518334Speter      }
258618334Speter
258718334Speter    /*  For commutative operations, check both orders.  */
258818334Speter    case PLUS:
258918334Speter    case MULT:
259018334Speter    case AND:
259118334Speter    case IOR:
259218334Speter    case XOR:
259318334Speter    case NE:
259418334Speter    case EQ:
259518334Speter      return ((exp_equiv_p (XEXP (x, 0), XEXP (y, 0), validate, equal_values)
259618334Speter	       && exp_equiv_p (XEXP (x, 1), XEXP (y, 1),
259718334Speter			       validate, equal_values))
259818334Speter	      || (exp_equiv_p (XEXP (x, 0), XEXP (y, 1),
259918334Speter			       validate, equal_values)
260018334Speter		  && exp_equiv_p (XEXP (x, 1), XEXP (y, 0),
260118334Speter				  validate, equal_values)));
260290075Sobrien
260390075Sobrien    case ASM_OPERANDS:
260490075Sobrien      /* We don't use the generic code below because we want to
260590075Sobrien	 disregard filename and line numbers.  */
260690075Sobrien
260790075Sobrien      /* A volatile asm isn't equivalent to any other.  */
260890075Sobrien      if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
260990075Sobrien	return 0;
261090075Sobrien
261190075Sobrien      if (GET_MODE (x) != GET_MODE (y)
261290075Sobrien	  || strcmp (ASM_OPERANDS_TEMPLATE (x), ASM_OPERANDS_TEMPLATE (y))
261390075Sobrien	  || strcmp (ASM_OPERANDS_OUTPUT_CONSTRAINT (x),
261490075Sobrien		     ASM_OPERANDS_OUTPUT_CONSTRAINT (y))
261590075Sobrien	  || ASM_OPERANDS_OUTPUT_IDX (x) != ASM_OPERANDS_OUTPUT_IDX (y)
261690075Sobrien	  || ASM_OPERANDS_INPUT_LENGTH (x) != ASM_OPERANDS_INPUT_LENGTH (y))
261790075Sobrien	return 0;
261890075Sobrien
261990075Sobrien      if (ASM_OPERANDS_INPUT_LENGTH (x))
262090075Sobrien	{
262190075Sobrien	  for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
262290075Sobrien	    if (! exp_equiv_p (ASM_OPERANDS_INPUT (x, i),
262390075Sobrien			       ASM_OPERANDS_INPUT (y, i),
262490075Sobrien			       validate, equal_values)
262590075Sobrien		|| strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i),
262690075Sobrien			   ASM_OPERANDS_INPUT_CONSTRAINT (y, i)))
262790075Sobrien	      return 0;
262890075Sobrien	}
262990075Sobrien
263090075Sobrien      return 1;
263190075Sobrien
263250397Sobrien    default:
263350397Sobrien      break;
263418334Speter    }
263518334Speter
263618334Speter  /* Compare the elements.  If any pair of corresponding elements
263718334Speter     fail to match, return 0 for the whole things.  */
263818334Speter
263918334Speter  fmt = GET_RTX_FORMAT (code);
264018334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
264118334Speter    {
264218334Speter      switch (fmt[i])
264318334Speter	{
264418334Speter	case 'e':
264518334Speter	  if (! exp_equiv_p (XEXP (x, i), XEXP (y, i), validate, equal_values))
264618334Speter	    return 0;
264718334Speter	  break;
264818334Speter
264918334Speter	case 'E':
265018334Speter	  if (XVECLEN (x, i) != XVECLEN (y, i))
265118334Speter	    return 0;
265218334Speter	  for (j = 0; j < XVECLEN (x, i); j++)
265318334Speter	    if (! exp_equiv_p (XVECEXP (x, i, j), XVECEXP (y, i, j),
265418334Speter			       validate, equal_values))
265518334Speter	      return 0;
265618334Speter	  break;
265718334Speter
265818334Speter	case 's':
265918334Speter	  if (strcmp (XSTR (x, i), XSTR (y, i)))
266018334Speter	    return 0;
266118334Speter	  break;
266218334Speter
266318334Speter	case 'i':
266418334Speter	  if (XINT (x, i) != XINT (y, i))
266518334Speter	    return 0;
266618334Speter	  break;
266718334Speter
266818334Speter	case 'w':
266918334Speter	  if (XWINT (x, i) != XWINT (y, i))
267018334Speter	    return 0;
267190075Sobrien	  break;
267218334Speter
267318334Speter	case '0':
267490075Sobrien	case 't':
267518334Speter	  break;
267618334Speter
267718334Speter	default:
267818334Speter	  abort ();
267918334Speter	}
268090075Sobrien    }
268118334Speter
268218334Speter  return 1;
268318334Speter}
268418334Speter
268550397Sobrien/* Return 1 if X has a value that can vary even between two
268650397Sobrien   executions of the program.  0 means X can be compared reliably
268750397Sobrien   against certain constants or near-constants.  */
268818334Speter
268918334Speterstatic int
269090075Sobriencse_rtx_varies_p (x, from_alias)
269190075Sobrien     rtx x;
269290075Sobrien     int from_alias;
269318334Speter{
269418334Speter  /* We need not check for X and the equivalence class being of the same
269518334Speter     mode because if X is equivalent to a constant in some mode, it
269618334Speter     doesn't vary in any mode.  */
269718334Speter
269850397Sobrien  if (GET_CODE (x) == REG
269990075Sobrien      && REGNO_QTY_VALID_P (REGNO (x)))
270090075Sobrien    {
270190075Sobrien      int x_q = REG_QTY (REGNO (x));
270290075Sobrien      struct qty_table_elem *x_ent = &qty_table[x_q];
270350397Sobrien
270490075Sobrien      if (GET_MODE (x) == x_ent->mode
270590075Sobrien	  && x_ent->const_rtx != NULL_RTX)
270690075Sobrien	return 0;
270790075Sobrien    }
270890075Sobrien
270950397Sobrien  if (GET_CODE (x) == PLUS
271050397Sobrien      && GET_CODE (XEXP (x, 1)) == CONST_INT
271118334Speter      && GET_CODE (XEXP (x, 0)) == REG
271290075Sobrien      && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))))
271390075Sobrien    {
271490075Sobrien      int x0_q = REG_QTY (REGNO (XEXP (x, 0)));
271590075Sobrien      struct qty_table_elem *x0_ent = &qty_table[x0_q];
271618334Speter
271790075Sobrien      if ((GET_MODE (XEXP (x, 0)) == x0_ent->mode)
271890075Sobrien	  && x0_ent->const_rtx != NULL_RTX)
271990075Sobrien	return 0;
272090075Sobrien    }
272190075Sobrien
272218334Speter  /* This can happen as the result of virtual register instantiation, if
272318334Speter     the initial constant is too large to be a valid address.  This gives
272418334Speter     us a three instruction sequence, load large offset into a register,
272518334Speter     load fp minus a constant into a register, then a MEM which is the
272618334Speter     sum of the two `constant' registers.  */
272750397Sobrien  if (GET_CODE (x) == PLUS
272850397Sobrien      && GET_CODE (XEXP (x, 0)) == REG
272950397Sobrien      && GET_CODE (XEXP (x, 1)) == REG
273050397Sobrien      && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0)))
273190075Sobrien      && REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))))
273290075Sobrien    {
273390075Sobrien      int x0_q = REG_QTY (REGNO (XEXP (x, 0)));
273490075Sobrien      int x1_q = REG_QTY (REGNO (XEXP (x, 1)));
273590075Sobrien      struct qty_table_elem *x0_ent = &qty_table[x0_q];
273690075Sobrien      struct qty_table_elem *x1_ent = &qty_table[x1_q];
273718334Speter
273890075Sobrien      if ((GET_MODE (XEXP (x, 0)) == x0_ent->mode)
273990075Sobrien	  && x0_ent->const_rtx != NULL_RTX
274090075Sobrien	  && (GET_MODE (XEXP (x, 1)) == x1_ent->mode)
274190075Sobrien	  && x1_ent->const_rtx != NULL_RTX)
274290075Sobrien	return 0;
274390075Sobrien    }
274490075Sobrien
274590075Sobrien  return rtx_varies_p (x, from_alias);
274618334Speter}
274718334Speter
274818334Speter/* Canonicalize an expression:
274918334Speter   replace each register reference inside it
275018334Speter   with the "oldest" equivalent register.
275118334Speter
275218334Speter   If INSN is non-zero and we are replacing a pseudo with a hard register
275318334Speter   or vice versa, validate_change is used to ensure that INSN remains valid
275418334Speter   after we make our substitution.  The calls are made with IN_GROUP non-zero
275518334Speter   so apply_change_group must be called upon the outermost return from this
275618334Speter   function (unless INSN is zero).  The result of apply_change_group can
275718334Speter   generally be discarded since the changes we are making are optional.  */
275818334Speter
275918334Speterstatic rtx
276018334Spetercanon_reg (x, insn)
276118334Speter     rtx x;
276218334Speter     rtx insn;
276318334Speter{
276490075Sobrien  int i;
276590075Sobrien  enum rtx_code code;
276690075Sobrien  const char *fmt;
276718334Speter
276818334Speter  if (x == 0)
276918334Speter    return x;
277018334Speter
277118334Speter  code = GET_CODE (x);
277218334Speter  switch (code)
277318334Speter    {
277418334Speter    case PC:
277518334Speter    case CC0:
277618334Speter    case CONST:
277718334Speter    case CONST_INT:
277818334Speter    case CONST_DOUBLE:
277918334Speter    case SYMBOL_REF:
278018334Speter    case LABEL_REF:
278118334Speter    case ADDR_VEC:
278218334Speter    case ADDR_DIFF_VEC:
278318334Speter      return x;
278418334Speter
278518334Speter    case REG:
278618334Speter      {
278790075Sobrien	int first;
278890075Sobrien	int q;
278990075Sobrien	struct qty_table_elem *ent;
279018334Speter
279118334Speter	/* Never replace a hard reg, because hard regs can appear
279218334Speter	   in more than one machine mode, and we must preserve the mode
279318334Speter	   of each occurrence.  Also, some hard regs appear in
279418334Speter	   MEMs that are shared and mustn't be altered.  Don't try to
279518334Speter	   replace any reg that maps to a reg of class NO_REGS.  */
279618334Speter	if (REGNO (x) < FIRST_PSEUDO_REGISTER
279718334Speter	    || ! REGNO_QTY_VALID_P (REGNO (x)))
279818334Speter	  return x;
279918334Speter
280090075Sobrien	q = REG_QTY (REGNO (x));
280190075Sobrien	ent = &qty_table[q];
280290075Sobrien	first = ent->first_reg;
280318334Speter	return (first >= FIRST_PSEUDO_REGISTER ? regno_reg_rtx[first]
280418334Speter		: REGNO_REG_CLASS (first) == NO_REGS ? x
280590075Sobrien		: gen_rtx_REG (ent->mode, first));
280618334Speter      }
280790075Sobrien
280850397Sobrien    default:
280950397Sobrien      break;
281018334Speter    }
281118334Speter
281218334Speter  fmt = GET_RTX_FORMAT (code);
281318334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
281418334Speter    {
281590075Sobrien      int j;
281618334Speter
281718334Speter      if (fmt[i] == 'e')
281818334Speter	{
281918334Speter	  rtx new = canon_reg (XEXP (x, i), insn);
282050397Sobrien	  int insn_code;
282118334Speter
282218334Speter	  /* If replacing pseudo with hard reg or vice versa, ensure the
282318334Speter	     insn remains valid.  Likewise if the insn has MATCH_DUPs.  */
282418334Speter	  if (insn != 0 && new != 0
282518334Speter	      && GET_CODE (new) == REG && GET_CODE (XEXP (x, i)) == REG
282618334Speter	      && (((REGNO (new) < FIRST_PSEUDO_REGISTER)
282718334Speter		   != (REGNO (XEXP (x, i)) < FIRST_PSEUDO_REGISTER))
282850397Sobrien		  || (insn_code = recog_memoized (insn)) < 0
282990075Sobrien		  || insn_data[insn_code].n_dups > 0))
283018334Speter	    validate_change (insn, &XEXP (x, i), new, 1);
283118334Speter	  else
283218334Speter	    XEXP (x, i) = new;
283318334Speter	}
283418334Speter      else if (fmt[i] == 'E')
283518334Speter	for (j = 0; j < XVECLEN (x, i); j++)
283618334Speter	  XVECEXP (x, i, j) = canon_reg (XVECEXP (x, i, j), insn);
283718334Speter    }
283818334Speter
283918334Speter  return x;
284018334Speter}
284118334Speter
284250397Sobrien/* LOC is a location within INSN that is an operand address (the contents of
284318334Speter   a MEM).  Find the best equivalent address to use that is valid for this
284418334Speter   insn.
284518334Speter
284618334Speter   On most CISC machines, complicated address modes are costly, and rtx_cost
284718334Speter   is a good approximation for that cost.  However, most RISC machines have
284818334Speter   only a few (usually only one) memory reference formats.  If an address is
284918334Speter   valid at all, it is often just as cheap as any other address.  Hence, for
285018334Speter   RISC machines, we use the configuration macro `ADDRESS_COST' to compare the
285118334Speter   costs of various addresses.  For two addresses of equal cost, choose the one
285218334Speter   with the highest `rtx_cost' value as that has the potential of eliminating
285318334Speter   the most insns.  For equal costs, we choose the first in the equivalence
285418334Speter   class.  Note that we ignore the fact that pseudo registers are cheaper
285518334Speter   than hard registers here because we would also prefer the pseudo registers.
285618334Speter  */
285718334Speter
285818334Speterstatic void
285990075Sobrienfind_best_addr (insn, loc, mode)
286018334Speter     rtx insn;
286118334Speter     rtx *loc;
286290075Sobrien     enum machine_mode mode;
286318334Speter{
286450397Sobrien  struct table_elt *elt;
286518334Speter  rtx addr = *loc;
286650397Sobrien#ifdef ADDRESS_COST
286750397Sobrien  struct table_elt *p;
286818334Speter  int found_better = 1;
286950397Sobrien#endif
287018334Speter  int save_do_not_record = do_not_record;
287118334Speter  int save_hash_arg_in_memory = hash_arg_in_memory;
287218334Speter  int addr_volatile;
287318334Speter  int regno;
287418334Speter  unsigned hash;
287518334Speter
287618334Speter  /* Do not try to replace constant addresses or addresses of local and
287718334Speter     argument slots.  These MEM expressions are made only once and inserted
287818334Speter     in many instructions, as well as being used to control symbol table
287918334Speter     output.  It is not safe to clobber them.
288018334Speter
288118334Speter     There are some uncommon cases where the address is already in a register
288218334Speter     for some reason, but we cannot take advantage of that because we have
288318334Speter     no easy way to unshare the MEM.  In addition, looking up all stack
288418334Speter     addresses is costly.  */
288518334Speter  if ((GET_CODE (addr) == PLUS
288618334Speter       && GET_CODE (XEXP (addr, 0)) == REG
288718334Speter       && GET_CODE (XEXP (addr, 1)) == CONST_INT
288818334Speter       && (regno = REGNO (XEXP (addr, 0)),
288918334Speter	   regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM
289018334Speter	   || regno == ARG_POINTER_REGNUM))
289118334Speter      || (GET_CODE (addr) == REG
289218334Speter	  && (regno = REGNO (addr), regno == FRAME_POINTER_REGNUM
289318334Speter	      || regno == HARD_FRAME_POINTER_REGNUM
289418334Speter	      || regno == ARG_POINTER_REGNUM))
289550397Sobrien      || GET_CODE (addr) == ADDRESSOF
289618334Speter      || CONSTANT_ADDRESS_P (addr))
289718334Speter    return;
289818334Speter
289918334Speter  /* If this address is not simply a register, try to fold it.  This will
290018334Speter     sometimes simplify the expression.  Many simplifications
290118334Speter     will not be valid, but some, usually applying the associative rule, will
290218334Speter     be valid and produce better code.  */
290350397Sobrien  if (GET_CODE (addr) != REG)
290450397Sobrien    {
290550397Sobrien      rtx folded = fold_rtx (copy_rtx (addr), NULL_RTX);
290690075Sobrien      int addr_folded_cost = address_cost (folded, mode);
290790075Sobrien      int addr_cost = address_cost (addr, mode);
290850397Sobrien
290990075Sobrien      if ((addr_folded_cost < addr_cost
291090075Sobrien	   || (addr_folded_cost == addr_cost
291190075Sobrien	       /* ??? The rtx_cost comparison is left over from an older
291290075Sobrien		  version of this code.  It is probably no longer helpful.  */
291390075Sobrien	       && (rtx_cost (folded, MEM) > rtx_cost (addr, MEM)
291490075Sobrien		   || approx_reg_cost (folded) < approx_reg_cost (addr))))
291550397Sobrien	  && validate_change (insn, loc, folded, 0))
291650397Sobrien	addr = folded;
291750397Sobrien    }
291890075Sobrien
291918334Speter  /* If this address is not in the hash table, we can't look for equivalences
292018334Speter     of the whole address.  Also, ignore if volatile.  */
292118334Speter
292218334Speter  do_not_record = 0;
292318334Speter  hash = HASH (addr, Pmode);
292418334Speter  addr_volatile = do_not_record;
292518334Speter  do_not_record = save_do_not_record;
292618334Speter  hash_arg_in_memory = save_hash_arg_in_memory;
292718334Speter
292818334Speter  if (addr_volatile)
292918334Speter    return;
293018334Speter
293118334Speter  elt = lookup (addr, hash, Pmode);
293218334Speter
293318334Speter#ifndef ADDRESS_COST
293418334Speter  if (elt)
293518334Speter    {
293650397Sobrien      int our_cost = elt->cost;
293718334Speter
293818334Speter      /* Find the lowest cost below ours that works.  */
293918334Speter      for (elt = elt->first_same_value; elt; elt = elt->next_same_value)
294018334Speter	if (elt->cost < our_cost
294118334Speter	    && (GET_CODE (elt->exp) == REG
294218334Speter		|| exp_equiv_p (elt->exp, elt->exp, 1, 0))
294318334Speter	    && validate_change (insn, loc,
294418334Speter				canon_reg (copy_rtx (elt->exp), NULL_RTX), 0))
294518334Speter	  return;
294618334Speter    }
294718334Speter#else
294818334Speter
294918334Speter  if (elt)
295018334Speter    {
295118334Speter      /* We need to find the best (under the criteria documented above) entry
295218334Speter	 in the class that is valid.  We use the `flag' field to indicate
295318334Speter	 choices that were invalid and iterate until we can't find a better
295418334Speter	 one that hasn't already been tried.  */
295518334Speter
295618334Speter      for (p = elt->first_same_value; p; p = p->next_same_value)
295718334Speter	p->flag = 0;
295818334Speter
295918334Speter      while (found_better)
296018334Speter	{
296190075Sobrien	  int best_addr_cost = address_cost (*loc, mode);
296218334Speter	  int best_rtx_cost = (elt->cost + 1) >> 1;
296390075Sobrien	  int exp_cost;
296490075Sobrien	  struct table_elt *best_elt = elt;
296518334Speter
296618334Speter	  found_better = 0;
296718334Speter	  for (p = elt->first_same_value; p; p = p->next_same_value)
296850397Sobrien	    if (! p->flag)
296918334Speter	      {
297050397Sobrien		if ((GET_CODE (p->exp) == REG
297150397Sobrien		     || exp_equiv_p (p->exp, p->exp, 1, 0))
297290075Sobrien		    && ((exp_cost = address_cost (p->exp, mode)) < best_addr_cost
297390075Sobrien			|| (exp_cost == best_addr_cost
297490075Sobrien			    && ((p->cost + 1) >> 1) > best_rtx_cost)))
297550397Sobrien		  {
297650397Sobrien		    found_better = 1;
297790075Sobrien		    best_addr_cost = exp_cost;
297850397Sobrien		    best_rtx_cost = (p->cost + 1) >> 1;
297950397Sobrien		    best_elt = p;
298050397Sobrien		  }
298118334Speter	      }
298218334Speter
298318334Speter	  if (found_better)
298418334Speter	    {
298518334Speter	      if (validate_change (insn, loc,
298618334Speter				   canon_reg (copy_rtx (best_elt->exp),
298718334Speter					      NULL_RTX), 0))
298818334Speter		return;
298918334Speter	      else
299018334Speter		best_elt->flag = 1;
299118334Speter	    }
299218334Speter	}
299318334Speter    }
299418334Speter
299518334Speter  /* If the address is a binary operation with the first operand a register
299618334Speter     and the second a constant, do the same as above, but looking for
299718334Speter     equivalences of the register.  Then try to simplify before checking for
299818334Speter     the best address to use.  This catches a few cases:  First is when we
299918334Speter     have REG+const and the register is another REG+const.  We can often merge
300018334Speter     the constants and eliminate one insn and one register.  It may also be
300118334Speter     that a machine has a cheap REG+REG+const.  Finally, this improves the
300218334Speter     code on the Alpha for unaligned byte stores.  */
300318334Speter
300418334Speter  if (flag_expensive_optimizations
300518334Speter      && (GET_RTX_CLASS (GET_CODE (*loc)) == '2'
300618334Speter	  || GET_RTX_CLASS (GET_CODE (*loc)) == 'c')
300718334Speter      && GET_CODE (XEXP (*loc, 0)) == REG
300818334Speter      && GET_CODE (XEXP (*loc, 1)) == CONST_INT)
300918334Speter    {
301018334Speter      rtx c = XEXP (*loc, 1);
301118334Speter
301218334Speter      do_not_record = 0;
301318334Speter      hash = HASH (XEXP (*loc, 0), Pmode);
301418334Speter      do_not_record = save_do_not_record;
301518334Speter      hash_arg_in_memory = save_hash_arg_in_memory;
301618334Speter
301718334Speter      elt = lookup (XEXP (*loc, 0), hash, Pmode);
301818334Speter      if (elt == 0)
301918334Speter	return;
302018334Speter
302118334Speter      /* We need to find the best (under the criteria documented above) entry
302218334Speter	 in the class that is valid.  We use the `flag' field to indicate
302318334Speter	 choices that were invalid and iterate until we can't find a better
302418334Speter	 one that hasn't already been tried.  */
302518334Speter
302618334Speter      for (p = elt->first_same_value; p; p = p->next_same_value)
302718334Speter	p->flag = 0;
302818334Speter
302918334Speter      while (found_better)
303018334Speter	{
303190075Sobrien	  int best_addr_cost = address_cost (*loc, mode);
303218334Speter	  int best_rtx_cost = (COST (*loc) + 1) >> 1;
303390075Sobrien	  struct table_elt *best_elt = elt;
303418334Speter	  rtx best_rtx = *loc;
303518334Speter	  int count;
303618334Speter
303718334Speter	  /* This is at worst case an O(n^2) algorithm, so limit our search
303818334Speter	     to the first 32 elements on the list.  This avoids trouble
303918334Speter	     compiling code with very long basic blocks that can easily
304090075Sobrien	     call simplify_gen_binary so many times that we run out of
304190075Sobrien	     memory.  */
304218334Speter
304318334Speter	  found_better = 0;
304418334Speter	  for (p = elt->first_same_value, count = 0;
304518334Speter	       p && count < 32;
304618334Speter	       p = p->next_same_value, count++)
304718334Speter	    if (! p->flag
304818334Speter		&& (GET_CODE (p->exp) == REG
304918334Speter		    || exp_equiv_p (p->exp, p->exp, 1, 0)))
305018334Speter	      {
305190075Sobrien		rtx new = simplify_gen_binary (GET_CODE (*loc), Pmode,
305290075Sobrien					       p->exp, c);
305390075Sobrien		int new_cost;
305490075Sobrien		new_cost = address_cost (new, mode);
305518334Speter
305690075Sobrien		if (new_cost < best_addr_cost
305790075Sobrien		    || (new_cost == best_addr_cost
305890075Sobrien			&& (COST (new) + 1) >> 1 > best_rtx_cost))
305918334Speter		  {
306018334Speter		    found_better = 1;
306190075Sobrien		    best_addr_cost = new_cost;
306218334Speter		    best_rtx_cost = (COST (new) + 1) >> 1;
306318334Speter		    best_elt = p;
306418334Speter		    best_rtx = new;
306518334Speter		  }
306618334Speter	      }
306718334Speter
306818334Speter	  if (found_better)
306918334Speter	    {
307018334Speter	      if (validate_change (insn, loc,
307118334Speter				   canon_reg (copy_rtx (best_rtx),
307218334Speter					      NULL_RTX), 0))
307318334Speter		return;
307418334Speter	      else
307518334Speter		best_elt->flag = 1;
307618334Speter	    }
307718334Speter	}
307818334Speter    }
307918334Speter#endif
308018334Speter}
308118334Speter
308218334Speter/* Given an operation (CODE, *PARG1, *PARG2), where code is a comparison
308318334Speter   operation (EQ, NE, GT, etc.), follow it back through the hash table and
308418334Speter   what values are being compared.
308518334Speter
308618334Speter   *PARG1 and *PARG2 are updated to contain the rtx representing the values
308718334Speter   actually being compared.  For example, if *PARG1 was (cc0) and *PARG2
308818334Speter   was (const_int 0), *PARG1 and *PARG2 will be set to the objects that were
308918334Speter   compared to produce cc0.
309018334Speter
309118334Speter   The return value is the comparison operator and is either the code of
309218334Speter   A or the code corresponding to the inverse of the comparison.  */
309318334Speter
309418334Speterstatic enum rtx_code
309518334Speterfind_comparison_args (code, parg1, parg2, pmode1, pmode2)
309618334Speter     enum rtx_code code;
309718334Speter     rtx *parg1, *parg2;
309818334Speter     enum machine_mode *pmode1, *pmode2;
309918334Speter{
310018334Speter  rtx arg1, arg2;
310118334Speter
310218334Speter  arg1 = *parg1, arg2 = *parg2;
310318334Speter
310418334Speter  /* If ARG2 is const0_rtx, see what ARG1 is equivalent to.  */
310518334Speter
310618334Speter  while (arg2 == CONST0_RTX (GET_MODE (arg1)))
310718334Speter    {
310818334Speter      /* Set non-zero when we find something of interest.  */
310918334Speter      rtx x = 0;
311018334Speter      int reverse_code = 0;
311118334Speter      struct table_elt *p = 0;
311218334Speter
311318334Speter      /* If arg1 is a COMPARE, extract the comparison arguments from it.
311418334Speter	 On machines with CC0, this is the only case that can occur, since
311518334Speter	 fold_rtx will return the COMPARE or item being compared with zero
311618334Speter	 when given CC0.  */
311718334Speter
311818334Speter      if (GET_CODE (arg1) == COMPARE && arg2 == const0_rtx)
311918334Speter	x = arg1;
312018334Speter
312118334Speter      /* If ARG1 is a comparison operator and CODE is testing for
312218334Speter	 STORE_FLAG_VALUE, get the inner arguments.  */
312318334Speter
312418334Speter      else if (GET_RTX_CLASS (GET_CODE (arg1)) == '<')
312518334Speter	{
312618334Speter	  if (code == NE
312718334Speter	      || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_INT
312818334Speter		  && code == LT && STORE_FLAG_VALUE == -1)
312918334Speter#ifdef FLOAT_STORE_FLAG_VALUE
313018334Speter	      || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_FLOAT
313190075Sobrien		  && (REAL_VALUE_NEGATIVE
313290075Sobrien		      (FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)))))
313318334Speter#endif
313418334Speter	      )
313518334Speter	    x = arg1;
313618334Speter	  else if (code == EQ
313718334Speter		   || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_INT
313818334Speter		       && code == GE && STORE_FLAG_VALUE == -1)
313918334Speter#ifdef FLOAT_STORE_FLAG_VALUE
314018334Speter		   || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_FLOAT
314190075Sobrien		       && (REAL_VALUE_NEGATIVE
314290075Sobrien			   (FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)))))
314318334Speter#endif
314418334Speter		   )
314518334Speter	    x = arg1, reverse_code = 1;
314618334Speter	}
314718334Speter
314818334Speter      /* ??? We could also check for
314918334Speter
315018334Speter	 (ne (and (eq (...) (const_int 1))) (const_int 0))
315118334Speter
315218334Speter	 and related forms, but let's wait until we see them occurring.  */
315318334Speter
315418334Speter      if (x == 0)
315518334Speter	/* Look up ARG1 in the hash table and see if it has an equivalence
315618334Speter	   that lets us see what is being compared.  */
315790075Sobrien	p = lookup (arg1, safe_hash (arg1, GET_MODE (arg1)) & HASH_MASK,
315818334Speter		    GET_MODE (arg1));
315990075Sobrien      if (p)
316090075Sobrien	{
316190075Sobrien	  p = p->first_same_value;
316218334Speter
316390075Sobrien	  /* If what we compare is already known to be constant, that is as
316490075Sobrien	     good as it gets.
316590075Sobrien	     We need to break the loop in this case, because otherwise we
316690075Sobrien	     can have an infinite loop when looking at a reg that is known
316790075Sobrien	     to be a constant which is the same as a comparison of a reg
316890075Sobrien	     against zero which appears later in the insn stream, which in
316990075Sobrien	     turn is constant and the same as the comparison of the first reg
317090075Sobrien	     against zero...  */
317190075Sobrien	  if (p->is_const)
317290075Sobrien	    break;
317390075Sobrien	}
317490075Sobrien
317518334Speter      for (; p; p = p->next_same_value)
317618334Speter	{
317718334Speter	  enum machine_mode inner_mode = GET_MODE (p->exp);
317818334Speter
317918334Speter	  /* If the entry isn't valid, skip it.  */
318018334Speter	  if (! exp_equiv_p (p->exp, p->exp, 1, 0))
318118334Speter	    continue;
318218334Speter
318318334Speter	  if (GET_CODE (p->exp) == COMPARE
318418334Speter	      /* Another possibility is that this machine has a compare insn
318518334Speter		 that includes the comparison code.  In that case, ARG1 would
318618334Speter		 be equivalent to a comparison operation that would set ARG1 to
318718334Speter		 either STORE_FLAG_VALUE or zero.  If this is an NE operation,
318818334Speter		 ORIG_CODE is the actual comparison being done; if it is an EQ,
318918334Speter		 we must reverse ORIG_CODE.  On machine with a negative value
319018334Speter		 for STORE_FLAG_VALUE, also look at LT and GE operations.  */
319118334Speter	      || ((code == NE
319218334Speter		   || (code == LT
319318334Speter		       && GET_MODE_CLASS (inner_mode) == MODE_INT
319418334Speter		       && (GET_MODE_BITSIZE (inner_mode)
319518334Speter			   <= HOST_BITS_PER_WIDE_INT)
319618334Speter		       && (STORE_FLAG_VALUE
319718334Speter			   & ((HOST_WIDE_INT) 1
319818334Speter			      << (GET_MODE_BITSIZE (inner_mode) - 1))))
319918334Speter#ifdef FLOAT_STORE_FLAG_VALUE
320018334Speter		   || (code == LT
320118334Speter		       && GET_MODE_CLASS (inner_mode) == MODE_FLOAT
320290075Sobrien		       && (REAL_VALUE_NEGATIVE
320390075Sobrien			   (FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)))))
320418334Speter#endif
320518334Speter		   )
320618334Speter		  && GET_RTX_CLASS (GET_CODE (p->exp)) == '<'))
320718334Speter	    {
320818334Speter	      x = p->exp;
320918334Speter	      break;
321018334Speter	    }
321118334Speter	  else if ((code == EQ
321218334Speter		    || (code == GE
321318334Speter			&& GET_MODE_CLASS (inner_mode) == MODE_INT
321418334Speter			&& (GET_MODE_BITSIZE (inner_mode)
321518334Speter			    <= HOST_BITS_PER_WIDE_INT)
321618334Speter			&& (STORE_FLAG_VALUE
321718334Speter			    & ((HOST_WIDE_INT) 1
321818334Speter			       << (GET_MODE_BITSIZE (inner_mode) - 1))))
321918334Speter#ifdef FLOAT_STORE_FLAG_VALUE
322018334Speter		    || (code == GE
322118334Speter			&& GET_MODE_CLASS (inner_mode) == MODE_FLOAT
322290075Sobrien		        && (REAL_VALUE_NEGATIVE
322390075Sobrien			    (FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)))))
322418334Speter#endif
322518334Speter		    )
322618334Speter		   && GET_RTX_CLASS (GET_CODE (p->exp)) == '<')
322718334Speter	    {
322818334Speter	      reverse_code = 1;
322918334Speter	      x = p->exp;
323018334Speter	      break;
323118334Speter	    }
323218334Speter
323318334Speter	  /* If this is fp + constant, the equivalent is a better operand since
323418334Speter	     it may let us predict the value of the comparison.  */
323518334Speter	  else if (NONZERO_BASE_PLUS_P (p->exp))
323618334Speter	    {
323718334Speter	      arg1 = p->exp;
323818334Speter	      continue;
323918334Speter	    }
324018334Speter	}
324118334Speter
324218334Speter      /* If we didn't find a useful equivalence for ARG1, we are done.
324318334Speter	 Otherwise, set up for the next iteration.  */
324418334Speter      if (x == 0)
324518334Speter	break;
324618334Speter
324790075Sobrien      /* If we need to reverse the comparison, make sure that that is
324890075Sobrien	 possible -- we can't necessarily infer the value of GE from LT
324990075Sobrien	 with floating-point operands.  */
325090075Sobrien      if (reverse_code)
325190075Sobrien	{
325290075Sobrien	  enum rtx_code reversed = reversed_comparison_code (x, NULL_RTX);
325390075Sobrien	  if (reversed == UNKNOWN)
325490075Sobrien	    break;
325590075Sobrien	  else code = reversed;
325690075Sobrien	}
325790075Sobrien      else if (GET_RTX_CLASS (GET_CODE (x)) == '<')
325818334Speter	code = GET_CODE (x);
325990075Sobrien      arg1 = XEXP (x, 0), arg2 = XEXP (x, 1);
326018334Speter    }
326118334Speter
326218334Speter  /* Return our results.  Return the modes from before fold_rtx
326318334Speter     because fold_rtx might produce const_int, and then it's too late.  */
326418334Speter  *pmode1 = GET_MODE (arg1), *pmode2 = GET_MODE (arg2);
326518334Speter  *parg1 = fold_rtx (arg1, 0), *parg2 = fold_rtx (arg2, 0);
326618334Speter
326718334Speter  return code;
326818334Speter}
326918334Speter
327018334Speter/* If X is a nontrivial arithmetic operation on an argument
327118334Speter   for which a constant value can be determined, return
327218334Speter   the result of operating on that value, as a constant.
327318334Speter   Otherwise, return X, possibly with one or more operands
327418334Speter   modified by recursive calls to this function.
327518334Speter
327618334Speter   If X is a register whose contents are known, we do NOT
327718334Speter   return those contents here.  equiv_constant is called to
327818334Speter   perform that task.
327918334Speter
328018334Speter   INSN is the insn that we may be modifying.  If it is 0, make a copy
328118334Speter   of X before modifying it.  */
328218334Speter
328318334Speterstatic rtx
328418334Speterfold_rtx (x, insn)
328518334Speter     rtx x;
328690075Sobrien     rtx insn;
328718334Speter{
328890075Sobrien  enum rtx_code code;
328990075Sobrien  enum machine_mode mode;
329090075Sobrien  const char *fmt;
329190075Sobrien  int i;
329218334Speter  rtx new = 0;
329318334Speter  int copied = 0;
329418334Speter  int must_swap = 0;
329518334Speter
329618334Speter  /* Folded equivalents of first two operands of X.  */
329718334Speter  rtx folded_arg0;
329818334Speter  rtx folded_arg1;
329918334Speter
330018334Speter  /* Constant equivalents of first three operands of X;
330118334Speter     0 when no such equivalent is known.  */
330218334Speter  rtx const_arg0;
330318334Speter  rtx const_arg1;
330418334Speter  rtx const_arg2;
330518334Speter
330618334Speter  /* The mode of the first operand of X.  We need this for sign and zero
330718334Speter     extends.  */
330818334Speter  enum machine_mode mode_arg0;
330918334Speter
331018334Speter  if (x == 0)
331118334Speter    return x;
331218334Speter
331318334Speter  mode = GET_MODE (x);
331418334Speter  code = GET_CODE (x);
331518334Speter  switch (code)
331618334Speter    {
331718334Speter    case CONST:
331818334Speter    case CONST_INT:
331918334Speter    case CONST_DOUBLE:
332018334Speter    case SYMBOL_REF:
332118334Speter    case LABEL_REF:
332218334Speter    case REG:
332318334Speter      /* No use simplifying an EXPR_LIST
332418334Speter	 since they are used only for lists of args
332518334Speter	 in a function call's REG_EQUAL note.  */
332618334Speter    case EXPR_LIST:
332750397Sobrien      /* Changing anything inside an ADDRESSOF is incorrect; we don't
332850397Sobrien	 want to (e.g.,) make (addressof (const_int 0)) just because
332950397Sobrien	 the location is known to be zero.  */
333050397Sobrien    case ADDRESSOF:
333118334Speter      return x;
333218334Speter
333318334Speter#ifdef HAVE_cc0
333418334Speter    case CC0:
333518334Speter      return prev_insn_cc0;
333618334Speter#endif
333718334Speter
333818334Speter    case PC:
333918334Speter      /* If the next insn is a CODE_LABEL followed by a jump table,
334018334Speter	 PC's value is a LABEL_REF pointing to that label.  That
334190075Sobrien	 lets us fold switch statements on the VAX.  */
334218334Speter      if (insn && GET_CODE (insn) == JUMP_INSN)
334318334Speter	{
334418334Speter	  rtx next = next_nonnote_insn (insn);
334518334Speter
334618334Speter	  if (next && GET_CODE (next) == CODE_LABEL
334718334Speter	      && NEXT_INSN (next) != 0
334818334Speter	      && GET_CODE (NEXT_INSN (next)) == JUMP_INSN
334918334Speter	      && (GET_CODE (PATTERN (NEXT_INSN (next))) == ADDR_VEC
335018334Speter		  || GET_CODE (PATTERN (NEXT_INSN (next))) == ADDR_DIFF_VEC))
335150397Sobrien	    return gen_rtx_LABEL_REF (Pmode, next);
335218334Speter	}
335318334Speter      break;
335418334Speter
335518334Speter    case SUBREG:
335618334Speter      /* See if we previously assigned a constant value to this SUBREG.  */
335718334Speter      if ((new = lookup_as_function (x, CONST_INT)) != 0
335818334Speter	  || (new = lookup_as_function (x, CONST_DOUBLE)) != 0)
335918334Speter	return new;
336018334Speter
336118334Speter      /* If this is a paradoxical SUBREG, we have no idea what value the
336218334Speter	 extra bits would have.  However, if the operand is equivalent
336318334Speter	 to a SUBREG whose operand is the same as our mode, and all the
336418334Speter	 modes are within a word, we can just use the inner operand
336518334Speter	 because these SUBREGs just say how to treat the register.
336618334Speter
336718334Speter	 Similarly if we find an integer constant.  */
336818334Speter
336918334Speter      if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
337018334Speter	{
337118334Speter	  enum machine_mode imode = GET_MODE (SUBREG_REG (x));
337218334Speter	  struct table_elt *elt;
337318334Speter
337418334Speter	  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
337518334Speter	      && GET_MODE_SIZE (imode) <= UNITS_PER_WORD
337618334Speter	      && (elt = lookup (SUBREG_REG (x), HASH (SUBREG_REG (x), imode),
337718334Speter				imode)) != 0)
337890075Sobrien	    for (elt = elt->first_same_value; elt; elt = elt->next_same_value)
337918334Speter	      {
338018334Speter		if (CONSTANT_P (elt->exp)
338118334Speter		    && GET_MODE (elt->exp) == VOIDmode)
338218334Speter		  return elt->exp;
338318334Speter
338418334Speter		if (GET_CODE (elt->exp) == SUBREG
338518334Speter		    && GET_MODE (SUBREG_REG (elt->exp)) == mode
338618334Speter		    && exp_equiv_p (elt->exp, elt->exp, 1, 0))
338718334Speter		  return copy_rtx (SUBREG_REG (elt->exp));
338890075Sobrien	      }
338918334Speter
339018334Speter	  return x;
339118334Speter	}
339218334Speter
339318334Speter      /* Fold SUBREG_REG.  If it changed, see if we can simplify the SUBREG.
339418334Speter	 We might be able to if the SUBREG is extracting a single word in an
339518334Speter	 integral mode or extracting the low part.  */
339618334Speter
339718334Speter      folded_arg0 = fold_rtx (SUBREG_REG (x), insn);
339818334Speter      const_arg0 = equiv_constant (folded_arg0);
339918334Speter      if (const_arg0)
340018334Speter	folded_arg0 = const_arg0;
340118334Speter
340218334Speter      if (folded_arg0 != SUBREG_REG (x))
340318334Speter	{
340490075Sobrien	  new = simplify_subreg (mode, folded_arg0,
340590075Sobrien				 GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
340618334Speter	  if (new)
340718334Speter	    return new;
340818334Speter	}
340918334Speter
341018334Speter      /* If this is a narrowing SUBREG and our operand is a REG, see if
341118334Speter	 we can find an equivalence for REG that is an arithmetic operation
341218334Speter	 in a wider mode where both operands are paradoxical SUBREGs
341318334Speter	 from objects of our result mode.  In that case, we couldn't report
341418334Speter	 an equivalent value for that operation, since we don't know what the
341518334Speter	 extra bits will be.  But we can find an equivalence for this SUBREG
341618334Speter	 by folding that operation is the narrow mode.  This allows us to
341718334Speter	 fold arithmetic in narrow modes when the machine only supports
341890075Sobrien	 word-sized arithmetic.
341918334Speter
342018334Speter	 Also look for a case where we have a SUBREG whose operand is the
342118334Speter	 same as our result.  If both modes are smaller than a word, we
342218334Speter	 are simply interpreting a register in different modes and we
342318334Speter	 can use the inner value.  */
342418334Speter
342518334Speter      if (GET_CODE (folded_arg0) == REG
342618334Speter	  && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (folded_arg0))
342718334Speter	  && subreg_lowpart_p (x))
342818334Speter	{
342918334Speter	  struct table_elt *elt;
343018334Speter
343118334Speter	  /* We can use HASH here since we know that canon_hash won't be
343218334Speter	     called.  */
343318334Speter	  elt = lookup (folded_arg0,
343418334Speter			HASH (folded_arg0, GET_MODE (folded_arg0)),
343518334Speter			GET_MODE (folded_arg0));
343618334Speter
343718334Speter	  if (elt)
343818334Speter	    elt = elt->first_same_value;
343918334Speter
344018334Speter	  for (; elt; elt = elt->next_same_value)
344118334Speter	    {
344218334Speter	      enum rtx_code eltcode = GET_CODE (elt->exp);
344318334Speter
344418334Speter	      /* Just check for unary and binary operations.  */
344518334Speter	      if (GET_RTX_CLASS (GET_CODE (elt->exp)) == '1'
344618334Speter		  && GET_CODE (elt->exp) != SIGN_EXTEND
344718334Speter		  && GET_CODE (elt->exp) != ZERO_EXTEND
344818334Speter		  && GET_CODE (XEXP (elt->exp, 0)) == SUBREG
344918334Speter		  && GET_MODE (SUBREG_REG (XEXP (elt->exp, 0))) == mode)
345018334Speter		{
345118334Speter		  rtx op0 = SUBREG_REG (XEXP (elt->exp, 0));
345218334Speter
345318334Speter		  if (GET_CODE (op0) != REG && ! CONSTANT_P (op0))
345418334Speter		    op0 = fold_rtx (op0, NULL_RTX);
345518334Speter
345618334Speter		  op0 = equiv_constant (op0);
345718334Speter		  if (op0)
345818334Speter		    new = simplify_unary_operation (GET_CODE (elt->exp), mode,
345918334Speter						    op0, mode);
346018334Speter		}
346118334Speter	      else if ((GET_RTX_CLASS (GET_CODE (elt->exp)) == '2'
346218334Speter			|| GET_RTX_CLASS (GET_CODE (elt->exp)) == 'c')
346318334Speter		       && eltcode != DIV && eltcode != MOD
346418334Speter		       && eltcode != UDIV && eltcode != UMOD
346518334Speter		       && eltcode != ASHIFTRT && eltcode != LSHIFTRT
346618334Speter		       && eltcode != ROTATE && eltcode != ROTATERT
346718334Speter		       && ((GET_CODE (XEXP (elt->exp, 0)) == SUBREG
346818334Speter			    && (GET_MODE (SUBREG_REG (XEXP (elt->exp, 0)))
346918334Speter				== mode))
347018334Speter			   || CONSTANT_P (XEXP (elt->exp, 0)))
347118334Speter		       && ((GET_CODE (XEXP (elt->exp, 1)) == SUBREG
347218334Speter			    && (GET_MODE (SUBREG_REG (XEXP (elt->exp, 1)))
347318334Speter				== mode))
347418334Speter			   || CONSTANT_P (XEXP (elt->exp, 1))))
347518334Speter		{
347618334Speter		  rtx op0 = gen_lowpart_common (mode, XEXP (elt->exp, 0));
347718334Speter		  rtx op1 = gen_lowpart_common (mode, XEXP (elt->exp, 1));
347818334Speter
347918334Speter		  if (op0 && GET_CODE (op0) != REG && ! CONSTANT_P (op0))
348018334Speter		    op0 = fold_rtx (op0, NULL_RTX);
348118334Speter
348218334Speter		  if (op0)
348318334Speter		    op0 = equiv_constant (op0);
348418334Speter
348518334Speter		  if (op1 && GET_CODE (op1) != REG && ! CONSTANT_P (op1))
348618334Speter		    op1 = fold_rtx (op1, NULL_RTX);
348718334Speter
348818334Speter		  if (op1)
348918334Speter		    op1 = equiv_constant (op1);
349018334Speter
349190075Sobrien		  /* If we are looking for the low SImode part of
349218334Speter		     (ashift:DI c (const_int 32)), it doesn't work
349318334Speter		     to compute that in SImode, because a 32-bit shift
349418334Speter		     in SImode is unpredictable.  We know the value is 0.  */
349518334Speter		  if (op0 && op1
349618334Speter		      && GET_CODE (elt->exp) == ASHIFT
349718334Speter		      && GET_CODE (op1) == CONST_INT
349818334Speter		      && INTVAL (op1) >= GET_MODE_BITSIZE (mode))
349918334Speter		    {
350018334Speter		      if (INTVAL (op1) < GET_MODE_BITSIZE (GET_MODE (elt->exp)))
350190075Sobrien
350218334Speter			/* If the count fits in the inner mode's width,
350318334Speter			   but exceeds the outer mode's width,
350418334Speter			   the value will get truncated to 0
350518334Speter			   by the subreg.  */
350618334Speter			new = const0_rtx;
350718334Speter		      else
350818334Speter			/* If the count exceeds even the inner mode's width,
350918334Speter			   don't fold this expression.  */
351018334Speter			new = 0;
351118334Speter		    }
351218334Speter		  else if (op0 && op1)
351318334Speter		    new = simplify_binary_operation (GET_CODE (elt->exp), mode,
351418334Speter						     op0, op1);
351518334Speter		}
351618334Speter
351718334Speter	      else if (GET_CODE (elt->exp) == SUBREG
351818334Speter		       && GET_MODE (SUBREG_REG (elt->exp)) == mode
351918334Speter		       && (GET_MODE_SIZE (GET_MODE (folded_arg0))
352018334Speter			   <= UNITS_PER_WORD)
352118334Speter		       && exp_equiv_p (elt->exp, elt->exp, 1, 0))
352218334Speter		new = copy_rtx (SUBREG_REG (elt->exp));
352318334Speter
352418334Speter	      if (new)
352518334Speter		return new;
352618334Speter	    }
352718334Speter	}
352818334Speter
352918334Speter      return x;
353018334Speter
353118334Speter    case NOT:
353218334Speter    case NEG:
353318334Speter      /* If we have (NOT Y), see if Y is known to be (NOT Z).
353418334Speter	 If so, (NOT Y) simplifies to Z.  Similarly for NEG.  */
353518334Speter      new = lookup_as_function (XEXP (x, 0), code);
353618334Speter      if (new)
353718334Speter	return fold_rtx (copy_rtx (XEXP (new, 0)), insn);
353818334Speter      break;
353918334Speter
354018334Speter    case MEM:
354118334Speter      /* If we are not actually processing an insn, don't try to find the
354218334Speter	 best address.  Not only don't we care, but we could modify the
354318334Speter	 MEM in an invalid way since we have no insn to validate against.  */
354418334Speter      if (insn != 0)
354590075Sobrien	find_best_addr (insn, &XEXP (x, 0), GET_MODE (x));
354618334Speter
354718334Speter      {
354818334Speter	/* Even if we don't fold in the insn itself,
354918334Speter	   we can safely do so here, in hopes of getting a constant.  */
355018334Speter	rtx addr = fold_rtx (XEXP (x, 0), NULL_RTX);
355118334Speter	rtx base = 0;
355218334Speter	HOST_WIDE_INT offset = 0;
355318334Speter
355418334Speter	if (GET_CODE (addr) == REG
355590075Sobrien	    && REGNO_QTY_VALID_P (REGNO (addr)))
355690075Sobrien	  {
355790075Sobrien	    int addr_q = REG_QTY (REGNO (addr));
355890075Sobrien	    struct qty_table_elem *addr_ent = &qty_table[addr_q];
355918334Speter
356090075Sobrien	    if (GET_MODE (addr) == addr_ent->mode
356190075Sobrien		&& addr_ent->const_rtx != NULL_RTX)
356290075Sobrien	      addr = addr_ent->const_rtx;
356390075Sobrien	  }
356490075Sobrien
356518334Speter	/* If address is constant, split it into a base and integer offset.  */
356618334Speter	if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
356718334Speter	  base = addr;
356818334Speter	else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
356918334Speter		 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
357018334Speter	  {
357118334Speter	    base = XEXP (XEXP (addr, 0), 0);
357218334Speter	    offset = INTVAL (XEXP (XEXP (addr, 0), 1));
357318334Speter	  }
357418334Speter	else if (GET_CODE (addr) == LO_SUM
357518334Speter		 && GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
357618334Speter	  base = XEXP (addr, 1);
357750397Sobrien	else if (GET_CODE (addr) == ADDRESSOF)
357850397Sobrien	  return change_address (x, VOIDmode, addr);
357918334Speter
358018334Speter	/* If this is a constant pool reference, we can fold it into its
358118334Speter	   constant to allow better value tracking.  */
358218334Speter	if (base && GET_CODE (base) == SYMBOL_REF
358318334Speter	    && CONSTANT_POOL_ADDRESS_P (base))
358418334Speter	  {
358518334Speter	    rtx constant = get_pool_constant (base);
358618334Speter	    enum machine_mode const_mode = get_pool_mode (base);
358718334Speter	    rtx new;
358818334Speter
358918334Speter	    if (CONSTANT_P (constant) && GET_CODE (constant) != CONST_INT)
359018334Speter	      constant_pool_entries_cost = COST (constant);
359118334Speter
359218334Speter	    /* If we are loading the full constant, we have an equivalence.  */
359318334Speter	    if (offset == 0 && mode == const_mode)
359418334Speter	      return constant;
359518334Speter
359618334Speter	    /* If this actually isn't a constant (weird!), we can't do
359718334Speter	       anything.  Otherwise, handle the two most common cases:
359818334Speter	       extracting a word from a multi-word constant, and extracting
359918334Speter	       the low-order bits.  Other cases don't seem common enough to
360018334Speter	       worry about.  */
360118334Speter	    if (! CONSTANT_P (constant))
360218334Speter	      return x;
360318334Speter
360418334Speter	    if (GET_MODE_CLASS (mode) == MODE_INT
360518334Speter		&& GET_MODE_SIZE (mode) == UNITS_PER_WORD
360618334Speter		&& offset % UNITS_PER_WORD == 0
360718334Speter		&& (new = operand_subword (constant,
360818334Speter					   offset / UNITS_PER_WORD,
360918334Speter					   0, const_mode)) != 0)
361018334Speter	      return new;
361118334Speter
361218334Speter	    if (((BYTES_BIG_ENDIAN
361318334Speter		  && offset == GET_MODE_SIZE (GET_MODE (constant)) - 1)
361418334Speter		 || (! BYTES_BIG_ENDIAN && offset == 0))
361518334Speter		&& (new = gen_lowpart_if_possible (mode, constant)) != 0)
361618334Speter	      return new;
361718334Speter	  }
361818334Speter
361918334Speter	/* If this is a reference to a label at a known position in a jump
362018334Speter	   table, we also know its value.  */
362118334Speter	if (base && GET_CODE (base) == LABEL_REF)
362218334Speter	  {
362318334Speter	    rtx label = XEXP (base, 0);
362418334Speter	    rtx table_insn = NEXT_INSN (label);
362590075Sobrien
362618334Speter	    if (table_insn && GET_CODE (table_insn) == JUMP_INSN
362718334Speter		&& GET_CODE (PATTERN (table_insn)) == ADDR_VEC)
362818334Speter	      {
362918334Speter		rtx table = PATTERN (table_insn);
363018334Speter
363118334Speter		if (offset >= 0
363218334Speter		    && (offset / GET_MODE_SIZE (GET_MODE (table))
363318334Speter			< XVECLEN (table, 0)))
363418334Speter		  return XVECEXP (table, 0,
363518334Speter				  offset / GET_MODE_SIZE (GET_MODE (table)));
363618334Speter	      }
363718334Speter	    if (table_insn && GET_CODE (table_insn) == JUMP_INSN
363818334Speter		&& GET_CODE (PATTERN (table_insn)) == ADDR_DIFF_VEC)
363918334Speter	      {
364018334Speter		rtx table = PATTERN (table_insn);
364118334Speter
364218334Speter		if (offset >= 0
364318334Speter		    && (offset / GET_MODE_SIZE (GET_MODE (table))
364418334Speter			< XVECLEN (table, 1)))
364518334Speter		  {
364618334Speter		    offset /= GET_MODE_SIZE (GET_MODE (table));
364750397Sobrien		    new = gen_rtx_MINUS (Pmode, XVECEXP (table, 1, offset),
364850397Sobrien					 XEXP (table, 0));
364918334Speter
365018334Speter		    if (GET_MODE (table) != Pmode)
365150397Sobrien		      new = gen_rtx_TRUNCATE (GET_MODE (table), new);
365218334Speter
365390075Sobrien		    /* Indicate this is a constant.  This isn't a
365418334Speter		       valid form of CONST, but it will only be used
365518334Speter		       to fold the next insns and then discarded, so
365650397Sobrien		       it should be safe.
365750397Sobrien
365850397Sobrien		       Note this expression must be explicitly discarded,
365950397Sobrien		       by cse_insn, else it may end up in a REG_EQUAL note
366050397Sobrien		       and "escape" to cause problems elsewhere.  */
366150397Sobrien		    return gen_rtx_CONST (GET_MODE (new), new);
366218334Speter		  }
366318334Speter	      }
366418334Speter	  }
366518334Speter
366618334Speter	return x;
366718334Speter      }
366850397Sobrien
366990075Sobrien#ifdef NO_FUNCTION_CSE
367090075Sobrien    case CALL:
367190075Sobrien      if (CONSTANT_P (XEXP (XEXP (x, 0), 0)))
367290075Sobrien	return x;
367390075Sobrien      break;
367490075Sobrien#endif
367590075Sobrien
367650397Sobrien    case ASM_OPERANDS:
367790075Sobrien      for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
367890075Sobrien	validate_change (insn, &ASM_OPERANDS_INPUT (x, i),
367990075Sobrien			 fold_rtx (ASM_OPERANDS_INPUT (x, i), insn), 0);
368050397Sobrien      break;
368190075Sobrien
368250397Sobrien    default:
368350397Sobrien      break;
368418334Speter    }
368518334Speter
368618334Speter  const_arg0 = 0;
368718334Speter  const_arg1 = 0;
368818334Speter  const_arg2 = 0;
368918334Speter  mode_arg0 = VOIDmode;
369018334Speter
369118334Speter  /* Try folding our operands.
369218334Speter     Then see which ones have constant values known.  */
369318334Speter
369418334Speter  fmt = GET_RTX_FORMAT (code);
369518334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
369618334Speter    if (fmt[i] == 'e')
369718334Speter      {
369818334Speter	rtx arg = XEXP (x, i);
369918334Speter	rtx folded_arg = arg, const_arg = 0;
370018334Speter	enum machine_mode mode_arg = GET_MODE (arg);
370118334Speter	rtx cheap_arg, expensive_arg;
370218334Speter	rtx replacements[2];
370318334Speter	int j;
370418334Speter
370518334Speter	/* Most arguments are cheap, so handle them specially.  */
370618334Speter	switch (GET_CODE (arg))
370718334Speter	  {
370818334Speter	  case REG:
370918334Speter	    /* This is the same as calling equiv_constant; it is duplicated
371018334Speter	       here for speed.  */
371190075Sobrien	    if (REGNO_QTY_VALID_P (REGNO (arg)))
371290075Sobrien	      {
371390075Sobrien		int arg_q = REG_QTY (REGNO (arg));
371490075Sobrien		struct qty_table_elem *arg_ent = &qty_table[arg_q];
371590075Sobrien
371690075Sobrien		if (arg_ent->const_rtx != NULL_RTX
371790075Sobrien		    && GET_CODE (arg_ent->const_rtx) != REG
371890075Sobrien		    && GET_CODE (arg_ent->const_rtx) != PLUS)
371990075Sobrien		  const_arg
372090075Sobrien		    = gen_lowpart_if_possible (GET_MODE (arg),
372190075Sobrien					       arg_ent->const_rtx);
372290075Sobrien	      }
372318334Speter	    break;
372418334Speter
372518334Speter	  case CONST:
372618334Speter	  case CONST_INT:
372718334Speter	  case SYMBOL_REF:
372818334Speter	  case LABEL_REF:
372918334Speter	  case CONST_DOUBLE:
373018334Speter	    const_arg = arg;
373118334Speter	    break;
373218334Speter
373318334Speter#ifdef HAVE_cc0
373418334Speter	  case CC0:
373518334Speter	    folded_arg = prev_insn_cc0;
373618334Speter	    mode_arg = prev_insn_cc0_mode;
373718334Speter	    const_arg = equiv_constant (folded_arg);
373818334Speter	    break;
373918334Speter#endif
374018334Speter
374118334Speter	  default:
374218334Speter	    folded_arg = fold_rtx (arg, insn);
374318334Speter	    const_arg = equiv_constant (folded_arg);
374418334Speter	  }
374518334Speter
374618334Speter	/* For the first three operands, see if the operand
374718334Speter	   is constant or equivalent to a constant.  */
374818334Speter	switch (i)
374918334Speter	  {
375018334Speter	  case 0:
375118334Speter	    folded_arg0 = folded_arg;
375218334Speter	    const_arg0 = const_arg;
375318334Speter	    mode_arg0 = mode_arg;
375418334Speter	    break;
375518334Speter	  case 1:
375618334Speter	    folded_arg1 = folded_arg;
375718334Speter	    const_arg1 = const_arg;
375818334Speter	    break;
375918334Speter	  case 2:
376018334Speter	    const_arg2 = const_arg;
376118334Speter	    break;
376218334Speter	  }
376318334Speter
376418334Speter	/* Pick the least expensive of the folded argument and an
376518334Speter	   equivalent constant argument.  */
376618334Speter	if (const_arg == 0 || const_arg == folded_arg
376790075Sobrien	    || COST_IN (const_arg, code) > COST_IN (folded_arg, code))
376818334Speter	  cheap_arg = folded_arg, expensive_arg = const_arg;
376918334Speter	else
377018334Speter	  cheap_arg = const_arg, expensive_arg = folded_arg;
377118334Speter
377218334Speter	/* Try to replace the operand with the cheapest of the two
377318334Speter	   possibilities.  If it doesn't work and this is either of the first
377418334Speter	   two operands of a commutative operation, try swapping them.
377518334Speter	   If THAT fails, try the more expensive, provided it is cheaper
377618334Speter	   than what is already there.  */
377718334Speter
377818334Speter	if (cheap_arg == XEXP (x, i))
377918334Speter	  continue;
378018334Speter
378118334Speter	if (insn == 0 && ! copied)
378218334Speter	  {
378318334Speter	    x = copy_rtx (x);
378418334Speter	    copied = 1;
378518334Speter	  }
378618334Speter
378790075Sobrien	/* Order the replacements from cheapest to most expensive.  */
378890075Sobrien	replacements[0] = cheap_arg;
378990075Sobrien	replacements[1] = expensive_arg;
379090075Sobrien
379190075Sobrien	for (j = 0; j < 2 && replacements[j];  j++)
379218334Speter	  {
379390075Sobrien	    int old_cost = COST_IN (XEXP (x, i), code);
379490075Sobrien	    int new_cost = COST_IN (replacements[j], code);
379590075Sobrien
379690075Sobrien	    /* Stop if what existed before was cheaper.  Prefer constants
379790075Sobrien	       in the case of a tie.  */
379890075Sobrien	    if (new_cost > old_cost
379990075Sobrien		|| (new_cost == old_cost && CONSTANT_P (XEXP (x, i))))
380090075Sobrien	      break;
380190075Sobrien
380218334Speter	    if (validate_change (insn, &XEXP (x, i), replacements[j], 0))
380318334Speter	      break;
380418334Speter
380590075Sobrien	    if (code == NE || code == EQ || GET_RTX_CLASS (code) == 'c'
380690075Sobrien		|| code == LTGT || code == UNEQ || code == ORDERED
380790075Sobrien		|| code == UNORDERED)
380818334Speter	      {
380918334Speter		validate_change (insn, &XEXP (x, i), XEXP (x, 1 - i), 1);
381018334Speter		validate_change (insn, &XEXP (x, 1 - i), replacements[j], 1);
381118334Speter
381218334Speter		if (apply_change_group ())
381318334Speter		  {
381418334Speter		    /* Swap them back to be invalid so that this loop can
381518334Speter		       continue and flag them to be swapped back later.  */
381618334Speter		    rtx tem;
381718334Speter
381818334Speter		    tem = XEXP (x, 0); XEXP (x, 0) = XEXP (x, 1);
381918334Speter				       XEXP (x, 1) = tem;
382018334Speter		    must_swap = 1;
382118334Speter		    break;
382218334Speter		  }
382318334Speter	      }
382418334Speter	  }
382518334Speter      }
382618334Speter
382750397Sobrien    else
382850397Sobrien      {
382950397Sobrien	if (fmt[i] == 'E')
383050397Sobrien	  /* Don't try to fold inside of a vector of expressions.
383150397Sobrien	     Doing nothing is harmless.  */
383290075Sobrien	  {;}
383350397Sobrien      }
383418334Speter
383518334Speter  /* If a commutative operation, place a constant integer as the second
383618334Speter     operand unless the first operand is also a constant integer.  Otherwise,
383718334Speter     place any constant second unless the first operand is also a constant.  */
383818334Speter
383990075Sobrien  if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c'
384090075Sobrien      || code == LTGT || code == UNEQ || code == ORDERED
384190075Sobrien      || code == UNORDERED)
384218334Speter    {
384318334Speter      if (must_swap || (const_arg0
384418334Speter	  		&& (const_arg1 == 0
384518334Speter	      		    || (GET_CODE (const_arg0) == CONST_INT
384618334Speter			        && GET_CODE (const_arg1) != CONST_INT))))
384718334Speter	{
384890075Sobrien	  rtx tem = XEXP (x, 0);
384918334Speter
385018334Speter	  if (insn == 0 && ! copied)
385118334Speter	    {
385218334Speter	      x = copy_rtx (x);
385318334Speter	      copied = 1;
385418334Speter	    }
385518334Speter
385618334Speter	  validate_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
385718334Speter	  validate_change (insn, &XEXP (x, 1), tem, 1);
385818334Speter	  if (apply_change_group ())
385918334Speter	    {
386018334Speter	      tem = const_arg0, const_arg0 = const_arg1, const_arg1 = tem;
386118334Speter	      tem = folded_arg0, folded_arg0 = folded_arg1, folded_arg1 = tem;
386218334Speter	    }
386318334Speter	}
386418334Speter    }
386518334Speter
386618334Speter  /* If X is an arithmetic operation, see if we can simplify it.  */
386718334Speter
386818334Speter  switch (GET_RTX_CLASS (code))
386918334Speter    {
387018334Speter    case '1':
387118334Speter      {
387218334Speter	int is_const = 0;
387318334Speter
387418334Speter	/* We can't simplify extension ops unless we know the
387518334Speter	   original mode.  */
387618334Speter	if ((code == ZERO_EXTEND || code == SIGN_EXTEND)
387718334Speter	    && mode_arg0 == VOIDmode)
387818334Speter	  break;
387918334Speter
388018334Speter	/* If we had a CONST, strip it off and put it back later if we
388118334Speter	   fold.  */
388218334Speter	if (const_arg0 != 0 && GET_CODE (const_arg0) == CONST)
388318334Speter	  is_const = 1, const_arg0 = XEXP (const_arg0, 0);
388418334Speter
388518334Speter	new = simplify_unary_operation (code, mode,
388618334Speter					const_arg0 ? const_arg0 : folded_arg0,
388718334Speter					mode_arg0);
388818334Speter	if (new != 0 && is_const)
388950397Sobrien	  new = gen_rtx_CONST (mode, new);
389018334Speter      }
389118334Speter      break;
389290075Sobrien
389318334Speter    case '<':
389418334Speter      /* See what items are actually being compared and set FOLDED_ARG[01]
389518334Speter	 to those values and CODE to the actual comparison code.  If any are
389618334Speter	 constant, set CONST_ARG0 and CONST_ARG1 appropriately.  We needn't
389718334Speter	 do anything if both operands are already known to be constant.  */
389818334Speter
389918334Speter      if (const_arg0 == 0 || const_arg1 == 0)
390018334Speter	{
390118334Speter	  struct table_elt *p0, *p1;
390290075Sobrien	  rtx true_rtx = const_true_rtx, false_rtx = const0_rtx;
390318334Speter	  enum machine_mode mode_arg1;
390418334Speter
390518334Speter#ifdef FLOAT_STORE_FLAG_VALUE
390618334Speter	  if (GET_MODE_CLASS (mode) == MODE_FLOAT)
390718334Speter	    {
390890075Sobrien	      true_rtx = (CONST_DOUBLE_FROM_REAL_VALUE
390990075Sobrien		      (FLOAT_STORE_FLAG_VALUE (mode), mode));
391090075Sobrien	      false_rtx = CONST0_RTX (mode);
391118334Speter	    }
391218334Speter#endif
391318334Speter
391418334Speter	  code = find_comparison_args (code, &folded_arg0, &folded_arg1,
391518334Speter				       &mode_arg0, &mode_arg1);
391618334Speter	  const_arg0 = equiv_constant (folded_arg0);
391718334Speter	  const_arg1 = equiv_constant (folded_arg1);
391818334Speter
391918334Speter	  /* If the mode is VOIDmode or a MODE_CC mode, we don't know
392018334Speter	     what kinds of things are being compared, so we can't do
392118334Speter	     anything with this comparison.  */
392218334Speter
392318334Speter	  if (mode_arg0 == VOIDmode || GET_MODE_CLASS (mode_arg0) == MODE_CC)
392418334Speter	    break;
392518334Speter
392650397Sobrien	  /* If we do not now have two constants being compared, see
392750397Sobrien	     if we can nevertheless deduce some things about the
392850397Sobrien	     comparison.  */
392918334Speter	  if (const_arg0 == 0 || const_arg1 == 0)
393018334Speter	    {
393150397Sobrien	      /* Is FOLDED_ARG0 frame-pointer plus a constant?  Or
393250397Sobrien		 non-explicit constant?  These aren't zero, but we
393350397Sobrien		 don't know their sign.  */
393418334Speter	      if (const_arg1 == const0_rtx
393518334Speter		  && (NONZERO_BASE_PLUS_P (folded_arg0)
393618334Speter#if 0  /* Sad to say, on sysvr4, #pragma weak can make a symbol address
393718334Speter	  come out as 0.  */
393818334Speter		      || GET_CODE (folded_arg0) == SYMBOL_REF
393918334Speter#endif
394018334Speter		      || GET_CODE (folded_arg0) == LABEL_REF
394118334Speter		      || GET_CODE (folded_arg0) == CONST))
394218334Speter		{
394318334Speter		  if (code == EQ)
394490075Sobrien		    return false_rtx;
394518334Speter		  else if (code == NE)
394690075Sobrien		    return true_rtx;
394718334Speter		}
394818334Speter
394990075Sobrien	      /* See if the two operands are the same.  */
395018334Speter
395190075Sobrien	      if (folded_arg0 == folded_arg1
395290075Sobrien		  || (GET_CODE (folded_arg0) == REG
395390075Sobrien		      && GET_CODE (folded_arg1) == REG
395490075Sobrien		      && (REG_QTY (REGNO (folded_arg0))
395590075Sobrien			  == REG_QTY (REGNO (folded_arg1))))
395690075Sobrien		  || ((p0 = lookup (folded_arg0,
395790075Sobrien				    (safe_hash (folded_arg0, mode_arg0)
395890075Sobrien				     & HASH_MASK), mode_arg0))
395990075Sobrien		      && (p1 = lookup (folded_arg1,
396090075Sobrien				       (safe_hash (folded_arg1, mode_arg0)
396190075Sobrien					& HASH_MASK), mode_arg0))
396290075Sobrien		      && p0->first_same_value == p1->first_same_value))
396390075Sobrien		{
396490075Sobrien		   /* Sadly two equal NaNs are not equivalent.  */
396590075Sobrien		   if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
396690075Sobrien		       || ! FLOAT_MODE_P (mode_arg0)
396790075Sobrien		       || flag_unsafe_math_optimizations)
396890075Sobrien		      return ((code == EQ || code == LE || code == GE
396990075Sobrien			       || code == LEU || code == GEU || code == UNEQ
397090075Sobrien			       || code == UNLE || code == UNGE || code == ORDERED)
397190075Sobrien			      ? true_rtx : false_rtx);
397290075Sobrien		   /* Take care for the FP compares we can resolve.  */
397390075Sobrien		   if (code == UNEQ || code == UNLE || code == UNGE)
397490075Sobrien		     return true_rtx;
397590075Sobrien		   if (code == LTGT || code == LT || code == GT)
397690075Sobrien		     return false_rtx;
397790075Sobrien		}
397818334Speter
397918334Speter	      /* If FOLDED_ARG0 is a register, see if the comparison we are
398018334Speter		 doing now is either the same as we did before or the reverse
398118334Speter		 (we only check the reverse if not floating-point).  */
398218334Speter	      else if (GET_CODE (folded_arg0) == REG)
398318334Speter		{
398452284Sobrien		  int qty = REG_QTY (REGNO (folded_arg0));
398518334Speter
398690075Sobrien		  if (REGNO_QTY_VALID_P (REGNO (folded_arg0)))
398790075Sobrien		    {
398890075Sobrien		      struct qty_table_elem *ent = &qty_table[qty];
398990075Sobrien
399090075Sobrien		      if ((comparison_dominates_p (ent->comparison_code, code)
399190075Sobrien			   || (! FLOAT_MODE_P (mode_arg0)
399290075Sobrien			       && comparison_dominates_p (ent->comparison_code,
399390075Sobrien						          reverse_condition (code))))
399490075Sobrien			  && (rtx_equal_p (ent->comparison_const, folded_arg1)
399590075Sobrien			      || (const_arg1
399690075Sobrien				  && rtx_equal_p (ent->comparison_const,
399790075Sobrien						  const_arg1))
399890075Sobrien			      || (GET_CODE (folded_arg1) == REG
399990075Sobrien				  && (REG_QTY (REGNO (folded_arg1)) == ent->comparison_qty))))
400090075Sobrien			return (comparison_dominates_p (ent->comparison_code, code)
400190075Sobrien				? true_rtx : false_rtx);
400290075Sobrien		    }
400318334Speter		}
400418334Speter	    }
400518334Speter	}
400618334Speter
400718334Speter      /* If we are comparing against zero, see if the first operand is
400818334Speter	 equivalent to an IOR with a constant.  If so, we may be able to
400918334Speter	 determine the result of this comparison.  */
401018334Speter
401118334Speter      if (const_arg1 == const0_rtx)
401218334Speter	{
401318334Speter	  rtx y = lookup_as_function (folded_arg0, IOR);
401418334Speter	  rtx inner_const;
401518334Speter
401618334Speter	  if (y != 0
401718334Speter	      && (inner_const = equiv_constant (XEXP (y, 1))) != 0
401818334Speter	      && GET_CODE (inner_const) == CONST_INT
401918334Speter	      && INTVAL (inner_const) != 0)
402018334Speter	    {
402118334Speter	      int sign_bitnum = GET_MODE_BITSIZE (mode_arg0) - 1;
402218334Speter	      int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
402318334Speter			      && (INTVAL (inner_const)
402418334Speter				  & ((HOST_WIDE_INT) 1 << sign_bitnum)));
402590075Sobrien	      rtx true_rtx = const_true_rtx, false_rtx = const0_rtx;
402618334Speter
402718334Speter#ifdef FLOAT_STORE_FLAG_VALUE
402818334Speter	      if (GET_MODE_CLASS (mode) == MODE_FLOAT)
402918334Speter		{
403090075Sobrien		  true_rtx = (CONST_DOUBLE_FROM_REAL_VALUE
403190075Sobrien			  (FLOAT_STORE_FLAG_VALUE (mode), mode));
403290075Sobrien		  false_rtx = CONST0_RTX (mode);
403318334Speter		}
403418334Speter#endif
403518334Speter
403618334Speter	      switch (code)
403718334Speter		{
403818334Speter		case EQ:
403990075Sobrien		  return false_rtx;
404018334Speter		case NE:
404190075Sobrien		  return true_rtx;
404218334Speter		case LT:  case LE:
404318334Speter		  if (has_sign)
404490075Sobrien		    return true_rtx;
404518334Speter		  break;
404618334Speter		case GT:  case GE:
404718334Speter		  if (has_sign)
404890075Sobrien		    return false_rtx;
404918334Speter		  break;
405050397Sobrien		default:
405150397Sobrien		  break;
405218334Speter		}
405318334Speter	    }
405418334Speter	}
405518334Speter
405690075Sobrien      new = simplify_relational_operation (code,
405790075Sobrien					   (mode_arg0 != VOIDmode
405890075Sobrien					    ? mode_arg0
405990075Sobrien					    : (GET_MODE (const_arg0
406090075Sobrien							 ? const_arg0
406190075Sobrien							 : folded_arg0)
406290075Sobrien					       != VOIDmode)
406390075Sobrien					    ? GET_MODE (const_arg0
406490075Sobrien							? const_arg0
406590075Sobrien							: folded_arg0)
406690075Sobrien					    : GET_MODE (const_arg1
406790075Sobrien							? const_arg1
406890075Sobrien							: folded_arg1)),
406918334Speter					   const_arg0 ? const_arg0 : folded_arg0,
407018334Speter					   const_arg1 ? const_arg1 : folded_arg1);
407118334Speter#ifdef FLOAT_STORE_FLAG_VALUE
407218334Speter      if (new != 0 && GET_MODE_CLASS (mode) == MODE_FLOAT)
407390075Sobrien	{
407490075Sobrien	  if (new == const0_rtx)
407590075Sobrien	    new = CONST0_RTX (mode);
407690075Sobrien	  else
407790075Sobrien	    new = (CONST_DOUBLE_FROM_REAL_VALUE
407890075Sobrien		   (FLOAT_STORE_FLAG_VALUE (mode), mode));
407990075Sobrien	}
408018334Speter#endif
408118334Speter      break;
408218334Speter
408318334Speter    case '2':
408418334Speter    case 'c':
408518334Speter      switch (code)
408618334Speter	{
408718334Speter	case PLUS:
408818334Speter	  /* If the second operand is a LABEL_REF, see if the first is a MINUS
408918334Speter	     with that LABEL_REF as its second operand.  If so, the result is
409018334Speter	     the first operand of that MINUS.  This handles switches with an
409118334Speter	     ADDR_DIFF_VEC table.  */
409218334Speter	  if (const_arg1 && GET_CODE (const_arg1) == LABEL_REF)
409318334Speter	    {
409418334Speter	      rtx y
409518334Speter		= GET_CODE (folded_arg0) == MINUS ? folded_arg0
409690075Sobrien		: lookup_as_function (folded_arg0, MINUS);
409718334Speter
409818334Speter	      if (y != 0 && GET_CODE (XEXP (y, 1)) == LABEL_REF
409918334Speter		  && XEXP (XEXP (y, 1), 0) == XEXP (const_arg1, 0))
410018334Speter		return XEXP (y, 0);
410118334Speter
410218334Speter	      /* Now try for a CONST of a MINUS like the above.  */
410318334Speter	      if ((y = (GET_CODE (folded_arg0) == CONST ? folded_arg0
410418334Speter			: lookup_as_function (folded_arg0, CONST))) != 0
410518334Speter		  && GET_CODE (XEXP (y, 0)) == MINUS
410618334Speter		  && GET_CODE (XEXP (XEXP (y, 0), 1)) == LABEL_REF
410790075Sobrien		  && XEXP (XEXP (XEXP (y, 0), 1), 0) == XEXP (const_arg1, 0))
410818334Speter		return XEXP (XEXP (y, 0), 0);
410918334Speter	    }
411018334Speter
411118334Speter	  /* Likewise if the operands are in the other order.  */
411218334Speter	  if (const_arg0 && GET_CODE (const_arg0) == LABEL_REF)
411318334Speter	    {
411418334Speter	      rtx y
411518334Speter		= GET_CODE (folded_arg1) == MINUS ? folded_arg1
411690075Sobrien		: lookup_as_function (folded_arg1, MINUS);
411718334Speter
411818334Speter	      if (y != 0 && GET_CODE (XEXP (y, 1)) == LABEL_REF
411918334Speter		  && XEXP (XEXP (y, 1), 0) == XEXP (const_arg0, 0))
412018334Speter		return XEXP (y, 0);
412118334Speter
412218334Speter	      /* Now try for a CONST of a MINUS like the above.  */
412318334Speter	      if ((y = (GET_CODE (folded_arg1) == CONST ? folded_arg1
412418334Speter			: lookup_as_function (folded_arg1, CONST))) != 0
412518334Speter		  && GET_CODE (XEXP (y, 0)) == MINUS
412618334Speter		  && GET_CODE (XEXP (XEXP (y, 0), 1)) == LABEL_REF
412790075Sobrien		  && XEXP (XEXP (XEXP (y, 0), 1), 0) == XEXP (const_arg0, 0))
412818334Speter		return XEXP (XEXP (y, 0), 0);
412918334Speter	    }
413018334Speter
413118334Speter	  /* If second operand is a register equivalent to a negative
413218334Speter	     CONST_INT, see if we can find a register equivalent to the
413318334Speter	     positive constant.  Make a MINUS if so.  Don't do this for
413450397Sobrien	     a non-negative constant since we might then alternate between
413590075Sobrien	     choosing positive and negative constants.  Having the positive
413650397Sobrien	     constant previously-used is the more common case.  Be sure
413750397Sobrien	     the resulting constant is non-negative; if const_arg1 were
413850397Sobrien	     the smallest negative number this would overflow: depending
413950397Sobrien	     on the mode, this would either just be the same value (and
414050397Sobrien	     hence not save anything) or be incorrect.  */
414150397Sobrien	  if (const_arg1 != 0 && GET_CODE (const_arg1) == CONST_INT
414250397Sobrien	      && INTVAL (const_arg1) < 0
414352750Sobrien	      /* This used to test
414452750Sobrien
414590075Sobrien	         -INTVAL (const_arg1) >= 0
414652750Sobrien
414752750Sobrien		 But The Sun V5.0 compilers mis-compiled that test.  So
414852750Sobrien		 instead we test for the problematic value in a more direct
414952750Sobrien		 manner and hope the Sun compilers get it correct.  */
415052750Sobrien	      && INTVAL (const_arg1) !=
415152750Sobrien	        ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1))
415250397Sobrien	      && GET_CODE (folded_arg1) == REG)
415318334Speter	    {
415490075Sobrien	      rtx new_const = GEN_INT (-INTVAL (const_arg1));
415518334Speter	      struct table_elt *p
415690075Sobrien		= lookup (new_const, safe_hash (new_const, mode) & HASH_MASK,
415718334Speter			  mode);
415818334Speter
415918334Speter	      if (p)
416018334Speter		for (p = p->first_same_value; p; p = p->next_same_value)
416118334Speter		  if (GET_CODE (p->exp) == REG)
416290075Sobrien		    return simplify_gen_binary (MINUS, mode, folded_arg0,
416390075Sobrien						canon_reg (p->exp, NULL_RTX));
416418334Speter	    }
416518334Speter	  goto from_plus;
416618334Speter
416718334Speter	case MINUS:
416818334Speter	  /* If we have (MINUS Y C), see if Y is known to be (PLUS Z C2).
416918334Speter	     If so, produce (PLUS Z C2-C).  */
417018334Speter	  if (const_arg1 != 0 && GET_CODE (const_arg1) == CONST_INT)
417118334Speter	    {
417218334Speter	      rtx y = lookup_as_function (XEXP (x, 0), PLUS);
417318334Speter	      if (y && GET_CODE (XEXP (y, 1)) == CONST_INT)
417418334Speter		return fold_rtx (plus_constant (copy_rtx (y),
417518334Speter						-INTVAL (const_arg1)),
417618334Speter				 NULL_RTX);
417718334Speter	    }
417818334Speter
417990075Sobrien	  /* Fall through.  */
418018334Speter
418118334Speter	from_plus:
418218334Speter	case SMIN:    case SMAX:      case UMIN:    case UMAX:
418318334Speter	case IOR:     case AND:       case XOR:
418418334Speter	case MULT:    case DIV:       case UDIV:
418518334Speter	case ASHIFT:  case LSHIFTRT:  case ASHIFTRT:
418618334Speter	  /* If we have (<op> <reg> <const_int>) for an associative OP and REG
418718334Speter	     is known to be of similar form, we may be able to replace the
418818334Speter	     operation with a combined operation.  This may eliminate the
418918334Speter	     intermediate operation if every use is simplified in this way.
419018334Speter	     Note that the similar optimization done by combine.c only works
419118334Speter	     if the intermediate operation's result has only one reference.  */
419218334Speter
419318334Speter	  if (GET_CODE (folded_arg0) == REG
419418334Speter	      && const_arg1 && GET_CODE (const_arg1) == CONST_INT)
419518334Speter	    {
419618334Speter	      int is_shift
419718334Speter		= (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT);
419818334Speter	      rtx y = lookup_as_function (folded_arg0, code);
419918334Speter	      rtx inner_const;
420018334Speter	      enum rtx_code associate_code;
420118334Speter	      rtx new_const;
420218334Speter
420318334Speter	      if (y == 0
420418334Speter		  || 0 == (inner_const
420518334Speter			   = equiv_constant (fold_rtx (XEXP (y, 1), 0)))
420618334Speter		  || GET_CODE (inner_const) != CONST_INT
420718334Speter		  /* If we have compiled a statement like
420818334Speter		     "if (x == (x & mask1))", and now are looking at
420918334Speter		     "x & mask2", we will have a case where the first operand
421018334Speter		     of Y is the same as our first operand.  Unless we detect
421118334Speter		     this case, an infinite loop will result.  */
421218334Speter		  || XEXP (y, 0) == folded_arg0)
421318334Speter		break;
421418334Speter
421518334Speter	      /* Don't associate these operations if they are a PLUS with the
421618334Speter		 same constant and it is a power of two.  These might be doable
421718334Speter		 with a pre- or post-increment.  Similarly for two subtracts of
421818334Speter		 identical powers of two with post decrement.  */
421918334Speter
422018334Speter	      if (code == PLUS && INTVAL (const_arg1) == INTVAL (inner_const)
422152284Sobrien		  && ((HAVE_PRE_INCREMENT
422252284Sobrien			  && exact_log2 (INTVAL (const_arg1)) >= 0)
422352284Sobrien		      || (HAVE_POST_INCREMENT
422452284Sobrien			  && exact_log2 (INTVAL (const_arg1)) >= 0)
422552284Sobrien		      || (HAVE_PRE_DECREMENT
422652284Sobrien			  && exact_log2 (- INTVAL (const_arg1)) >= 0)
422752284Sobrien		      || (HAVE_POST_DECREMENT
422852284Sobrien			  && exact_log2 (- INTVAL (const_arg1)) >= 0)))
422918334Speter		break;
423018334Speter
423118334Speter	      /* Compute the code used to compose the constants.  For example,
423218334Speter		 A/C1/C2 is A/(C1 * C2), so if CODE == DIV, we want MULT.  */
423318334Speter
423418334Speter	      associate_code
423518334Speter		= (code == MULT || code == DIV || code == UDIV ? MULT
423618334Speter		   : is_shift || code == PLUS || code == MINUS ? PLUS : code);
423718334Speter
423818334Speter	      new_const = simplify_binary_operation (associate_code, mode,
423918334Speter						     const_arg1, inner_const);
424018334Speter
424118334Speter	      if (new_const == 0)
424218334Speter		break;
424318334Speter
424418334Speter	      /* If we are associating shift operations, don't let this
424518334Speter		 produce a shift of the size of the object or larger.
424618334Speter		 This could occur when we follow a sign-extend by a right
424718334Speter		 shift on a machine that does a sign-extend as a pair
424818334Speter		 of shifts.  */
424918334Speter
425018334Speter	      if (is_shift && GET_CODE (new_const) == CONST_INT
425118334Speter		  && INTVAL (new_const) >= GET_MODE_BITSIZE (mode))
425218334Speter		{
425318334Speter		  /* As an exception, we can turn an ASHIFTRT of this
425418334Speter		     form into a shift of the number of bits - 1.  */
425518334Speter		  if (code == ASHIFTRT)
425618334Speter		    new_const = GEN_INT (GET_MODE_BITSIZE (mode) - 1);
425718334Speter		  else
425818334Speter		    break;
425918334Speter		}
426018334Speter
426118334Speter	      y = copy_rtx (XEXP (y, 0));
426218334Speter
426318334Speter	      /* If Y contains our first operand (the most common way this
426418334Speter		 can happen is if Y is a MEM), we would do into an infinite
426518334Speter		 loop if we tried to fold it.  So don't in that case.  */
426618334Speter
426718334Speter	      if (! reg_mentioned_p (folded_arg0, y))
426818334Speter		y = fold_rtx (y, insn);
426918334Speter
427090075Sobrien	      return simplify_gen_binary (code, mode, y, new_const);
427118334Speter	    }
427250397Sobrien	  break;
427350397Sobrien
427450397Sobrien	default:
427550397Sobrien	  break;
427618334Speter	}
427718334Speter
427818334Speter      new = simplify_binary_operation (code, mode,
427918334Speter				       const_arg0 ? const_arg0 : folded_arg0,
428018334Speter				       const_arg1 ? const_arg1 : folded_arg1);
428118334Speter      break;
428218334Speter
428318334Speter    case 'o':
428418334Speter      /* (lo_sum (high X) X) is simply X.  */
428518334Speter      if (code == LO_SUM && const_arg0 != 0
428618334Speter	  && GET_CODE (const_arg0) == HIGH
428718334Speter	  && rtx_equal_p (XEXP (const_arg0, 0), const_arg1))
428818334Speter	return const_arg1;
428918334Speter      break;
429018334Speter
429118334Speter    case '3':
429218334Speter    case 'b':
429318334Speter      new = simplify_ternary_operation (code, mode, mode_arg0,
429418334Speter					const_arg0 ? const_arg0 : folded_arg0,
429518334Speter					const_arg1 ? const_arg1 : folded_arg1,
429618334Speter					const_arg2 ? const_arg2 : XEXP (x, 2));
429718334Speter      break;
429850397Sobrien
429950397Sobrien    case 'x':
430090075Sobrien      /* Always eliminate CONSTANT_P_RTX at this stage.  */
430150397Sobrien      if (code == CONSTANT_P_RTX)
430250397Sobrien	return (const_arg0 ? const1_rtx : const0_rtx);
430350397Sobrien      break;
430418334Speter    }
430518334Speter
430618334Speter  return new ? new : x;
430718334Speter}
430818334Speter
430918334Speter/* Return a constant value currently equivalent to X.
431018334Speter   Return 0 if we don't know one.  */
431118334Speter
431218334Speterstatic rtx
431318334Speterequiv_constant (x)
431418334Speter     rtx x;
431518334Speter{
431618334Speter  if (GET_CODE (x) == REG
431790075Sobrien      && REGNO_QTY_VALID_P (REGNO (x)))
431890075Sobrien    {
431990075Sobrien      int x_q = REG_QTY (REGNO (x));
432090075Sobrien      struct qty_table_elem *x_ent = &qty_table[x_q];
432118334Speter
432290075Sobrien      if (x_ent->const_rtx)
432390075Sobrien	x = gen_lowpart_if_possible (GET_MODE (x), x_ent->const_rtx);
432490075Sobrien    }
432590075Sobrien
432652284Sobrien  if (x == 0 || CONSTANT_P (x))
432718334Speter    return x;
432818334Speter
432918334Speter  /* If X is a MEM, try to fold it outside the context of any insn to see if
433018334Speter     it might be equivalent to a constant.  That handles the case where it
433118334Speter     is a constant-pool reference.  Then try to look it up in the hash table
433218334Speter     in case it is something whose value we have seen before.  */
433318334Speter
433418334Speter  if (GET_CODE (x) == MEM)
433518334Speter    {
433618334Speter      struct table_elt *elt;
433718334Speter
433818334Speter      x = fold_rtx (x, NULL_RTX);
433918334Speter      if (CONSTANT_P (x))
434018334Speter	return x;
434118334Speter
434290075Sobrien      elt = lookup (x, safe_hash (x, GET_MODE (x)) & HASH_MASK, GET_MODE (x));
434318334Speter      if (elt == 0)
434418334Speter	return 0;
434518334Speter
434618334Speter      for (elt = elt->first_same_value; elt; elt = elt->next_same_value)
434718334Speter	if (elt->is_const && CONSTANT_P (elt->exp))
434818334Speter	  return elt->exp;
434918334Speter    }
435018334Speter
435118334Speter  return 0;
435218334Speter}
435318334Speter
435418334Speter/* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a fixed-point
435518334Speter   number, return an rtx (MEM, SUBREG, or CONST_INT) that refers to the
435618334Speter   least-significant part of X.
435790075Sobrien   MODE specifies how big a part of X to return.
435818334Speter
435918334Speter   If the requested operation cannot be done, 0 is returned.
436018334Speter
436118334Speter   This is similar to gen_lowpart in emit-rtl.c.  */
436218334Speter
436318334Speterrtx
436418334Spetergen_lowpart_if_possible (mode, x)
436518334Speter     enum machine_mode mode;
436690075Sobrien     rtx x;
436718334Speter{
436818334Speter  rtx result = gen_lowpart_common (mode, x);
436918334Speter
437018334Speter  if (result)
437118334Speter    return result;
437218334Speter  else if (GET_CODE (x) == MEM)
437318334Speter    {
437418334Speter      /* This is the only other case we handle.  */
437590075Sobrien      int offset = 0;
437618334Speter      rtx new;
437718334Speter
437818334Speter      if (WORDS_BIG_ENDIAN)
437918334Speter	offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
438018334Speter		  - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
438118334Speter      if (BYTES_BIG_ENDIAN)
438218334Speter	/* Adjust the address so that the address-after-the-data is
438318334Speter	   unchanged.  */
438418334Speter	offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
438518334Speter		   - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
438690075Sobrien
438790075Sobrien      new = adjust_address_nv (x, mode, offset);
438818334Speter      if (! memory_address_p (mode, XEXP (new, 0)))
438918334Speter	return 0;
439090075Sobrien
439118334Speter      return new;
439218334Speter    }
439318334Speter  else
439418334Speter    return 0;
439518334Speter}
439618334Speter
439718334Speter/* Given INSN, a jump insn, TAKEN indicates if we are following the "taken"
439818334Speter   branch.  It will be zero if not.
439918334Speter
440018334Speter   In certain cases, this can cause us to add an equivalence.  For example,
440190075Sobrien   if we are following the taken case of
440218334Speter   	if (i == 2)
440318334Speter   we can add the fact that `i' and '2' are now equivalent.
440418334Speter
440518334Speter   In any case, we can record that this comparison was passed.  If the same
440618334Speter   comparison is seen later, we will know its value.  */
440718334Speter
440818334Speterstatic void
440918334Speterrecord_jump_equiv (insn, taken)
441018334Speter     rtx insn;
441118334Speter     int taken;
441218334Speter{
441318334Speter  int cond_known_true;
441418334Speter  rtx op0, op1;
441590075Sobrien  rtx set;
441618334Speter  enum machine_mode mode, mode0, mode1;
441718334Speter  int reversed_nonequality = 0;
441818334Speter  enum rtx_code code;
441918334Speter
442018334Speter  /* Ensure this is the right kind of insn.  */
442190075Sobrien  if (! any_condjump_p (insn))
442218334Speter    return;
442390075Sobrien  set = pc_set (insn);
442418334Speter
442518334Speter  /* See if this jump condition is known true or false.  */
442618334Speter  if (taken)
442790075Sobrien    cond_known_true = (XEXP (SET_SRC (set), 2) == pc_rtx);
442818334Speter  else
442990075Sobrien    cond_known_true = (XEXP (SET_SRC (set), 1) == pc_rtx);
443018334Speter
443118334Speter  /* Get the type of comparison being done and the operands being compared.
443218334Speter     If we had to reverse a non-equality condition, record that fact so we
443318334Speter     know that it isn't valid for floating-point.  */
443490075Sobrien  code = GET_CODE (XEXP (SET_SRC (set), 0));
443590075Sobrien  op0 = fold_rtx (XEXP (XEXP (SET_SRC (set), 0), 0), insn);
443690075Sobrien  op1 = fold_rtx (XEXP (XEXP (SET_SRC (set), 0), 1), insn);
443718334Speter
443818334Speter  code = find_comparison_args (code, &op0, &op1, &mode0, &mode1);
443918334Speter  if (! cond_known_true)
444018334Speter    {
444190075Sobrien      code = reversed_comparison_code_parts (code, op0, op1, insn);
444290075Sobrien
444390075Sobrien      /* Don't remember if we can't find the inverse.  */
444490075Sobrien      if (code == UNKNOWN)
444590075Sobrien	return;
444618334Speter    }
444718334Speter
444818334Speter  /* The mode is the mode of the non-constant.  */
444918334Speter  mode = mode0;
445018334Speter  if (mode1 != VOIDmode)
445118334Speter    mode = mode1;
445218334Speter
445318334Speter  record_jump_cond (code, mode, op0, op1, reversed_nonequality);
445418334Speter}
445518334Speter
445618334Speter/* We know that comparison CODE applied to OP0 and OP1 in MODE is true.
445718334Speter   REVERSED_NONEQUALITY is nonzero if CODE had to be swapped.
445818334Speter   Make any useful entries we can with that information.  Called from
445918334Speter   above function and called recursively.  */
446018334Speter
446118334Speterstatic void
446218334Speterrecord_jump_cond (code, mode, op0, op1, reversed_nonequality)
446318334Speter     enum rtx_code code;
446418334Speter     enum machine_mode mode;
446518334Speter     rtx op0, op1;
446618334Speter     int reversed_nonequality;
446718334Speter{
446818334Speter  unsigned op0_hash, op1_hash;
446990075Sobrien  int op0_in_memory, op1_in_memory;
447018334Speter  struct table_elt *op0_elt, *op1_elt;
447118334Speter
447218334Speter  /* If OP0 and OP1 are known equal, and either is a paradoxical SUBREG,
447318334Speter     we know that they are also equal in the smaller mode (this is also
447418334Speter     true for all smaller modes whether or not there is a SUBREG, but
447550397Sobrien     is not worth testing for with no SUBREG).  */
447618334Speter
447718334Speter  /* Note that GET_MODE (op0) may not equal MODE.  */
447818334Speter  if (code == EQ && GET_CODE (op0) == SUBREG
447918334Speter      && (GET_MODE_SIZE (GET_MODE (op0))
448018334Speter	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))
448118334Speter    {
448218334Speter      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
448318334Speter      rtx tem = gen_lowpart_if_possible (inner_mode, op1);
448418334Speter
448518334Speter      record_jump_cond (code, mode, SUBREG_REG (op0),
448650397Sobrien			tem ? tem : gen_rtx_SUBREG (inner_mode, op1, 0),
448718334Speter			reversed_nonequality);
448818334Speter    }
448918334Speter
449018334Speter  if (code == EQ && GET_CODE (op1) == SUBREG
449118334Speter      && (GET_MODE_SIZE (GET_MODE (op1))
449218334Speter	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1)))))
449318334Speter    {
449418334Speter      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op1));
449518334Speter      rtx tem = gen_lowpart_if_possible (inner_mode, op0);
449618334Speter
449718334Speter      record_jump_cond (code, mode, SUBREG_REG (op1),
449850397Sobrien			tem ? tem : gen_rtx_SUBREG (inner_mode, op0, 0),
449918334Speter			reversed_nonequality);
450018334Speter    }
450118334Speter
450290075Sobrien  /* Similarly, if this is an NE comparison, and either is a SUBREG
450318334Speter     making a smaller mode, we know the whole thing is also NE.  */
450418334Speter
450518334Speter  /* Note that GET_MODE (op0) may not equal MODE;
450618334Speter     if we test MODE instead, we can get an infinite recursion
450718334Speter     alternating between two modes each wider than MODE.  */
450818334Speter
450918334Speter  if (code == NE && GET_CODE (op0) == SUBREG
451018334Speter      && subreg_lowpart_p (op0)
451118334Speter      && (GET_MODE_SIZE (GET_MODE (op0))
451218334Speter	  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))
451318334Speter    {
451418334Speter      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
451518334Speter      rtx tem = gen_lowpart_if_possible (inner_mode, op1);
451618334Speter
451718334Speter      record_jump_cond (code, mode, SUBREG_REG (op0),
451850397Sobrien			tem ? tem : gen_rtx_SUBREG (inner_mode, op1, 0),
451918334Speter			reversed_nonequality);
452018334Speter    }
452118334Speter
452218334Speter  if (code == NE && GET_CODE (op1) == SUBREG
452318334Speter      && subreg_lowpart_p (op1)
452418334Speter      && (GET_MODE_SIZE (GET_MODE (op1))
452518334Speter	  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1)))))
452618334Speter    {
452718334Speter      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op1));
452818334Speter      rtx tem = gen_lowpart_if_possible (inner_mode, op0);
452918334Speter
453018334Speter      record_jump_cond (code, mode, SUBREG_REG (op1),
453150397Sobrien			tem ? tem : gen_rtx_SUBREG (inner_mode, op0, 0),
453218334Speter			reversed_nonequality);
453318334Speter    }
453418334Speter
453518334Speter  /* Hash both operands.  */
453618334Speter
453718334Speter  do_not_record = 0;
453818334Speter  hash_arg_in_memory = 0;
453918334Speter  op0_hash = HASH (op0, mode);
454018334Speter  op0_in_memory = hash_arg_in_memory;
454118334Speter
454218334Speter  if (do_not_record)
454318334Speter    return;
454418334Speter
454518334Speter  do_not_record = 0;
454618334Speter  hash_arg_in_memory = 0;
454718334Speter  op1_hash = HASH (op1, mode);
454818334Speter  op1_in_memory = hash_arg_in_memory;
454990075Sobrien
455018334Speter  if (do_not_record)
455118334Speter    return;
455218334Speter
455318334Speter  /* Look up both operands.  */
455418334Speter  op0_elt = lookup (op0, op0_hash, mode);
455518334Speter  op1_elt = lookup (op1, op1_hash, mode);
455618334Speter
455718334Speter  /* If both operands are already equivalent or if they are not in the
455818334Speter     table but are identical, do nothing.  */
455918334Speter  if ((op0_elt != 0 && op1_elt != 0
456018334Speter       && op0_elt->first_same_value == op1_elt->first_same_value)
456118334Speter      || op0 == op1 || rtx_equal_p (op0, op1))
456218334Speter    return;
456318334Speter
456418334Speter  /* If we aren't setting two things equal all we can do is save this
456518334Speter     comparison.   Similarly if this is floating-point.  In the latter
456618334Speter     case, OP1 might be zero and both -0.0 and 0.0 are equal to it.
456718334Speter     If we record the equality, we might inadvertently delete code
456818334Speter     whose intent was to change -0 to +0.  */
456918334Speter
457018334Speter  if (code != EQ || FLOAT_MODE_P (GET_MODE (op0)))
457118334Speter    {
457290075Sobrien      struct qty_table_elem *ent;
457390075Sobrien      int qty;
457490075Sobrien
457518334Speter      /* If we reversed a floating-point comparison, if OP0 is not a
457618334Speter	 register, or if OP1 is neither a register or constant, we can't
457718334Speter	 do anything.  */
457818334Speter
457918334Speter      if (GET_CODE (op1) != REG)
458018334Speter	op1 = equiv_constant (op1);
458118334Speter
458218334Speter      if ((reversed_nonequality && FLOAT_MODE_P (mode))
458318334Speter	  || GET_CODE (op0) != REG || op1 == 0)
458418334Speter	return;
458518334Speter
458618334Speter      /* Put OP0 in the hash table if it isn't already.  This gives it a
458718334Speter	 new quantity number.  */
458818334Speter      if (op0_elt == 0)
458918334Speter	{
459090075Sobrien	  if (insert_regs (op0, NULL, 0))
459118334Speter	    {
459218334Speter	      rehash_using_reg (op0);
459318334Speter	      op0_hash = HASH (op0, mode);
459418334Speter
459518334Speter	      /* If OP0 is contained in OP1, this changes its hash code
459618334Speter		 as well.  Faster to rehash than to check, except
459718334Speter		 for the simple case of a constant.  */
459818334Speter	      if (! CONSTANT_P (op1))
459918334Speter		op1_hash = HASH (op1,mode);
460018334Speter	    }
460118334Speter
460290075Sobrien	  op0_elt = insert (op0, NULL, op0_hash, mode);
460318334Speter	  op0_elt->in_memory = op0_in_memory;
460418334Speter	}
460518334Speter
460690075Sobrien      qty = REG_QTY (REGNO (op0));
460790075Sobrien      ent = &qty_table[qty];
460890075Sobrien
460990075Sobrien      ent->comparison_code = code;
461018334Speter      if (GET_CODE (op1) == REG)
461118334Speter	{
461218334Speter	  /* Look it up again--in case op0 and op1 are the same.  */
461318334Speter	  op1_elt = lookup (op1, op1_hash, mode);
461418334Speter
461518334Speter	  /* Put OP1 in the hash table so it gets a new quantity number.  */
461618334Speter	  if (op1_elt == 0)
461718334Speter	    {
461890075Sobrien	      if (insert_regs (op1, NULL, 0))
461918334Speter		{
462018334Speter		  rehash_using_reg (op1);
462118334Speter		  op1_hash = HASH (op1, mode);
462218334Speter		}
462318334Speter
462490075Sobrien	      op1_elt = insert (op1, NULL, op1_hash, mode);
462518334Speter	      op1_elt->in_memory = op1_in_memory;
462618334Speter	    }
462718334Speter
462890075Sobrien	  ent->comparison_const = NULL_RTX;
462990075Sobrien	  ent->comparison_qty = REG_QTY (REGNO (op1));
463018334Speter	}
463118334Speter      else
463218334Speter	{
463390075Sobrien	  ent->comparison_const = op1;
463490075Sobrien	  ent->comparison_qty = -1;
463518334Speter	}
463618334Speter
463718334Speter      return;
463818334Speter    }
463918334Speter
464018334Speter  /* If either side is still missing an equivalence, make it now,
464118334Speter     then merge the equivalences.  */
464218334Speter
464318334Speter  if (op0_elt == 0)
464418334Speter    {
464590075Sobrien      if (insert_regs (op0, NULL, 0))
464618334Speter	{
464718334Speter	  rehash_using_reg (op0);
464818334Speter	  op0_hash = HASH (op0, mode);
464918334Speter	}
465018334Speter
465190075Sobrien      op0_elt = insert (op0, NULL, op0_hash, mode);
465218334Speter      op0_elt->in_memory = op0_in_memory;
465318334Speter    }
465418334Speter
465518334Speter  if (op1_elt == 0)
465618334Speter    {
465790075Sobrien      if (insert_regs (op1, NULL, 0))
465818334Speter	{
465918334Speter	  rehash_using_reg (op1);
466018334Speter	  op1_hash = HASH (op1, mode);
466118334Speter	}
466218334Speter
466390075Sobrien      op1_elt = insert (op1, NULL, op1_hash, mode);
466418334Speter      op1_elt->in_memory = op1_in_memory;
466518334Speter    }
466618334Speter
466718334Speter  merge_equiv_classes (op0_elt, op1_elt);
466818334Speter  last_jump_equiv_class = op0_elt;
466918334Speter}
467018334Speter
467118334Speter/* CSE processing for one instruction.
467218334Speter   First simplify sources and addresses of all assignments
467318334Speter   in the instruction, using previously-computed equivalents values.
467418334Speter   Then install the new sources and destinations in the table
467590075Sobrien   of available values.
467618334Speter
467750397Sobrien   If LIBCALL_INSN is nonzero, don't record any equivalence made in
467850397Sobrien   the insn.  It means that INSN is inside libcall block.  In this
467990075Sobrien   case LIBCALL_INSN is the corresponding insn with REG_LIBCALL.  */
468018334Speter
468118334Speter/* Data on one SET contained in the instruction.  */
468218334Speter
468318334Speterstruct set
468418334Speter{
468518334Speter  /* The SET rtx itself.  */
468618334Speter  rtx rtl;
468718334Speter  /* The SET_SRC of the rtx (the original value, if it is changing).  */
468818334Speter  rtx src;
468918334Speter  /* The hash-table element for the SET_SRC of the SET.  */
469018334Speter  struct table_elt *src_elt;
469118334Speter  /* Hash value for the SET_SRC.  */
469218334Speter  unsigned src_hash;
469318334Speter  /* Hash value for the SET_DEST.  */
469418334Speter  unsigned dest_hash;
469518334Speter  /* The SET_DEST, with SUBREG, etc., stripped.  */
469618334Speter  rtx inner_dest;
469790075Sobrien  /* Nonzero if the SET_SRC is in memory.  */
469818334Speter  char src_in_memory;
469918334Speter  /* Nonzero if the SET_SRC contains something
470018334Speter     whose value cannot be predicted and understood.  */
470118334Speter  char src_volatile;
470218334Speter  /* Original machine mode, in case it becomes a CONST_INT.  */
470318334Speter  enum machine_mode mode;
470418334Speter  /* A constant equivalent for SET_SRC, if any.  */
470518334Speter  rtx src_const;
470690075Sobrien  /* Original SET_SRC value used for libcall notes.  */
470790075Sobrien  rtx orig_src;
470818334Speter  /* Hash value of constant equivalent for SET_SRC.  */
470918334Speter  unsigned src_const_hash;
471018334Speter  /* Table entry for constant equivalent for SET_SRC, if any.  */
471118334Speter  struct table_elt *src_const_elt;
471218334Speter};
471318334Speter
471418334Speterstatic void
471550397Sobriencse_insn (insn, libcall_insn)
471618334Speter     rtx insn;
471750397Sobrien     rtx libcall_insn;
471818334Speter{
471990075Sobrien  rtx x = PATTERN (insn);
472090075Sobrien  int i;
472118334Speter  rtx tem;
472290075Sobrien  int n_sets = 0;
472318334Speter
472450397Sobrien#ifdef HAVE_cc0
472518334Speter  /* Records what this insn does to set CC0.  */
472618334Speter  rtx this_insn_cc0 = 0;
472750397Sobrien  enum machine_mode this_insn_cc0_mode = VOIDmode;
472850397Sobrien#endif
472918334Speter
473018334Speter  rtx src_eqv = 0;
473118334Speter  struct table_elt *src_eqv_elt = 0;
473290075Sobrien  int src_eqv_volatile = 0;
473390075Sobrien  int src_eqv_in_memory = 0;
473490075Sobrien  unsigned src_eqv_hash = 0;
473518334Speter
473690075Sobrien  struct set *sets = (struct set *) 0;
473718334Speter
473818334Speter  this_insn = insn;
473918334Speter
474018334Speter  /* Find all the SETs and CLOBBERs in this instruction.
474118334Speter     Record all the SETs in the array `set' and count them.
474218334Speter     Also determine whether there is a CLOBBER that invalidates
474318334Speter     all memory references, or all references at varying addresses.  */
474418334Speter
474518334Speter  if (GET_CODE (insn) == CALL_INSN)
474618334Speter    {
474718334Speter      for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
474890075Sobrien	{
474990075Sobrien	  if (GET_CODE (XEXP (tem, 0)) == CLOBBER)
475090075Sobrien	    invalidate (SET_DEST (XEXP (tem, 0)), VOIDmode);
475190075Sobrien	  XEXP (tem, 0) = canon_reg (XEXP (tem, 0), insn);
475290075Sobrien	}
475318334Speter    }
475418334Speter
475518334Speter  if (GET_CODE (x) == SET)
475618334Speter    {
475718334Speter      sets = (struct set *) alloca (sizeof (struct set));
475818334Speter      sets[0].rtl = x;
475918334Speter
476018334Speter      /* Ignore SETs that are unconditional jumps.
476118334Speter	 They never need cse processing, so this does not hurt.
476218334Speter	 The reason is not efficiency but rather
476318334Speter	 so that we can test at the end for instructions
476418334Speter	 that have been simplified to unconditional jumps
476518334Speter	 and not be misled by unchanged instructions
476618334Speter	 that were unconditional jumps to begin with.  */
476718334Speter      if (SET_DEST (x) == pc_rtx
476818334Speter	  && GET_CODE (SET_SRC (x)) == LABEL_REF)
476918334Speter	;
477018334Speter
477118334Speter      /* Don't count call-insns, (set (reg 0) (call ...)), as a set.
477218334Speter	 The hard function value register is used only once, to copy to
477318334Speter	 someplace else, so it isn't worth cse'ing (and on 80386 is unsafe)!
477418334Speter	 Ensure we invalidate the destination register.  On the 80386 no
477518334Speter	 other code would invalidate it since it is a fixed_reg.
477650397Sobrien	 We need not check the return of apply_change_group; see canon_reg.  */
477718334Speter
477818334Speter      else if (GET_CODE (SET_SRC (x)) == CALL)
477918334Speter	{
478018334Speter	  canon_reg (SET_SRC (x), insn);
478118334Speter	  apply_change_group ();
478218334Speter	  fold_rtx (SET_SRC (x), insn);
478318334Speter	  invalidate (SET_DEST (x), VOIDmode);
478418334Speter	}
478518334Speter      else
478618334Speter	n_sets = 1;
478718334Speter    }
478818334Speter  else if (GET_CODE (x) == PARALLEL)
478918334Speter    {
479090075Sobrien      int lim = XVECLEN (x, 0);
479118334Speter
479218334Speter      sets = (struct set *) alloca (lim * sizeof (struct set));
479318334Speter
479418334Speter      /* Find all regs explicitly clobbered in this insn,
479518334Speter	 and ensure they are not replaced with any other regs
479618334Speter	 elsewhere in this insn.
479718334Speter	 When a reg that is clobbered is also used for input,
479818334Speter	 we should presume that that is for a reason,
479918334Speter	 and we should not substitute some other register
480018334Speter	 which is not supposed to be clobbered.
480118334Speter	 Therefore, this loop cannot be merged into the one below
480218334Speter	 because a CALL may precede a CLOBBER and refer to the
480318334Speter	 value clobbered.  We must not let a canonicalization do
480418334Speter	 anything in that case.  */
480518334Speter      for (i = 0; i < lim; i++)
480618334Speter	{
480790075Sobrien	  rtx y = XVECEXP (x, 0, i);
480818334Speter	  if (GET_CODE (y) == CLOBBER)
480918334Speter	    {
481018334Speter	      rtx clobbered = XEXP (y, 0);
481118334Speter
481218334Speter	      if (GET_CODE (clobbered) == REG
481318334Speter		  || GET_CODE (clobbered) == SUBREG)
481418334Speter		invalidate (clobbered, VOIDmode);
481518334Speter	      else if (GET_CODE (clobbered) == STRICT_LOW_PART
481618334Speter		       || GET_CODE (clobbered) == ZERO_EXTRACT)
481718334Speter		invalidate (XEXP (clobbered, 0), GET_MODE (clobbered));
481818334Speter	    }
481918334Speter	}
482090075Sobrien
482118334Speter      for (i = 0; i < lim; i++)
482218334Speter	{
482390075Sobrien	  rtx y = XVECEXP (x, 0, i);
482418334Speter	  if (GET_CODE (y) == SET)
482518334Speter	    {
482618334Speter	      /* As above, we ignore unconditional jumps and call-insns and
482718334Speter		 ignore the result of apply_change_group.  */
482818334Speter	      if (GET_CODE (SET_SRC (y)) == CALL)
482918334Speter		{
483018334Speter		  canon_reg (SET_SRC (y), insn);
483118334Speter		  apply_change_group ();
483218334Speter		  fold_rtx (SET_SRC (y), insn);
483318334Speter		  invalidate (SET_DEST (y), VOIDmode);
483418334Speter		}
483518334Speter	      else if (SET_DEST (y) == pc_rtx
483618334Speter		       && GET_CODE (SET_SRC (y)) == LABEL_REF)
483718334Speter		;
483818334Speter	      else
483918334Speter		sets[n_sets++].rtl = y;
484018334Speter	    }
484118334Speter	  else if (GET_CODE (y) == CLOBBER)
484218334Speter	    {
484350397Sobrien	      /* If we clobber memory, canon the address.
484418334Speter		 This does nothing when a register is clobbered
484518334Speter		 because we have already invalidated the reg.  */
484618334Speter	      if (GET_CODE (XEXP (y, 0)) == MEM)
484750397Sobrien		canon_reg (XEXP (y, 0), NULL_RTX);
484818334Speter	    }
484918334Speter	  else if (GET_CODE (y) == USE
485018334Speter		   && ! (GET_CODE (XEXP (y, 0)) == REG
485118334Speter			 && REGNO (XEXP (y, 0)) < FIRST_PSEUDO_REGISTER))
485218334Speter	    canon_reg (y, NULL_RTX);
485318334Speter	  else if (GET_CODE (y) == CALL)
485418334Speter	    {
485518334Speter	      /* The result of apply_change_group can be ignored; see
485618334Speter		 canon_reg.  */
485718334Speter	      canon_reg (y, insn);
485818334Speter	      apply_change_group ();
485918334Speter	      fold_rtx (y, insn);
486018334Speter	    }
486118334Speter	}
486218334Speter    }
486318334Speter  else if (GET_CODE (x) == CLOBBER)
486418334Speter    {
486518334Speter      if (GET_CODE (XEXP (x, 0)) == MEM)
486650397Sobrien	canon_reg (XEXP (x, 0), NULL_RTX);
486718334Speter    }
486818334Speter
486918334Speter  /* Canonicalize a USE of a pseudo register or memory location.  */
487018334Speter  else if (GET_CODE (x) == USE
487118334Speter	   && ! (GET_CODE (XEXP (x, 0)) == REG
487218334Speter		 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER))
487318334Speter    canon_reg (XEXP (x, 0), NULL_RTX);
487418334Speter  else if (GET_CODE (x) == CALL)
487518334Speter    {
487618334Speter      /* The result of apply_change_group can be ignored; see canon_reg.  */
487718334Speter      canon_reg (x, insn);
487818334Speter      apply_change_group ();
487918334Speter      fold_rtx (x, insn);
488018334Speter    }
488118334Speter
488218334Speter  /* Store the equivalent value in SRC_EQV, if different, or if the DEST
488318334Speter     is a STRICT_LOW_PART.  The latter condition is necessary because SRC_EQV
488418334Speter     is handled specially for this case, and if it isn't set, then there will
488518334Speter     be no equivalence for the destination.  */
488618334Speter  if (n_sets == 1 && REG_NOTES (insn) != 0
488718334Speter      && (tem = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0
488818334Speter      && (! rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl))
488918334Speter	  || GET_CODE (SET_DEST (sets[0].rtl)) == STRICT_LOW_PART))
489018334Speter    src_eqv = canon_reg (XEXP (tem, 0), NULL_RTX);
489118334Speter
489218334Speter  /* Canonicalize sources and addresses of destinations.
489318334Speter     We do this in a separate pass to avoid problems when a MATCH_DUP is
489418334Speter     present in the insn pattern.  In that case, we want to ensure that
489518334Speter     we don't break the duplicate nature of the pattern.  So we will replace
489618334Speter     both operands at the same time.  Otherwise, we would fail to find an
489718334Speter     equivalent substitution in the loop calling validate_change below.
489818334Speter
489918334Speter     We used to suppress canonicalization of DEST if it appears in SRC,
490018334Speter     but we don't do this any more.  */
490118334Speter
490218334Speter  for (i = 0; i < n_sets; i++)
490318334Speter    {
490418334Speter      rtx dest = SET_DEST (sets[i].rtl);
490518334Speter      rtx src = SET_SRC (sets[i].rtl);
490618334Speter      rtx new = canon_reg (src, insn);
490750397Sobrien      int insn_code;
490818334Speter
490990075Sobrien      sets[i].orig_src = src;
491018334Speter      if ((GET_CODE (new) == REG && GET_CODE (src) == REG
491118334Speter	   && ((REGNO (new) < FIRST_PSEUDO_REGISTER)
491218334Speter	       != (REGNO (src) < FIRST_PSEUDO_REGISTER)))
491350397Sobrien	  || (insn_code = recog_memoized (insn)) < 0
491490075Sobrien	  || insn_data[insn_code].n_dups > 0)
491518334Speter	validate_change (insn, &SET_SRC (sets[i].rtl), new, 1);
491618334Speter      else
491718334Speter	SET_SRC (sets[i].rtl) = new;
491818334Speter
491918334Speter      if (GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT)
492018334Speter	{
492118334Speter	  validate_change (insn, &XEXP (dest, 1),
492218334Speter			   canon_reg (XEXP (dest, 1), insn), 1);
492318334Speter	  validate_change (insn, &XEXP (dest, 2),
492418334Speter			   canon_reg (XEXP (dest, 2), insn), 1);
492518334Speter	}
492618334Speter
492718334Speter      while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
492818334Speter	     || GET_CODE (dest) == ZERO_EXTRACT
492918334Speter	     || GET_CODE (dest) == SIGN_EXTRACT)
493018334Speter	dest = XEXP (dest, 0);
493118334Speter
493218334Speter      if (GET_CODE (dest) == MEM)
493318334Speter	canon_reg (dest, insn);
493418334Speter    }
493518334Speter
493618334Speter  /* Now that we have done all the replacements, we can apply the change
493718334Speter     group and see if they all work.  Note that this will cause some
493818334Speter     canonicalizations that would have worked individually not to be applied
493918334Speter     because some other canonicalization didn't work, but this should not
494090075Sobrien     occur often.
494118334Speter
494218334Speter     The result of apply_change_group can be ignored; see canon_reg.  */
494318334Speter
494418334Speter  apply_change_group ();
494518334Speter
494618334Speter  /* Set sets[i].src_elt to the class each source belongs to.
494718334Speter     Detect assignments from or to volatile things
494818334Speter     and set set[i] to zero so they will be ignored
494918334Speter     in the rest of this function.
495018334Speter
495118334Speter     Nothing in this loop changes the hash table or the register chains.  */
495218334Speter
495318334Speter  for (i = 0; i < n_sets; i++)
495418334Speter    {
495590075Sobrien      rtx src, dest;
495690075Sobrien      rtx src_folded;
495790075Sobrien      struct table_elt *elt = 0, *p;
495818334Speter      enum machine_mode mode;
495918334Speter      rtx src_eqv_here;
496018334Speter      rtx src_const = 0;
496118334Speter      rtx src_related = 0;
496218334Speter      struct table_elt *src_const_elt = 0;
496390075Sobrien      int src_cost = MAX_COST;
496490075Sobrien      int src_eqv_cost = MAX_COST;
496590075Sobrien      int src_folded_cost = MAX_COST;
496690075Sobrien      int src_related_cost = MAX_COST;
496790075Sobrien      int src_elt_cost = MAX_COST;
496890075Sobrien      int src_regcost = MAX_COST;
496990075Sobrien      int src_eqv_regcost = MAX_COST;
497090075Sobrien      int src_folded_regcost = MAX_COST;
497190075Sobrien      int src_related_regcost = MAX_COST;
497290075Sobrien      int src_elt_regcost = MAX_COST;
497318334Speter      /* Set non-zero if we need to call force_const_mem on with the
497418334Speter	 contents of src_folded before using it.  */
497518334Speter      int src_folded_force_flag = 0;
497618334Speter
497718334Speter      dest = SET_DEST (sets[i].rtl);
497818334Speter      src = SET_SRC (sets[i].rtl);
497918334Speter
498018334Speter      /* If SRC is a constant that has no machine mode,
498118334Speter	 hash it with the destination's machine mode.
498218334Speter	 This way we can keep different modes separate.  */
498318334Speter
498418334Speter      mode = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src);
498518334Speter      sets[i].mode = mode;
498618334Speter
498718334Speter      if (src_eqv)
498818334Speter	{
498918334Speter	  enum machine_mode eqvmode = mode;
499018334Speter	  if (GET_CODE (dest) == STRICT_LOW_PART)
499118334Speter	    eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
499218334Speter	  do_not_record = 0;
499318334Speter	  hash_arg_in_memory = 0;
499418334Speter	  src_eqv = fold_rtx (src_eqv, insn);
499518334Speter	  src_eqv_hash = HASH (src_eqv, eqvmode);
499618334Speter
499718334Speter	  /* Find the equivalence class for the equivalent expression.  */
499818334Speter
499918334Speter	  if (!do_not_record)
500018334Speter	    src_eqv_elt = lookup (src_eqv, src_eqv_hash, eqvmode);
500118334Speter
500218334Speter	  src_eqv_volatile = do_not_record;
500318334Speter	  src_eqv_in_memory = hash_arg_in_memory;
500418334Speter	}
500518334Speter
500618334Speter      /* If this is a STRICT_LOW_PART assignment, src_eqv corresponds to the
500718334Speter	 value of the INNER register, not the destination.  So it is not
500818334Speter	 a valid substitution for the source.  But save it for later.  */
500918334Speter      if (GET_CODE (dest) == STRICT_LOW_PART)
501018334Speter	src_eqv_here = 0;
501118334Speter      else
501218334Speter	src_eqv_here = src_eqv;
501318334Speter
501418334Speter      /* Simplify and foldable subexpressions in SRC.  Then get the fully-
501518334Speter	 simplified result, which may not necessarily be valid.  */
501618334Speter      src_folded = fold_rtx (src, insn);
501718334Speter
501818334Speter#if 0
501918334Speter      /* ??? This caused bad code to be generated for the m68k port with -O2.
502018334Speter	 Suppose src is (CONST_INT -1), and that after truncation src_folded
502118334Speter	 is (CONST_INT 3).  Suppose src_folded is then used for src_const.
502218334Speter	 At the end we will add src and src_const to the same equivalence
502318334Speter	 class.  We now have 3 and -1 on the same equivalence class.  This
502418334Speter	 causes later instructions to be mis-optimized.  */
502518334Speter      /* If storing a constant in a bitfield, pre-truncate the constant
502618334Speter	 so we will be able to record it later.  */
502718334Speter      if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT
502818334Speter	  || GET_CODE (SET_DEST (sets[i].rtl)) == SIGN_EXTRACT)
502918334Speter	{
503018334Speter	  rtx width = XEXP (SET_DEST (sets[i].rtl), 1);
503118334Speter
503218334Speter	  if (GET_CODE (src) == CONST_INT
503318334Speter	      && GET_CODE (width) == CONST_INT
503418334Speter	      && INTVAL (width) < HOST_BITS_PER_WIDE_INT
503518334Speter	      && (INTVAL (src) & ((HOST_WIDE_INT) (-1) << INTVAL (width))))
503618334Speter	    src_folded
503718334Speter	      = GEN_INT (INTVAL (src) & (((HOST_WIDE_INT) 1
503818334Speter					  << INTVAL (width)) - 1));
503918334Speter	}
504018334Speter#endif
504118334Speter
504218334Speter      /* Compute SRC's hash code, and also notice if it
504318334Speter	 should not be recorded at all.  In that case,
504418334Speter	 prevent any further processing of this assignment.  */
504518334Speter      do_not_record = 0;
504618334Speter      hash_arg_in_memory = 0;
504718334Speter
504818334Speter      sets[i].src = src;
504918334Speter      sets[i].src_hash = HASH (src, mode);
505018334Speter      sets[i].src_volatile = do_not_record;
505118334Speter      sets[i].src_in_memory = hash_arg_in_memory;
505218334Speter
505350397Sobrien      /* If SRC is a MEM, there is a REG_EQUIV note for SRC, and DEST is
505490075Sobrien	 a pseudo, do not record SRC.  Using SRC as a replacement for
505590075Sobrien	 anything else will be incorrect in that situation.  Note that
505690075Sobrien	 this usually occurs only for stack slots, in which case all the
505790075Sobrien	 RTL would be referring to SRC, so we don't lose any optimization
505890075Sobrien	 opportunities by not having SRC in the hash table.  */
505950397Sobrien
506050397Sobrien      if (GET_CODE (src) == MEM
506190075Sobrien	  && find_reg_note (insn, REG_EQUIV, NULL_RTX) != 0
506250397Sobrien	  && GET_CODE (dest) == REG
506390075Sobrien	  && REGNO (dest) >= FIRST_PSEUDO_REGISTER)
506450397Sobrien	sets[i].src_volatile = 1;
506550397Sobrien
506618334Speter#if 0
506718334Speter      /* It is no longer clear why we used to do this, but it doesn't
506818334Speter	 appear to still be needed.  So let's try without it since this
506918334Speter	 code hurts cse'ing widened ops.  */
507018334Speter      /* If source is a perverse subreg (such as QI treated as an SI),
507118334Speter	 treat it as volatile.  It may do the work of an SI in one context
507218334Speter	 where the extra bits are not being used, but cannot replace an SI
507318334Speter	 in general.  */
507418334Speter      if (GET_CODE (src) == SUBREG
507518334Speter	  && (GET_MODE_SIZE (GET_MODE (src))
507618334Speter	      > GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))
507718334Speter	sets[i].src_volatile = 1;
507818334Speter#endif
507918334Speter
508018334Speter      /* Locate all possible equivalent forms for SRC.  Try to replace
508118334Speter         SRC in the insn with each cheaper equivalent.
508218334Speter
508318334Speter         We have the following types of equivalents: SRC itself, a folded
508418334Speter         version, a value given in a REG_EQUAL note, or a value related
508518334Speter	 to a constant.
508618334Speter
508718334Speter         Each of these equivalents may be part of an additional class
508818334Speter         of equivalents (if more than one is in the table, they must be in
508918334Speter         the same class; we check for this).
509018334Speter
509118334Speter	 If the source is volatile, we don't do any table lookups.
509218334Speter
509318334Speter         We note any constant equivalent for possible later use in a
509418334Speter         REG_NOTE.  */
509518334Speter
509618334Speter      if (!sets[i].src_volatile)
509718334Speter	elt = lookup (src, sets[i].src_hash, mode);
509818334Speter
509918334Speter      sets[i].src_elt = elt;
510018334Speter
510118334Speter      if (elt && src_eqv_here && src_eqv_elt)
510290075Sobrien	{
510390075Sobrien	  if (elt->first_same_value != src_eqv_elt->first_same_value)
510418334Speter	    {
510518334Speter	      /* The REG_EQUAL is indicating that two formerly distinct
510618334Speter		 classes are now equivalent.  So merge them.  */
510718334Speter	      merge_equiv_classes (elt, src_eqv_elt);
510818334Speter	      src_eqv_hash = HASH (src_eqv, elt->mode);
510918334Speter	      src_eqv_elt = lookup (src_eqv, src_eqv_hash, elt->mode);
511018334Speter	    }
511118334Speter
511290075Sobrien	  src_eqv_here = 0;
511390075Sobrien	}
511418334Speter
511518334Speter      else if (src_eqv_elt)
511690075Sobrien	elt = src_eqv_elt;
511718334Speter
511818334Speter      /* Try to find a constant somewhere and record it in `src_const'.
511918334Speter	 Record its table element, if any, in `src_const_elt'.  Look in
512018334Speter	 any known equivalences first.  (If the constant is not in the
512118334Speter	 table, also set `sets[i].src_const_hash').  */
512218334Speter      if (elt)
512390075Sobrien	for (p = elt->first_same_value; p; p = p->next_same_value)
512418334Speter	  if (p->is_const)
512518334Speter	    {
512618334Speter	      src_const = p->exp;
512718334Speter	      src_const_elt = elt;
512818334Speter	      break;
512918334Speter	    }
513018334Speter
513118334Speter      if (src_const == 0
513218334Speter	  && (CONSTANT_P (src_folded)
513390075Sobrien	      /* Consider (minus (label_ref L1) (label_ref L2)) as
513418334Speter		 "constant" here so we will record it. This allows us
513518334Speter		 to fold switch statements when an ADDR_DIFF_VEC is used.  */
513618334Speter	      || (GET_CODE (src_folded) == MINUS
513718334Speter		  && GET_CODE (XEXP (src_folded, 0)) == LABEL_REF
513818334Speter		  && GET_CODE (XEXP (src_folded, 1)) == LABEL_REF)))
513918334Speter	src_const = src_folded, src_const_elt = elt;
514018334Speter      else if (src_const == 0 && src_eqv_here && CONSTANT_P (src_eqv_here))
514118334Speter	src_const = src_eqv_here, src_const_elt = src_eqv_elt;
514218334Speter
514318334Speter      /* If we don't know if the constant is in the table, get its
514418334Speter	 hash code and look it up.  */
514518334Speter      if (src_const && src_const_elt == 0)
514618334Speter	{
514718334Speter	  sets[i].src_const_hash = HASH (src_const, mode);
514818334Speter	  src_const_elt = lookup (src_const, sets[i].src_const_hash, mode);
514918334Speter	}
515018334Speter
515118334Speter      sets[i].src_const = src_const;
515218334Speter      sets[i].src_const_elt = src_const_elt;
515318334Speter
515418334Speter      /* If the constant and our source are both in the table, mark them as
515518334Speter	 equivalent.  Otherwise, if a constant is in the table but the source
515618334Speter	 isn't, set ELT to it.  */
515718334Speter      if (src_const_elt && elt
515818334Speter	  && src_const_elt->first_same_value != elt->first_same_value)
515918334Speter	merge_equiv_classes (elt, src_const_elt);
516018334Speter      else if (src_const_elt && elt == 0)
516118334Speter	elt = src_const_elt;
516218334Speter
516318334Speter      /* See if there is a register linearly related to a constant
516418334Speter         equivalent of SRC.  */
516518334Speter      if (src_const
516618334Speter	  && (GET_CODE (src_const) == CONST
516718334Speter	      || (src_const_elt && src_const_elt->related_value != 0)))
516890075Sobrien	{
516990075Sobrien	  src_related = use_related_value (src_const, src_const_elt);
517090075Sobrien	  if (src_related)
517190075Sobrien	    {
517218334Speter	      struct table_elt *src_related_elt
517390075Sobrien		= lookup (src_related, HASH (src_related, mode), mode);
517418334Speter	      if (src_related_elt && elt)
517590075Sobrien		{
517618334Speter		  if (elt->first_same_value
517718334Speter		      != src_related_elt->first_same_value)
517890075Sobrien		    /* This can occur when we previously saw a CONST
517918334Speter		       involving a SYMBOL_REF and then see the SYMBOL_REF
518018334Speter		       twice.  Merge the involved classes.  */
518118334Speter		    merge_equiv_classes (elt, src_related_elt);
518218334Speter
518390075Sobrien		  src_related = 0;
518418334Speter		  src_related_elt = 0;
518590075Sobrien		}
518690075Sobrien	      else if (src_related_elt && elt == 0)
518790075Sobrien		elt = src_related_elt;
518818334Speter	    }
518990075Sobrien	}
519018334Speter
519118334Speter      /* See if we have a CONST_INT that is already in a register in a
519218334Speter	 wider mode.  */
519318334Speter
519418334Speter      if (src_const && src_related == 0 && GET_CODE (src_const) == CONST_INT
519518334Speter	  && GET_MODE_CLASS (mode) == MODE_INT
519618334Speter	  && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
519718334Speter	{
519818334Speter	  enum machine_mode wider_mode;
519918334Speter
520018334Speter	  for (wider_mode = GET_MODE_WIDER_MODE (mode);
520118334Speter	       GET_MODE_BITSIZE (wider_mode) <= BITS_PER_WORD
520218334Speter	       && src_related == 0;
520318334Speter	       wider_mode = GET_MODE_WIDER_MODE (wider_mode))
520418334Speter	    {
520518334Speter	      struct table_elt *const_elt
520618334Speter		= lookup (src_const, HASH (src_const, wider_mode), wider_mode);
520718334Speter
520818334Speter	      if (const_elt == 0)
520918334Speter		continue;
521018334Speter
521118334Speter	      for (const_elt = const_elt->first_same_value;
521218334Speter		   const_elt; const_elt = const_elt->next_same_value)
521318334Speter		if (GET_CODE (const_elt->exp) == REG)
521418334Speter		  {
521518334Speter		    src_related = gen_lowpart_if_possible (mode,
521618334Speter							   const_elt->exp);
521718334Speter		    break;
521818334Speter		  }
521918334Speter	    }
522018334Speter	}
522118334Speter
522218334Speter      /* Another possibility is that we have an AND with a constant in
522318334Speter	 a mode narrower than a word.  If so, it might have been generated
522418334Speter	 as part of an "if" which would narrow the AND.  If we already
522518334Speter	 have done the AND in a wider mode, we can use a SUBREG of that
522618334Speter	 value.  */
522718334Speter
522818334Speter      if (flag_expensive_optimizations && ! src_related
522918334Speter	  && GET_CODE (src) == AND && GET_CODE (XEXP (src, 1)) == CONST_INT
523018334Speter	  && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
523118334Speter	{
523218334Speter	  enum machine_mode tmode;
523350397Sobrien	  rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));
523418334Speter
523518334Speter	  for (tmode = GET_MODE_WIDER_MODE (mode);
523618334Speter	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
523718334Speter	       tmode = GET_MODE_WIDER_MODE (tmode))
523818334Speter	    {
523918334Speter	      rtx inner = gen_lowpart_if_possible (tmode, XEXP (src, 0));
524018334Speter	      struct table_elt *larger_elt;
524118334Speter
524218334Speter	      if (inner)
524318334Speter		{
524418334Speter		  PUT_MODE (new_and, tmode);
524518334Speter		  XEXP (new_and, 0) = inner;
524618334Speter		  larger_elt = lookup (new_and, HASH (new_and, tmode), tmode);
524718334Speter		  if (larger_elt == 0)
524818334Speter		    continue;
524918334Speter
525018334Speter		  for (larger_elt = larger_elt->first_same_value;
525118334Speter		       larger_elt; larger_elt = larger_elt->next_same_value)
525218334Speter		    if (GET_CODE (larger_elt->exp) == REG)
525318334Speter		      {
525418334Speter			src_related
525518334Speter			  = gen_lowpart_if_possible (mode, larger_elt->exp);
525618334Speter			break;
525718334Speter		      }
525818334Speter
525918334Speter		  if (src_related)
526018334Speter		    break;
526118334Speter		}
526218334Speter	    }
526318334Speter	}
526418334Speter
526518334Speter#ifdef LOAD_EXTEND_OP
526618334Speter      /* See if a MEM has already been loaded with a widening operation;
526718334Speter	 if it has, we can use a subreg of that.  Many CISC machines
526818334Speter	 also have such operations, but this is only likely to be
526918334Speter	 beneficial these machines.  */
527090075Sobrien
527190075Sobrien      if (flag_expensive_optimizations && src_related == 0
527218334Speter	  && (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
527318334Speter	  && GET_MODE_CLASS (mode) == MODE_INT
527418334Speter	  && GET_CODE (src) == MEM && ! do_not_record
527518334Speter	  && LOAD_EXTEND_OP (mode) != NIL)
527618334Speter	{
527718334Speter	  enum machine_mode tmode;
527890075Sobrien
527918334Speter	  /* Set what we are trying to extend and the operation it might
528018334Speter	     have been extended with.  */
528118334Speter	  PUT_CODE (memory_extend_rtx, LOAD_EXTEND_OP (mode));
528218334Speter	  XEXP (memory_extend_rtx, 0) = src;
528390075Sobrien
528418334Speter	  for (tmode = GET_MODE_WIDER_MODE (mode);
528518334Speter	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
528618334Speter	       tmode = GET_MODE_WIDER_MODE (tmode))
528718334Speter	    {
528818334Speter	      struct table_elt *larger_elt;
528990075Sobrien
529018334Speter	      PUT_MODE (memory_extend_rtx, tmode);
529190075Sobrien	      larger_elt = lookup (memory_extend_rtx,
529218334Speter				   HASH (memory_extend_rtx, tmode), tmode);
529318334Speter	      if (larger_elt == 0)
529418334Speter		continue;
529590075Sobrien
529618334Speter	      for (larger_elt = larger_elt->first_same_value;
529718334Speter		   larger_elt; larger_elt = larger_elt->next_same_value)
529818334Speter		if (GET_CODE (larger_elt->exp) == REG)
529918334Speter		  {
530090075Sobrien		    src_related = gen_lowpart_if_possible (mode,
530118334Speter							   larger_elt->exp);
530218334Speter		    break;
530318334Speter		  }
530490075Sobrien
530518334Speter	      if (src_related)
530618334Speter		break;
530718334Speter	    }
530818334Speter	}
530918334Speter#endif /* LOAD_EXTEND_OP */
531090075Sobrien
531118334Speter      if (src == src_folded)
531290075Sobrien	src_folded = 0;
531318334Speter
531418334Speter      /* At this point, ELT, if non-zero, points to a class of expressions
531518334Speter         equivalent to the source of this SET and SRC, SRC_EQV, SRC_FOLDED,
531618334Speter	 and SRC_RELATED, if non-zero, each contain additional equivalent
531718334Speter	 expressions.  Prune these latter expressions by deleting expressions
531818334Speter	 already in the equivalence class.
531918334Speter
532018334Speter	 Check for an equivalent identical to the destination.  If found,
532118334Speter	 this is the preferred equivalent since it will likely lead to
532218334Speter	 elimination of the insn.  Indicate this by placing it in
532318334Speter	 `src_related'.  */
532418334Speter
532590075Sobrien      if (elt)
532690075Sobrien	elt = elt->first_same_value;
532718334Speter      for (p = elt; p; p = p->next_same_value)
532890075Sobrien	{
532918334Speter	  enum rtx_code code = GET_CODE (p->exp);
533018334Speter
533118334Speter	  /* If the expression is not valid, ignore it.  Then we do not
533218334Speter	     have to check for validity below.  In most cases, we can use
533318334Speter	     `rtx_equal_p', since canonicalization has already been done.  */
533418334Speter	  if (code != REG && ! exp_equiv_p (p->exp, p->exp, 1, 0))
533518334Speter	    continue;
533618334Speter
533750397Sobrien	  /* Also skip paradoxical subregs, unless that's what we're
533850397Sobrien	     looking for.  */
533950397Sobrien	  if (code == SUBREG
534050397Sobrien	      && (GET_MODE_SIZE (GET_MODE (p->exp))
534150397Sobrien		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (p->exp))))
534250397Sobrien	      && ! (src != 0
534350397Sobrien		    && GET_CODE (src) == SUBREG
534450397Sobrien		    && GET_MODE (src) == GET_MODE (p->exp)
534550397Sobrien		    && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
534650397Sobrien			< GET_MODE_SIZE (GET_MODE (SUBREG_REG (p->exp))))))
534750397Sobrien	    continue;
534850397Sobrien
534990075Sobrien	  if (src && GET_CODE (src) == code && rtx_equal_p (src, p->exp))
535018334Speter	    src = 0;
535190075Sobrien	  else if (src_folded && GET_CODE (src_folded) == code
535218334Speter		   && rtx_equal_p (src_folded, p->exp))
535318334Speter	    src_folded = 0;
535490075Sobrien	  else if (src_eqv_here && GET_CODE (src_eqv_here) == code
535518334Speter		   && rtx_equal_p (src_eqv_here, p->exp))
535618334Speter	    src_eqv_here = 0;
535790075Sobrien	  else if (src_related && GET_CODE (src_related) == code
535818334Speter		   && rtx_equal_p (src_related, p->exp))
535918334Speter	    src_related = 0;
536018334Speter
536118334Speter	  /* This is the same as the destination of the insns, we want
536218334Speter	     to prefer it.  Copy it to src_related.  The code below will
536318334Speter	     then give it a negative cost.  */
536418334Speter	  if (GET_CODE (dest) == code && rtx_equal_p (p->exp, dest))
536518334Speter	    src_related = dest;
536690075Sobrien	}
536718334Speter
536818334Speter      /* Find the cheapest valid equivalent, trying all the available
536918334Speter         possibilities.  Prefer items not in the hash table to ones
537018334Speter         that are when they are equal cost.  Note that we can never
537118334Speter         worsen an insn as the current contents will also succeed.
537218334Speter	 If we find an equivalent identical to the destination, use it as best,
537350397Sobrien	 since this insn will probably be eliminated in that case.  */
537418334Speter      if (src)
537518334Speter	{
537618334Speter	  if (rtx_equal_p (src, dest))
537790075Sobrien	    src_cost = src_regcost = -1;
537818334Speter	  else
537990075Sobrien	    {
538090075Sobrien	      src_cost = COST (src);
538190075Sobrien	      src_regcost = approx_reg_cost (src);
538290075Sobrien	    }
538318334Speter	}
538418334Speter
538518334Speter      if (src_eqv_here)
538618334Speter	{
538718334Speter	  if (rtx_equal_p (src_eqv_here, dest))
538890075Sobrien	    src_eqv_cost = src_eqv_regcost = -1;
538918334Speter	  else
539090075Sobrien	    {
539190075Sobrien	      src_eqv_cost = COST (src_eqv_here);
539290075Sobrien	      src_eqv_regcost = approx_reg_cost (src_eqv_here);
539390075Sobrien	    }
539418334Speter	}
539518334Speter
539618334Speter      if (src_folded)
539718334Speter	{
539818334Speter	  if (rtx_equal_p (src_folded, dest))
539990075Sobrien	    src_folded_cost = src_folded_regcost = -1;
540018334Speter	  else
540190075Sobrien	    {
540290075Sobrien	      src_folded_cost = COST (src_folded);
540390075Sobrien	      src_folded_regcost = approx_reg_cost (src_folded);
540490075Sobrien	    }
540518334Speter	}
540618334Speter
540718334Speter      if (src_related)
540818334Speter	{
540918334Speter	  if (rtx_equal_p (src_related, dest))
541090075Sobrien	    src_related_cost = src_related_regcost = -1;
541118334Speter	  else
541290075Sobrien	    {
541390075Sobrien	      src_related_cost = COST (src_related);
541490075Sobrien	      src_related_regcost = approx_reg_cost (src_related);
541590075Sobrien	    }
541618334Speter	}
541718334Speter
541818334Speter      /* If this was an indirect jump insn, a known label will really be
541918334Speter	 cheaper even though it looks more expensive.  */
542018334Speter      if (dest == pc_rtx && src_const && GET_CODE (src_const) == LABEL_REF)
542190075Sobrien	src_folded = src_const, src_folded_cost = src_folded_regcost = -1;
542290075Sobrien
542318334Speter      /* Terminate loop when replacement made.  This must terminate since
542418334Speter         the current contents will be tested and will always be valid.  */
542518334Speter      while (1)
542690075Sobrien	{
542790075Sobrien	  rtx trial;
542818334Speter
542990075Sobrien	  /* Skip invalid entries.  */
543090075Sobrien	  while (elt && GET_CODE (elt->exp) != REG
543190075Sobrien		 && ! exp_equiv_p (elt->exp, elt->exp, 1, 0))
543290075Sobrien	    elt = elt->next_same_value;
543350397Sobrien
543450397Sobrien	  /* A paradoxical subreg would be bad here: it'll be the right
543550397Sobrien	     size, but later may be adjusted so that the upper bits aren't
543650397Sobrien	     what we want.  So reject it.  */
543750397Sobrien	  if (elt != 0
543850397Sobrien	      && GET_CODE (elt->exp) == SUBREG
543950397Sobrien	      && (GET_MODE_SIZE (GET_MODE (elt->exp))
544050397Sobrien		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (elt->exp))))
544150397Sobrien	      /* It is okay, though, if the rtx we're trying to match
544250397Sobrien		 will ignore any of the bits we can't predict.  */
544350397Sobrien	      && ! (src != 0
544450397Sobrien		    && GET_CODE (src) == SUBREG
544550397Sobrien		    && GET_MODE (src) == GET_MODE (elt->exp)
544650397Sobrien		    && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
544750397Sobrien			< GET_MODE_SIZE (GET_MODE (SUBREG_REG (elt->exp))))))
544850397Sobrien	    {
544950397Sobrien	      elt = elt->next_same_value;
545050397Sobrien	      continue;
545150397Sobrien	    }
545218334Speter
545390075Sobrien          if (elt)
545490075Sobrien	    {
545590075Sobrien	      src_elt_cost = elt->cost;
545690075Sobrien	      src_elt_regcost = elt->regcost;
545790075Sobrien	    }
545890075Sobrien
545918334Speter          /* Find cheapest and skip it for the next time.   For items
546018334Speter	     of equal cost, use this order:
546118334Speter	     src_folded, src, src_eqv, src_related and hash table entry.  */
546290075Sobrien	  if (src_folded
546390075Sobrien	      && preferrable (src_folded_cost, src_folded_regcost,
546490075Sobrien			      src_cost, src_regcost) <= 0
546590075Sobrien	      && preferrable (src_folded_cost, src_folded_regcost,
546690075Sobrien			      src_eqv_cost, src_eqv_regcost) <= 0
546790075Sobrien	      && preferrable (src_folded_cost, src_folded_regcost,
546890075Sobrien			      src_related_cost, src_related_regcost) <= 0
546990075Sobrien	      && preferrable (src_folded_cost, src_folded_regcost,
547090075Sobrien			      src_elt_cost, src_elt_regcost) <= 0)
547118334Speter	    {
547290075Sobrien	      trial = src_folded, src_folded_cost = MAX_COST;
547318334Speter	      if (src_folded_force_flag)
547418334Speter		trial = force_const_mem (mode, trial);
547518334Speter	    }
547690075Sobrien	  else if (src
547790075Sobrien		   && preferrable (src_cost, src_regcost,
547890075Sobrien				   src_eqv_cost, src_eqv_regcost) <= 0
547990075Sobrien		   && preferrable (src_cost, src_regcost,
548090075Sobrien				   src_related_cost, src_related_regcost) <= 0
548190075Sobrien		   && preferrable (src_cost, src_regcost,
548290075Sobrien				   src_elt_cost, src_elt_regcost) <= 0)
548390075Sobrien	    trial = src, src_cost = MAX_COST;
548490075Sobrien	  else if (src_eqv_here
548590075Sobrien		   && preferrable (src_eqv_cost, src_eqv_regcost,
548690075Sobrien				   src_related_cost, src_related_regcost) <= 0
548790075Sobrien		   && preferrable (src_eqv_cost, src_eqv_regcost,
548890075Sobrien				   src_elt_cost, src_elt_regcost) <= 0)
548990075Sobrien	    trial = copy_rtx (src_eqv_here), src_eqv_cost = MAX_COST;
549090075Sobrien	  else if (src_related
549190075Sobrien		   && preferrable (src_related_cost, src_related_regcost,
549290075Sobrien				   src_elt_cost, src_elt_regcost) <= 0)
549390075Sobrien  	    trial = copy_rtx (src_related), src_related_cost = MAX_COST;
549490075Sobrien	  else
549518334Speter	    {
549618334Speter	      trial = copy_rtx (elt->exp);
549718334Speter	      elt = elt->next_same_value;
549890075Sobrien	      src_elt_cost = MAX_COST;
549918334Speter	    }
550018334Speter
550118334Speter	  /* We don't normally have an insn matching (set (pc) (pc)), so
550218334Speter	     check for this separately here.  We will delete such an
550318334Speter	     insn below.
550418334Speter
550590075Sobrien	     For other cases such as a table jump or conditional jump
550690075Sobrien	     where we know the ultimate target, go ahead and replace the
550790075Sobrien	     operand.  While that may not make a valid insn, we will
550890075Sobrien	     reemit the jump below (and also insert any necessary
550990075Sobrien	     barriers).  */
551018334Speter	  if (n_sets == 1 && dest == pc_rtx
551118334Speter	      && (trial == pc_rtx
551218334Speter		  || (GET_CODE (trial) == LABEL_REF
551318334Speter		      && ! condjump_p (insn))))
551418334Speter	    {
551518334Speter	      SET_SRC (sets[i].rtl) = trial;
551690075Sobrien	      cse_jumps_altered = 1;
551718334Speter	      break;
551818334Speter	    }
551990075Sobrien
552018334Speter	  /* Look for a substitution that makes a valid insn.  */
552190075Sobrien	  else if (validate_change (insn, &SET_SRC (sets[i].rtl), trial, 0))
552218334Speter	    {
552350397Sobrien	      /* If we just made a substitution inside a libcall, then we
552450397Sobrien		 need to make the same substitution in any notes attached
552550397Sobrien		 to the RETVAL insn.  */
552650397Sobrien	      if (libcall_insn
552790075Sobrien		  && (GET_CODE (sets[i].orig_src) == REG
552890075Sobrien		      || GET_CODE (sets[i].orig_src) == SUBREG
552990075Sobrien		      || GET_CODE (sets[i].orig_src) == MEM))
553090075Sobrien		replace_rtx (REG_NOTES (libcall_insn), sets[i].orig_src,
553150397Sobrien			     canon_reg (SET_SRC (sets[i].rtl), insn));
553250397Sobrien
553318334Speter	      /* The result of apply_change_group can be ignored; see
553418334Speter		 canon_reg.  */
553518334Speter
553618334Speter	      validate_change (insn, &SET_SRC (sets[i].rtl),
553718334Speter			       canon_reg (SET_SRC (sets[i].rtl), insn),
553818334Speter			       1);
553918334Speter	      apply_change_group ();
554018334Speter	      break;
554118334Speter	    }
554218334Speter
554390075Sobrien	  /* If we previously found constant pool entries for
554418334Speter	     constants and this is a constant, try making a
554518334Speter	     pool entry.  Put it in src_folded unless we already have done
554618334Speter	     this since that is where it likely came from.  */
554718334Speter
554818334Speter	  else if (constant_pool_entries_cost
554918334Speter		   && CONSTANT_P (trial)
555090075Sobrien		   /* Reject cases that will abort in decode_rtx_const.
555190075Sobrien		      On the alpha when simplifying a switch, we get
555290075Sobrien		      (const (truncate (minus (label_ref) (label_ref)))).  */
555318334Speter		   && ! (GET_CODE (trial) == CONST
555418334Speter			 && GET_CODE (XEXP (trial, 0)) == TRUNCATE)
555590075Sobrien		   /* Likewise on IA-64, except without the truncate.  */
555690075Sobrien		   && ! (GET_CODE (trial) == CONST
555790075Sobrien			 && GET_CODE (XEXP (trial, 0)) == MINUS
555890075Sobrien			 && GET_CODE (XEXP (XEXP (trial, 0), 0)) == LABEL_REF
555990075Sobrien			 && GET_CODE (XEXP (XEXP (trial, 0), 1)) == LABEL_REF)
556018334Speter		   && (src_folded == 0
556118334Speter		       || (GET_CODE (src_folded) != MEM
556218334Speter			   && ! src_folded_force_flag))
556350397Sobrien		   && GET_MODE_CLASS (mode) != MODE_CC
556450397Sobrien		   && mode != VOIDmode)
556518334Speter	    {
556618334Speter	      src_folded_force_flag = 1;
556718334Speter	      src_folded = trial;
556818334Speter	      src_folded_cost = constant_pool_entries_cost;
556918334Speter	    }
557090075Sobrien	}
557118334Speter
557218334Speter      src = SET_SRC (sets[i].rtl);
557318334Speter
557418334Speter      /* In general, it is good to have a SET with SET_SRC == SET_DEST.
557518334Speter	 However, there is an important exception:  If both are registers
557618334Speter	 that are not the head of their equivalence class, replace SET_SRC
557718334Speter	 with the head of the class.  If we do not do this, we will have
557818334Speter	 both registers live over a portion of the basic block.  This way,
557918334Speter	 their lifetimes will likely abut instead of overlapping.  */
558018334Speter      if (GET_CODE (dest) == REG
558190075Sobrien	  && REGNO_QTY_VALID_P (REGNO (dest)))
558218334Speter	{
558390075Sobrien	  int dest_q = REG_QTY (REGNO (dest));
558490075Sobrien	  struct qty_table_elem *dest_ent = &qty_table[dest_q];
558518334Speter
558690075Sobrien	  if (dest_ent->mode == GET_MODE (dest)
558790075Sobrien	      && dest_ent->first_reg != REGNO (dest)
558890075Sobrien	      && GET_CODE (src) == REG && REGNO (src) == REGNO (dest)
558990075Sobrien	      /* Don't do this if the original insn had a hard reg as
559090075Sobrien		 SET_SRC or SET_DEST.  */
559190075Sobrien	      && (GET_CODE (sets[i].src) != REG
559290075Sobrien		  || REGNO (sets[i].src) >= FIRST_PSEUDO_REGISTER)
559390075Sobrien	      && (GET_CODE (dest) != REG || REGNO (dest) >= FIRST_PSEUDO_REGISTER))
559490075Sobrien	    /* We can't call canon_reg here because it won't do anything if
559590075Sobrien	       SRC is a hard register.  */
559650397Sobrien	    {
559790075Sobrien	      int src_q = REG_QTY (REGNO (src));
559890075Sobrien	      struct qty_table_elem *src_ent = &qty_table[src_q];
559990075Sobrien	      int first = src_ent->first_reg;
560090075Sobrien	      rtx new_src
560190075Sobrien		= (first >= FIRST_PSEUDO_REGISTER
560290075Sobrien		   ? regno_reg_rtx[first] : gen_rtx_REG (GET_MODE (src), first));
560390075Sobrien
560490075Sobrien	      /* We must use validate-change even for this, because this
560590075Sobrien		 might be a special no-op instruction, suitable only to
560690075Sobrien		 tag notes onto.  */
560790075Sobrien	      if (validate_change (insn, &SET_SRC (sets[i].rtl), new_src, 0))
560890075Sobrien		{
560990075Sobrien		  src = new_src;
561090075Sobrien		  /* If we had a constant that is cheaper than what we are now
561190075Sobrien		     setting SRC to, use that constant.  We ignored it when we
561290075Sobrien		     thought we could make this into a no-op.  */
561390075Sobrien		  if (src_const && COST (src_const) < COST (src)
561490075Sobrien		      && validate_change (insn, &SET_SRC (sets[i].rtl),
561590075Sobrien					  src_const, 0))
561690075Sobrien		    src = src_const;
561790075Sobrien		}
561850397Sobrien	    }
561918334Speter	}
562018334Speter
562118334Speter      /* If we made a change, recompute SRC values.  */
562218334Speter      if (src != sets[i].src)
562390075Sobrien	{
562490075Sobrien	  cse_altered = 1;
562590075Sobrien	  do_not_record = 0;
562690075Sobrien	  hash_arg_in_memory = 0;
562718334Speter	  sets[i].src = src;
562890075Sobrien	  sets[i].src_hash = HASH (src, mode);
562990075Sobrien	  sets[i].src_volatile = do_not_record;
563090075Sobrien	  sets[i].src_in_memory = hash_arg_in_memory;
563190075Sobrien	  sets[i].src_elt = lookup (src, sets[i].src_hash, mode);
563290075Sobrien	}
563318334Speter
563418334Speter      /* If this is a single SET, we are setting a register, and we have an
563518334Speter	 equivalent constant, we want to add a REG_NOTE.   We don't want
563618334Speter	 to write a REG_EQUAL note for a constant pseudo since verifying that
563718334Speter	 that pseudo hasn't been eliminated is a pain.  Such a note also
563890075Sobrien	 won't help anything.
563950397Sobrien
564050397Sobrien	 Avoid a REG_EQUAL note for (CONST (MINUS (LABEL_REF) (LABEL_REF)))
564150397Sobrien	 which can be created for a reference to a compile time computable
564250397Sobrien	 entry in a jump table.  */
564350397Sobrien
564418334Speter      if (n_sets == 1 && src_const && GET_CODE (dest) == REG
564550397Sobrien	  && GET_CODE (src_const) != REG
564650397Sobrien	  && ! (GET_CODE (src_const) == CONST
564750397Sobrien		&& GET_CODE (XEXP (src_const, 0)) == MINUS
564850397Sobrien		&& GET_CODE (XEXP (XEXP (src_const, 0), 0)) == LABEL_REF
564950397Sobrien		&& GET_CODE (XEXP (XEXP (src_const, 0), 1)) == LABEL_REF))
565018334Speter	{
565152284Sobrien	  /* Make sure that the rtx is not shared with any other insn.  */
565252284Sobrien	  src_const = copy_rtx (src_const);
565352284Sobrien
565418334Speter	  /* Record the actual constant value in a REG_EQUAL note, making
565518334Speter	     a new one if one does not already exist.  */
565690075Sobrien	  set_unique_reg_note (insn, REG_EQUAL, src_const);
565718334Speter
565818334Speter          /* If storing a constant value in a register that
565918334Speter	     previously held the constant value 0,
566018334Speter	     record this fact with a REG_WAS_0 note on this insn.
566118334Speter
566218334Speter	     Note that the *register* is required to have previously held 0,
566318334Speter	     not just any register in the quantity and we must point to the
566418334Speter	     insn that set that register to zero.
566518334Speter
566618334Speter	     Rather than track each register individually, we just see if
566718334Speter	     the last set for this quantity was for this register.  */
566818334Speter
566990075Sobrien	  if (REGNO_QTY_VALID_P (REGNO (dest)))
567018334Speter	    {
567190075Sobrien	      int dest_q = REG_QTY (REGNO (dest));
567290075Sobrien	      struct qty_table_elem *dest_ent = &qty_table[dest_q];
567318334Speter
567490075Sobrien	      if (dest_ent->const_rtx == const0_rtx)
567518334Speter		{
567690075Sobrien		  /* See if we previously had a REG_WAS_0 note.  */
567790075Sobrien		  rtx note = find_reg_note (insn, REG_WAS_0, NULL_RTX);
567890075Sobrien		  rtx const_insn = dest_ent->const_insn;
567990075Sobrien
568090075Sobrien		  if ((tem = single_set (const_insn)) != 0
568190075Sobrien		      && rtx_equal_p (SET_DEST (tem), dest))
568290075Sobrien		    {
568390075Sobrien		      if (note)
568490075Sobrien			XEXP (note, 0) = const_insn;
568590075Sobrien		      else
568690075Sobrien			REG_NOTES (insn)
568790075Sobrien			  = gen_rtx_INSN_LIST (REG_WAS_0, const_insn,
568890075Sobrien					       REG_NOTES (insn));
568990075Sobrien		    }
569018334Speter		}
569118334Speter	    }
569218334Speter	}
569318334Speter
569418334Speter      /* Now deal with the destination.  */
569518334Speter      do_not_record = 0;
569618334Speter
569718334Speter      /* Look within any SIGN_EXTRACT or ZERO_EXTRACT
569818334Speter	 to the MEM or REG within it.  */
569918334Speter      while (GET_CODE (dest) == SIGN_EXTRACT
570018334Speter	     || GET_CODE (dest) == ZERO_EXTRACT
570118334Speter	     || GET_CODE (dest) == SUBREG
570218334Speter	     || GET_CODE (dest) == STRICT_LOW_PART)
570390075Sobrien	dest = XEXP (dest, 0);
570418334Speter
570518334Speter      sets[i].inner_dest = dest;
570618334Speter
570718334Speter      if (GET_CODE (dest) == MEM)
570818334Speter	{
570950397Sobrien#ifdef PUSH_ROUNDING
571050397Sobrien	  /* Stack pushes invalidate the stack pointer.  */
571150397Sobrien	  rtx addr = XEXP (dest, 0);
571290075Sobrien	  if (GET_RTX_CLASS (GET_CODE (addr)) == 'a'
571350397Sobrien	      && XEXP (addr, 0) == stack_pointer_rtx)
571450397Sobrien	    invalidate (stack_pointer_rtx, Pmode);
571550397Sobrien#endif
571618334Speter	  dest = fold_rtx (dest, insn);
571718334Speter	}
571818334Speter
571918334Speter      /* Compute the hash code of the destination now,
572018334Speter	 before the effects of this instruction are recorded,
572118334Speter	 since the register values used in the address computation
572218334Speter	 are those before this instruction.  */
572318334Speter      sets[i].dest_hash = HASH (dest, mode);
572418334Speter
572518334Speter      /* Don't enter a bit-field in the hash table
572618334Speter	 because the value in it after the store
572718334Speter	 may not equal what was stored, due to truncation.  */
572818334Speter
572918334Speter      if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT
573018334Speter	  || GET_CODE (SET_DEST (sets[i].rtl)) == SIGN_EXTRACT)
573118334Speter	{
573218334Speter	  rtx width = XEXP (SET_DEST (sets[i].rtl), 1);
573318334Speter
573418334Speter	  if (src_const != 0 && GET_CODE (src_const) == CONST_INT
573518334Speter	      && GET_CODE (width) == CONST_INT
573618334Speter	      && INTVAL (width) < HOST_BITS_PER_WIDE_INT
573718334Speter	      && ! (INTVAL (src_const)
573818334Speter		    & ((HOST_WIDE_INT) (-1) << INTVAL (width))))
573918334Speter	    /* Exception: if the value is constant,
574018334Speter	       and it won't be truncated, record it.  */
574118334Speter	    ;
574218334Speter	  else
574318334Speter	    {
574418334Speter	      /* This is chosen so that the destination will be invalidated
574518334Speter		 but no new value will be recorded.
574618334Speter		 We must invalidate because sometimes constant
574718334Speter		 values can be recorded for bitfields.  */
574818334Speter	      sets[i].src_elt = 0;
574918334Speter	      sets[i].src_volatile = 1;
575018334Speter	      src_eqv = 0;
575118334Speter	      src_eqv_elt = 0;
575218334Speter	    }
575318334Speter	}
575418334Speter
575518334Speter      /* If only one set in a JUMP_INSN and it is now a no-op, we can delete
575618334Speter	 the insn.  */
575718334Speter      else if (n_sets == 1 && dest == pc_rtx && src == pc_rtx)
575818334Speter	{
575990075Sobrien	  /* One less use of the label this insn used to jump to.  */
576090075Sobrien	  delete_insn (insn);
576118334Speter	  cse_jumps_altered = 1;
576218334Speter	  /* No more processing for this set.  */
576318334Speter	  sets[i].rtl = 0;
576418334Speter	}
576518334Speter
576618334Speter      /* If this SET is now setting PC to a label, we know it used to
576790075Sobrien	 be a conditional or computed branch.  */
576818334Speter      else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF)
576918334Speter	{
577090075Sobrien	  /* Now emit a BARRIER after the unconditional jump.  */
577190075Sobrien	  if (NEXT_INSN (insn) == 0
577290075Sobrien	      || GET_CODE (NEXT_INSN (insn)) != BARRIER)
577390075Sobrien	    emit_barrier_after (insn);
577418334Speter
577590075Sobrien	  /* We reemit the jump in as many cases as possible just in
577690075Sobrien	     case the form of an unconditional jump is significantly
577790075Sobrien	     different than a computed jump or conditional jump.
577890075Sobrien
577990075Sobrien	     If this insn has multiple sets, then reemitting the
578090075Sobrien	     jump is nontrivial.  So instead we just force rerecognition
578190075Sobrien	     and hope for the best.  */
578290075Sobrien	  if (n_sets == 1)
578318334Speter	    {
578418334Speter	      rtx new = emit_jump_insn_before (gen_jump (XEXP (src, 0)), insn);
578590075Sobrien
578618334Speter	      JUMP_LABEL (new) = XEXP (src, 0);
578718334Speter	      LABEL_NUSES (XEXP (src, 0))++;
578818334Speter	      insn = new;
578990075Sobrien
579090075Sobrien	      /* Now emit a BARRIER after the unconditional jump.  */
579190075Sobrien	      if (NEXT_INSN (insn) == 0
579290075Sobrien		  || GET_CODE (NEXT_INSN (insn)) != BARRIER)
579390075Sobrien		emit_barrier_after (insn);
579418334Speter	    }
579518334Speter	  else
579618334Speter	    INSN_CODE (insn) = -1;
579718334Speter
579890075Sobrien	  never_reached_warning (insn);
579918334Speter
580090075Sobrien	  /* Do not bother deleting any unreachable code,
580190075Sobrien	     let jump/flow do that.  */
580290075Sobrien
580318334Speter	  cse_jumps_altered = 1;
580418334Speter	  sets[i].rtl = 0;
580518334Speter	}
580618334Speter
580718334Speter      /* If destination is volatile, invalidate it and then do no further
580818334Speter	 processing for this assignment.  */
580918334Speter
581018334Speter      else if (do_not_record)
581118334Speter	{
581290075Sobrien	  if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
581318334Speter	    invalidate (dest, VOIDmode);
581490075Sobrien	  else if (GET_CODE (dest) == MEM)
581590075Sobrien	    {
581690075Sobrien	      /* Outgoing arguments for a libcall don't
581790075Sobrien		 affect any recorded expressions.  */
581890075Sobrien	      if (! libcall_insn || insn == libcall_insn)
581990075Sobrien		invalidate (dest, VOIDmode);
582090075Sobrien	    }
582118334Speter	  else if (GET_CODE (dest) == STRICT_LOW_PART
582218334Speter		   || GET_CODE (dest) == ZERO_EXTRACT)
582318334Speter	    invalidate (XEXP (dest, 0), GET_MODE (dest));
582418334Speter	  sets[i].rtl = 0;
582518334Speter	}
582618334Speter
582718334Speter      if (sets[i].rtl != 0 && dest != SET_DEST (sets[i].rtl))
582818334Speter	sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode);
582918334Speter
583018334Speter#ifdef HAVE_cc0
583118334Speter      /* If setting CC0, record what it was set to, or a constant, if it
583218334Speter	 is equivalent to a constant.  If it is being set to a floating-point
583318334Speter	 value, make a COMPARE with the appropriate constant of 0.  If we
583418334Speter	 don't do this, later code can interpret this as a test against
583518334Speter	 const0_rtx, which can cause problems if we try to put it into an
583618334Speter	 insn as a floating-point operand.  */
583718334Speter      if (dest == cc0_rtx)
583818334Speter	{
583918334Speter	  this_insn_cc0 = src_const && mode != VOIDmode ? src_const : src;
584018334Speter	  this_insn_cc0_mode = mode;
584118334Speter	  if (FLOAT_MODE_P (mode))
584250397Sobrien	    this_insn_cc0 = gen_rtx_COMPARE (VOIDmode, this_insn_cc0,
584350397Sobrien					     CONST0_RTX (mode));
584418334Speter	}
584518334Speter#endif
584618334Speter    }
584718334Speter
584818334Speter  /* Now enter all non-volatile source expressions in the hash table
584918334Speter     if they are not already present.
585018334Speter     Record their equivalence classes in src_elt.
585118334Speter     This way we can insert the corresponding destinations into
585218334Speter     the same classes even if the actual sources are no longer in them
585318334Speter     (having been invalidated).  */
585418334Speter
585518334Speter  if (src_eqv && src_eqv_elt == 0 && sets[0].rtl != 0 && ! src_eqv_volatile
585618334Speter      && ! rtx_equal_p (src_eqv, SET_DEST (sets[0].rtl)))
585718334Speter    {
585890075Sobrien      struct table_elt *elt;
585990075Sobrien      struct table_elt *classp = sets[0].src_elt;
586018334Speter      rtx dest = SET_DEST (sets[0].rtl);
586118334Speter      enum machine_mode eqvmode = GET_MODE (dest);
586218334Speter
586318334Speter      if (GET_CODE (dest) == STRICT_LOW_PART)
586418334Speter	{
586518334Speter	  eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
586618334Speter	  classp = 0;
586718334Speter	}
586818334Speter      if (insert_regs (src_eqv, classp, 0))
586918334Speter	{
587018334Speter	  rehash_using_reg (src_eqv);
587118334Speter	  src_eqv_hash = HASH (src_eqv, eqvmode);
587218334Speter	}
587318334Speter      elt = insert (src_eqv, classp, src_eqv_hash, eqvmode);
587418334Speter      elt->in_memory = src_eqv_in_memory;
587518334Speter      src_eqv_elt = elt;
587618334Speter
587718334Speter      /* Check to see if src_eqv_elt is the same as a set source which
587818334Speter	 does not yet have an elt, and if so set the elt of the set source
587918334Speter	 to src_eqv_elt.  */
588018334Speter      for (i = 0; i < n_sets; i++)
588118334Speter	if (sets[i].rtl && sets[i].src_elt == 0
588218334Speter	    && rtx_equal_p (SET_SRC (sets[i].rtl), src_eqv))
588318334Speter	  sets[i].src_elt = src_eqv_elt;
588418334Speter    }
588518334Speter
588618334Speter  for (i = 0; i < n_sets; i++)
588718334Speter    if (sets[i].rtl && ! sets[i].src_volatile
588818334Speter	&& ! rtx_equal_p (SET_SRC (sets[i].rtl), SET_DEST (sets[i].rtl)))
588918334Speter      {
589018334Speter	if (GET_CODE (SET_DEST (sets[i].rtl)) == STRICT_LOW_PART)
589118334Speter	  {
589218334Speter	    /* REG_EQUAL in setting a STRICT_LOW_PART
589318334Speter	       gives an equivalent for the entire destination register,
589418334Speter	       not just for the subreg being stored in now.
589518334Speter	       This is a more interesting equivalence, so we arrange later
589618334Speter	       to treat the entire reg as the destination.  */
589718334Speter	    sets[i].src_elt = src_eqv_elt;
589818334Speter	    sets[i].src_hash = src_eqv_hash;
589918334Speter	  }
590018334Speter	else
590118334Speter	  {
590218334Speter	    /* Insert source and constant equivalent into hash table, if not
590318334Speter	       already present.  */
590490075Sobrien	    struct table_elt *classp = src_eqv_elt;
590590075Sobrien	    rtx src = sets[i].src;
590690075Sobrien	    rtx dest = SET_DEST (sets[i].rtl);
590718334Speter	    enum machine_mode mode
590818334Speter	      = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src);
590918334Speter
591090075Sobrien	    if (sets[i].src_elt == 0)
591118334Speter	      {
591290075Sobrien		/* Don't put a hard register source into the table if this is
591390075Sobrien		   the last insn of a libcall.  In this case, we only need
591490075Sobrien		   to put src_eqv_elt in src_elt.  */
591590075Sobrien		if (! find_reg_note (insn, REG_RETVAL, NULL_RTX))
591690075Sobrien		  {
591790075Sobrien		    struct table_elt *elt;
591818334Speter
591990075Sobrien		    /* Note that these insert_regs calls cannot remove
592090075Sobrien		       any of the src_elt's, because they would have failed to
592190075Sobrien		       match if not still valid.  */
592290075Sobrien		    if (insert_regs (src, classp, 0))
592390075Sobrien		      {
592490075Sobrien			rehash_using_reg (src);
592590075Sobrien			sets[i].src_hash = HASH (src, mode);
592690075Sobrien		      }
592790075Sobrien		    elt = insert (src, classp, sets[i].src_hash, mode);
592890075Sobrien		    elt->in_memory = sets[i].src_in_memory;
592990075Sobrien		    sets[i].src_elt = classp = elt;
593018334Speter		  }
593190075Sobrien		else
593290075Sobrien		  sets[i].src_elt = classp;
593318334Speter	      }
593418334Speter	    if (sets[i].src_const && sets[i].src_const_elt == 0
593518334Speter		&& src != sets[i].src_const
593618334Speter		&& ! rtx_equal_p (sets[i].src_const, src))
593718334Speter	      sets[i].src_elt = insert (sets[i].src_const, classp,
593818334Speter					sets[i].src_const_hash, mode);
593918334Speter	  }
594018334Speter      }
594118334Speter    else if (sets[i].src_elt == 0)
594218334Speter      /* If we did not insert the source into the hash table (e.g., it was
594318334Speter	 volatile), note the equivalence class for the REG_EQUAL value, if any,
594418334Speter	 so that the destination goes into that class.  */
594518334Speter      sets[i].src_elt = src_eqv_elt;
594618334Speter
594750397Sobrien  invalidate_from_clobbers (x);
594818334Speter
594990075Sobrien  /* Some registers are invalidated by subroutine calls.  Memory is
595018334Speter     invalidated by non-constant calls.  */
595118334Speter
595218334Speter  if (GET_CODE (insn) == CALL_INSN)
595318334Speter    {
595490075Sobrien      if (! CONST_OR_PURE_CALL_P (insn))
595550397Sobrien	invalidate_memory ();
595618334Speter      invalidate_for_call ();
595718334Speter    }
595818334Speter
595918334Speter  /* Now invalidate everything set by this instruction.
596018334Speter     If a SUBREG or other funny destination is being set,
596118334Speter     sets[i].rtl is still nonzero, so here we invalidate the reg
596218334Speter     a part of which is being set.  */
596318334Speter
596418334Speter  for (i = 0; i < n_sets; i++)
596518334Speter    if (sets[i].rtl)
596618334Speter      {
596718334Speter	/* We can't use the inner dest, because the mode associated with
596818334Speter	   a ZERO_EXTRACT is significant.  */
596990075Sobrien	rtx dest = SET_DEST (sets[i].rtl);
597018334Speter
597118334Speter	/* Needed for registers to remove the register from its
597218334Speter	   previous quantity's chain.
597318334Speter	   Needed for memory if this is a nonvarying address, unless
597418334Speter	   we have just done an invalidate_memory that covers even those.  */
597590075Sobrien	if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
597618334Speter	  invalidate (dest, VOIDmode);
597790075Sobrien	else if (GET_CODE (dest) == MEM)
597890075Sobrien	  {
597990075Sobrien	    /* Outgoing arguments for a libcall don't
598090075Sobrien	       affect any recorded expressions.  */
598190075Sobrien	    if (! libcall_insn || insn == libcall_insn)
598290075Sobrien	      invalidate (dest, VOIDmode);
598390075Sobrien	  }
598418334Speter	else if (GET_CODE (dest) == STRICT_LOW_PART
598518334Speter		 || GET_CODE (dest) == ZERO_EXTRACT)
598618334Speter	  invalidate (XEXP (dest, 0), GET_MODE (dest));
598718334Speter      }
598818334Speter
598952284Sobrien  /* A volatile ASM invalidates everything.  */
599052284Sobrien  if (GET_CODE (insn) == INSN
599152284Sobrien      && GET_CODE (PATTERN (insn)) == ASM_OPERANDS
599252284Sobrien      && MEM_VOLATILE_P (PATTERN (insn)))
599352284Sobrien    flush_hash_table ();
599452284Sobrien
599518334Speter  /* Make sure registers mentioned in destinations
599618334Speter     are safe for use in an expression to be inserted.
599718334Speter     This removes from the hash table
599818334Speter     any invalid entry that refers to one of these registers.
599918334Speter
600018334Speter     We don't care about the return value from mention_regs because
600118334Speter     we are going to hash the SET_DEST values unconditionally.  */
600218334Speter
600318334Speter  for (i = 0; i < n_sets; i++)
600452284Sobrien    {
600552284Sobrien      if (sets[i].rtl)
600652284Sobrien	{
600752284Sobrien	  rtx x = SET_DEST (sets[i].rtl);
600818334Speter
600952284Sobrien	  if (GET_CODE (x) != REG)
601052284Sobrien	    mention_regs (x);
601152284Sobrien	  else
601252284Sobrien	    {
601352284Sobrien	      /* We used to rely on all references to a register becoming
601452284Sobrien		 inaccessible when a register changes to a new quantity,
601552284Sobrien		 since that changes the hash code.  However, that is not
601690075Sobrien		 safe, since after HASH_SIZE new quantities we get a
601752284Sobrien		 hash 'collision' of a register with its own invalid
601852284Sobrien		 entries.  And since SUBREGs have been changed not to
601952284Sobrien		 change their hash code with the hash code of the register,
602052284Sobrien		 it wouldn't work any longer at all.  So we have to check
602152284Sobrien		 for any invalid references lying around now.
602252284Sobrien		 This code is similar to the REG case in mention_regs,
602352284Sobrien		 but it knows that reg_tick has been incremented, and
602452284Sobrien		 it leaves reg_in_table as -1 .  */
602590075Sobrien	      unsigned int regno = REGNO (x);
602690075Sobrien	      unsigned int endregno
602752284Sobrien		= regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
602852284Sobrien			   : HARD_REGNO_NREGS (regno, GET_MODE (x)));
602990075Sobrien	      unsigned int i;
603052284Sobrien
603152284Sobrien	      for (i = regno; i < endregno; i++)
603252284Sobrien		{
603352284Sobrien		  if (REG_IN_TABLE (i) >= 0)
603452284Sobrien		    {
603552284Sobrien		      remove_invalid_refs (i);
603652284Sobrien		      REG_IN_TABLE (i) = -1;
603752284Sobrien		    }
603852284Sobrien		}
603952284Sobrien	    }
604052284Sobrien	}
604152284Sobrien    }
604252284Sobrien
604318334Speter  /* We may have just removed some of the src_elt's from the hash table.
604418334Speter     So replace each one with the current head of the same class.  */
604518334Speter
604618334Speter  for (i = 0; i < n_sets; i++)
604718334Speter    if (sets[i].rtl)
604818334Speter      {
604918334Speter	if (sets[i].src_elt && sets[i].src_elt->first_same_value == 0)
605018334Speter	  /* If elt was removed, find current head of same class,
605118334Speter	     or 0 if nothing remains of that class.  */
605218334Speter	  {
605390075Sobrien	    struct table_elt *elt = sets[i].src_elt;
605418334Speter
605518334Speter	    while (elt && elt->prev_same_value)
605618334Speter	      elt = elt->prev_same_value;
605718334Speter
605818334Speter	    while (elt && elt->first_same_value == 0)
605918334Speter	      elt = elt->next_same_value;
606018334Speter	    sets[i].src_elt = elt ? elt->first_same_value : 0;
606118334Speter	  }
606218334Speter      }
606318334Speter
606418334Speter  /* Now insert the destinations into their equivalence classes.  */
606518334Speter
606618334Speter  for (i = 0; i < n_sets; i++)
606718334Speter    if (sets[i].rtl)
606818334Speter      {
606990075Sobrien	rtx dest = SET_DEST (sets[i].rtl);
607050397Sobrien	rtx inner_dest = sets[i].inner_dest;
607190075Sobrien	struct table_elt *elt;
607218334Speter
607318334Speter	/* Don't record value if we are not supposed to risk allocating
607418334Speter	   floating-point values in registers that might be wider than
607518334Speter	   memory.  */
607618334Speter	if ((flag_float_store
607718334Speter	     && GET_CODE (dest) == MEM
607818334Speter	     && FLOAT_MODE_P (GET_MODE (dest)))
607950397Sobrien	    /* Don't record BLKmode values, because we don't know the
608050397Sobrien	       size of it, and can't be sure that other BLKmode values
608150397Sobrien	       have the same or smaller size.  */
608250397Sobrien	    || GET_MODE (dest) == BLKmode
608318334Speter	    /* Don't record values of destinations set inside a libcall block
608418334Speter	       since we might delete the libcall.  Things should have been set
608518334Speter	       up so we won't want to reuse such a value, but we play it safe
608618334Speter	       here.  */
608750397Sobrien	    || libcall_insn
608818334Speter	    /* If we didn't put a REG_EQUAL value or a source into the hash
608918334Speter	       table, there is no point is recording DEST.  */
609018334Speter	    || sets[i].src_elt == 0
609118334Speter	    /* If DEST is a paradoxical SUBREG and SRC is a ZERO_EXTEND
609218334Speter	       or SIGN_EXTEND, don't record DEST since it can cause
609318334Speter	       some tracking to be wrong.
609418334Speter
609518334Speter	       ??? Think about this more later.  */
609618334Speter	    || (GET_CODE (dest) == SUBREG
609718334Speter		&& (GET_MODE_SIZE (GET_MODE (dest))
609818334Speter		    > GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))))
609918334Speter		&& (GET_CODE (sets[i].src) == SIGN_EXTEND
610018334Speter		    || GET_CODE (sets[i].src) == ZERO_EXTEND)))
610118334Speter	  continue;
610218334Speter
610318334Speter	/* STRICT_LOW_PART isn't part of the value BEING set,
610418334Speter	   and neither is the SUBREG inside it.
610518334Speter	   Note that in this case SETS[I].SRC_ELT is really SRC_EQV_ELT.  */
610618334Speter	if (GET_CODE (dest) == STRICT_LOW_PART)
610718334Speter	  dest = SUBREG_REG (XEXP (dest, 0));
610818334Speter
610918334Speter	if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
611018334Speter	  /* Registers must also be inserted into chains for quantities.  */
611118334Speter	  if (insert_regs (dest, sets[i].src_elt, 1))
611218334Speter	    {
611318334Speter	      /* If `insert_regs' changes something, the hash code must be
611418334Speter		 recalculated.  */
611518334Speter	      rehash_using_reg (dest);
611618334Speter	      sets[i].dest_hash = HASH (dest, GET_MODE (dest));
611718334Speter	    }
611818334Speter
611950397Sobrien	if (GET_CODE (inner_dest) == MEM
612050397Sobrien	    && GET_CODE (XEXP (inner_dest, 0)) == ADDRESSOF)
612150397Sobrien	  /* Given (SET (MEM (ADDRESSOF (X))) Y) we don't want to say
612290075Sobrien	     that (MEM (ADDRESSOF (X))) is equivalent to Y.
612350397Sobrien	     Consider the case in which the address of the MEM is
612450397Sobrien	     passed to a function, which alters the MEM.  Then, if we
612550397Sobrien	     later use Y instead of the MEM we'll miss the update.  */
612650397Sobrien	  elt = insert (dest, 0, sets[i].dest_hash, GET_MODE (dest));
612750397Sobrien	else
612850397Sobrien	  elt = insert (dest, sets[i].src_elt,
612950397Sobrien			sets[i].dest_hash, GET_MODE (dest));
613050397Sobrien
613118334Speter	elt->in_memory = (GET_CODE (sets[i].inner_dest) == MEM
613250397Sobrien			  && (! RTX_UNCHANGING_P (sets[i].inner_dest)
613350397Sobrien			      || FIXED_BASE_PLUS_P (XEXP (sets[i].inner_dest,
613450397Sobrien							  0))));
613518334Speter
613618334Speter	/* If we have (set (subreg:m1 (reg:m2 foo) 0) (bar:m1)), M1 is no
613718334Speter	   narrower than M2, and both M1 and M2 are the same number of words,
613818334Speter	   we are also doing (set (reg:m2 foo) (subreg:m2 (bar:m1) 0)) so
613918334Speter	   make that equivalence as well.
614018334Speter
614118334Speter	   However, BAR may have equivalences for which gen_lowpart_if_possible
614218334Speter	   will produce a simpler value than gen_lowpart_if_possible applied to
614318334Speter	   BAR (e.g., if BAR was ZERO_EXTENDed from M2), so we will scan all
614490075Sobrien	   BAR's equivalences.  If we don't get a simplified form, make
614518334Speter	   the SUBREG.  It will not be used in an equivalence, but will
614618334Speter	   cause two similar assignments to be detected.
614718334Speter
614818334Speter	   Note the loop below will find SUBREG_REG (DEST) since we have
614918334Speter	   already entered SRC and DEST of the SET in the table.  */
615018334Speter
615118334Speter	if (GET_CODE (dest) == SUBREG
615218334Speter	    && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) - 1)
615318334Speter		 / UNITS_PER_WORD)
615490075Sobrien		== (GET_MODE_SIZE (GET_MODE (dest)) - 1) / UNITS_PER_WORD)
615518334Speter	    && (GET_MODE_SIZE (GET_MODE (dest))
615618334Speter		>= GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))))
615718334Speter	    && sets[i].src_elt != 0)
615818334Speter	  {
615918334Speter	    enum machine_mode new_mode = GET_MODE (SUBREG_REG (dest));
616018334Speter	    struct table_elt *elt, *classp = 0;
616118334Speter
616218334Speter	    for (elt = sets[i].src_elt->first_same_value; elt;
616318334Speter		 elt = elt->next_same_value)
616418334Speter	      {
616518334Speter		rtx new_src = 0;
616618334Speter		unsigned src_hash;
616718334Speter		struct table_elt *src_elt;
616818334Speter
616918334Speter		/* Ignore invalid entries.  */
617018334Speter		if (GET_CODE (elt->exp) != REG
617118334Speter		    && ! exp_equiv_p (elt->exp, elt->exp, 1, 0))
617218334Speter		  continue;
617318334Speter
617418334Speter		new_src = gen_lowpart_if_possible (new_mode, elt->exp);
617518334Speter		if (new_src == 0)
617650397Sobrien		  new_src = gen_rtx_SUBREG (new_mode, elt->exp, 0);
617718334Speter
617818334Speter		src_hash = HASH (new_src, new_mode);
617918334Speter		src_elt = lookup (new_src, src_hash, new_mode);
618018334Speter
618118334Speter		/* Put the new source in the hash table is if isn't
618218334Speter		   already.  */
618318334Speter		if (src_elt == 0)
618418334Speter		  {
618518334Speter		    if (insert_regs (new_src, classp, 0))
618618334Speter		      {
618718334Speter			rehash_using_reg (new_src);
618818334Speter			src_hash = HASH (new_src, new_mode);
618918334Speter		      }
619018334Speter		    src_elt = insert (new_src, classp, src_hash, new_mode);
619118334Speter		    src_elt->in_memory = elt->in_memory;
619218334Speter		  }
619318334Speter		else if (classp && classp != src_elt->first_same_value)
619490075Sobrien		  /* Show that two things that we've seen before are
619518334Speter		     actually the same.  */
619618334Speter		  merge_equiv_classes (src_elt, classp);
619718334Speter
619818334Speter		classp = src_elt->first_same_value;
619950397Sobrien		/* Ignore invalid entries.  */
620050397Sobrien		while (classp
620150397Sobrien		       && GET_CODE (classp->exp) != REG
620250397Sobrien		       && ! exp_equiv_p (classp->exp, classp->exp, 1, 0))
620350397Sobrien		  classp = classp->next_same_value;
620418334Speter	      }
620518334Speter	  }
620618334Speter      }
620718334Speter
620890075Sobrien  /* Special handling for (set REG0 REG1) where REG0 is the
620990075Sobrien     "cheapest", cheaper than REG1.  After cse, REG1 will probably not
621090075Sobrien     be used in the sequel, so (if easily done) change this insn to
621190075Sobrien     (set REG1 REG0) and replace REG1 with REG0 in the previous insn
621290075Sobrien     that computed their value.  Then REG1 will become a dead store
621390075Sobrien     and won't cloud the situation for later optimizations.
621418334Speter
621518334Speter     Do not make this change if REG1 is a hard register, because it will
621618334Speter     then be used in the sequel and we may be changing a two-operand insn
621718334Speter     into a three-operand insn.
621818334Speter
621952284Sobrien     Also do not do this if we are operating on a copy of INSN.
622018334Speter
622152284Sobrien     Also don't do this if INSN ends a libcall; this would cause an unrelated
622252284Sobrien     register to be set in the middle of a libcall, and we then get bad code
622352284Sobrien     if the libcall is deleted.  */
622452284Sobrien
622518334Speter  if (n_sets == 1 && sets[0].rtl && GET_CODE (SET_DEST (sets[0].rtl)) == REG
622618334Speter      && NEXT_INSN (PREV_INSN (insn)) == insn
622718334Speter      && GET_CODE (SET_SRC (sets[0].rtl)) == REG
622818334Speter      && REGNO (SET_SRC (sets[0].rtl)) >= FIRST_PSEUDO_REGISTER
622990075Sobrien      && REGNO_QTY_VALID_P (REGNO (SET_SRC (sets[0].rtl))))
623018334Speter    {
623190075Sobrien      int src_q = REG_QTY (REGNO (SET_SRC (sets[0].rtl)));
623290075Sobrien      struct qty_table_elem *src_ent = &qty_table[src_q];
623318334Speter
623490075Sobrien      if ((src_ent->first_reg == REGNO (SET_DEST (sets[0].rtl)))
623590075Sobrien	  && ! find_reg_note (insn, REG_RETVAL, NULL_RTX))
623618334Speter	{
623790075Sobrien	  rtx prev = prev_nonnote_insn (insn);
623818334Speter
623990075Sobrien	  /* Do not swap the registers around if the previous instruction
624090075Sobrien	     attaches a REG_EQUIV note to REG1.
624118334Speter
624290075Sobrien	     ??? It's not entirely clear whether we can transfer a REG_EQUIV
624390075Sobrien	     from the pseudo that originally shadowed an incoming argument
624490075Sobrien	     to another register.  Some uses of REG_EQUIV might rely on it
624590075Sobrien	     being attached to REG1 rather than REG2.
624618334Speter
624790075Sobrien	     This section previously turned the REG_EQUIV into a REG_EQUAL
624890075Sobrien	     note.  We cannot do that because REG_EQUIV may provide an
624990075Sobrien	     uninitialised stack slot when REG_PARM_STACK_SPACE is used.  */
625018334Speter
625190075Sobrien	  if (prev != 0 && GET_CODE (prev) == INSN
625290075Sobrien	      && GET_CODE (PATTERN (prev)) == SET
625390075Sobrien	      && SET_DEST (PATTERN (prev)) == SET_SRC (sets[0].rtl)
625490075Sobrien	      && ! find_reg_note (prev, REG_EQUIV, NULL_RTX))
625518334Speter	    {
625690075Sobrien	      rtx dest = SET_DEST (sets[0].rtl);
625790075Sobrien	      rtx src = SET_SRC (sets[0].rtl);
625890075Sobrien	      rtx note;
625990075Sobrien
626090075Sobrien	      validate_change (prev, &SET_DEST (PATTERN (prev)), dest, 1);
626190075Sobrien	      validate_change (insn, &SET_DEST (sets[0].rtl), src, 1);
626290075Sobrien	      validate_change (insn, &SET_SRC (sets[0].rtl), dest, 1);
626390075Sobrien	      apply_change_group ();
626490075Sobrien
626590075Sobrien	      /* If there was a REG_WAS_0 note on PREV, remove it.  Move
626690075Sobrien		 any REG_WAS_0 note on INSN to PREV.  */
626790075Sobrien	      note = find_reg_note (prev, REG_WAS_0, NULL_RTX);
626890075Sobrien	      if (note)
626990075Sobrien		remove_note (prev, note);
627090075Sobrien
627190075Sobrien	      note = find_reg_note (insn, REG_WAS_0, NULL_RTX);
627290075Sobrien	      if (note)
627390075Sobrien		{
627490075Sobrien		  remove_note (insn, note);
627590075Sobrien		  XEXP (note, 1) = REG_NOTES (prev);
627690075Sobrien		  REG_NOTES (prev) = note;
627790075Sobrien		}
627890075Sobrien
627990075Sobrien	      /* If INSN has a REG_EQUAL note, and this note mentions
628090075Sobrien		 REG0, then we must delete it, because the value in
628190075Sobrien		 REG0 has changed.  If the note's value is REG1, we must
628290075Sobrien		 also delete it because that is now this insn's dest.  */
628390075Sobrien	      note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
628490075Sobrien	      if (note != 0
628590075Sobrien		  && (reg_mentioned_p (dest, XEXP (note, 0))
628690075Sobrien		      || rtx_equal_p (src, XEXP (note, 0))))
628790075Sobrien		remove_note (insn, note);
628818334Speter	    }
628918334Speter	}
629018334Speter    }
629118334Speter
629218334Speter  /* If this is a conditional jump insn, record any known equivalences due to
629318334Speter     the condition being tested.  */
629418334Speter
629518334Speter  last_jump_equiv_class = 0;
629618334Speter  if (GET_CODE (insn) == JUMP_INSN
629718334Speter      && n_sets == 1 && GET_CODE (x) == SET
629818334Speter      && GET_CODE (SET_SRC (x)) == IF_THEN_ELSE)
629918334Speter    record_jump_equiv (insn, 0);
630018334Speter
630118334Speter#ifdef HAVE_cc0
630218334Speter  /* If the previous insn set CC0 and this insn no longer references CC0,
630318334Speter     delete the previous insn.  Here we use the fact that nothing expects CC0
630418334Speter     to be valid over an insn, which is true until the final pass.  */
630518334Speter  if (prev_insn && GET_CODE (prev_insn) == INSN
630618334Speter      && (tem = single_set (prev_insn)) != 0
630718334Speter      && SET_DEST (tem) == cc0_rtx
630818334Speter      && ! reg_mentioned_p (cc0_rtx, x))
630990075Sobrien    delete_insn (prev_insn);
631018334Speter
631118334Speter  prev_insn_cc0 = this_insn_cc0;
631218334Speter  prev_insn_cc0_mode = this_insn_cc0_mode;
631318334Speter#endif
631418334Speter
631518334Speter  prev_insn = insn;
631618334Speter}
631718334Speter
631852284Sobrien/* Remove from the hash table all expressions that reference memory.  */
631990075Sobrien
632018334Speterstatic void
632150397Sobrieninvalidate_memory ()
632218334Speter{
632390075Sobrien  int i;
632490075Sobrien  struct table_elt *p, *next;
632518334Speter
632690075Sobrien  for (i = 0; i < HASH_SIZE; i++)
632750397Sobrien    for (p = table[i]; p; p = next)
632850397Sobrien      {
632950397Sobrien	next = p->next_same_hash;
633050397Sobrien	if (p->in_memory)
633150397Sobrien	  remove_from_table (p, i);
633250397Sobrien      }
633350397Sobrien}
633450397Sobrien
633590075Sobrien/* If ADDR is an address that implicitly affects the stack pointer, return
633690075Sobrien   1 and update the register tables to show the effect.  Else, return 0.  */
633790075Sobrien
633850397Sobrienstatic int
633990075Sobrienaddr_affects_sp_p (addr)
634090075Sobrien     rtx addr;
634150397Sobrien{
634290075Sobrien  if (GET_RTX_CLASS (GET_CODE (addr)) == 'a'
634350397Sobrien      && GET_CODE (XEXP (addr, 0)) == REG
634450397Sobrien      && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
634518334Speter    {
634652284Sobrien      if (REG_TICK (STACK_POINTER_REGNUM) >= 0)
634752284Sobrien	REG_TICK (STACK_POINTER_REGNUM)++;
634850397Sobrien
634950397Sobrien      /* This should be *very* rare.  */
635050397Sobrien      if (TEST_HARD_REG_BIT (hard_regs_in_table, STACK_POINTER_REGNUM))
635150397Sobrien	invalidate (stack_pointer_rtx, VOIDmode);
635290075Sobrien
635350397Sobrien      return 1;
635418334Speter    }
635590075Sobrien
635650397Sobrien  return 0;
635718334Speter}
635818334Speter
635918334Speter/* Perform invalidation on the basis of everything about an insn
636018334Speter   except for invalidating the actual places that are SET in it.
636118334Speter   This includes the places CLOBBERed, and anything that might
636218334Speter   alias with something that is SET or CLOBBERed.
636318334Speter
636418334Speter   X is the pattern of the insn.  */
636518334Speter
636618334Speterstatic void
636750397Sobrieninvalidate_from_clobbers (x)
636818334Speter     rtx x;
636918334Speter{
637018334Speter  if (GET_CODE (x) == CLOBBER)
637118334Speter    {
637218334Speter      rtx ref = XEXP (x, 0);
637318334Speter      if (ref)
637418334Speter	{
637518334Speter	  if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
637650397Sobrien	      || GET_CODE (ref) == MEM)
637718334Speter	    invalidate (ref, VOIDmode);
637818334Speter	  else if (GET_CODE (ref) == STRICT_LOW_PART
637918334Speter		   || GET_CODE (ref) == ZERO_EXTRACT)
638018334Speter	    invalidate (XEXP (ref, 0), GET_MODE (ref));
638118334Speter	}
638218334Speter    }
638318334Speter  else if (GET_CODE (x) == PARALLEL)
638418334Speter    {
638590075Sobrien      int i;
638618334Speter      for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
638718334Speter	{
638890075Sobrien	  rtx y = XVECEXP (x, 0, i);
638918334Speter	  if (GET_CODE (y) == CLOBBER)
639018334Speter	    {
639118334Speter	      rtx ref = XEXP (y, 0);
639250397Sobrien	      if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
639350397Sobrien		  || GET_CODE (ref) == MEM)
639450397Sobrien		invalidate (ref, VOIDmode);
639550397Sobrien	      else if (GET_CODE (ref) == STRICT_LOW_PART
639650397Sobrien		       || GET_CODE (ref) == ZERO_EXTRACT)
639750397Sobrien		invalidate (XEXP (ref, 0), GET_MODE (ref));
639818334Speter	    }
639918334Speter	}
640018334Speter    }
640118334Speter}
640218334Speter
640318334Speter/* Process X, part of the REG_NOTES of an insn.  Look at any REG_EQUAL notes
640418334Speter   and replace any registers in them with either an equivalent constant
640518334Speter   or the canonical form of the register.  If we are inside an address,
640618334Speter   only do this if the address remains valid.
640718334Speter
640818334Speter   OBJECT is 0 except when within a MEM in which case it is the MEM.
640918334Speter
641018334Speter   Return the replacement for X.  */
641118334Speter
641218334Speterstatic rtx
641318334Spetercse_process_notes (x, object)
641418334Speter     rtx x;
641518334Speter     rtx object;
641618334Speter{
641718334Speter  enum rtx_code code = GET_CODE (x);
641890075Sobrien  const char *fmt = GET_RTX_FORMAT (code);
641918334Speter  int i;
642018334Speter
642118334Speter  switch (code)
642218334Speter    {
642318334Speter    case CONST_INT:
642418334Speter    case CONST:
642518334Speter    case SYMBOL_REF:
642618334Speter    case LABEL_REF:
642718334Speter    case CONST_DOUBLE:
642818334Speter    case PC:
642918334Speter    case CC0:
643018334Speter    case LO_SUM:
643118334Speter      return x;
643218334Speter
643318334Speter    case MEM:
643490075Sobrien      validate_change (x, &XEXP (x, 0),
643590075Sobrien		       cse_process_notes (XEXP (x, 0), x), 0);
643618334Speter      return x;
643718334Speter
643818334Speter    case EXPR_LIST:
643918334Speter    case INSN_LIST:
644018334Speter      if (REG_NOTE_KIND (x) == REG_EQUAL)
644118334Speter	XEXP (x, 0) = cse_process_notes (XEXP (x, 0), NULL_RTX);
644218334Speter      if (XEXP (x, 1))
644318334Speter	XEXP (x, 1) = cse_process_notes (XEXP (x, 1), NULL_RTX);
644418334Speter      return x;
644518334Speter
644618334Speter    case SIGN_EXTEND:
644718334Speter    case ZERO_EXTEND:
644850397Sobrien    case SUBREG:
644918334Speter      {
645018334Speter	rtx new = cse_process_notes (XEXP (x, 0), object);
645118334Speter	/* We don't substitute VOIDmode constants into these rtx,
645218334Speter	   since they would impede folding.  */
645318334Speter	if (GET_MODE (new) != VOIDmode)
645418334Speter	  validate_change (object, &XEXP (x, 0), new, 0);
645518334Speter	return x;
645618334Speter      }
645718334Speter
645818334Speter    case REG:
645952284Sobrien      i = REG_QTY (REGNO (x));
646018334Speter
646118334Speter      /* Return a constant or a constant register.  */
646290075Sobrien      if (REGNO_QTY_VALID_P (REGNO (x)))
646318334Speter	{
646490075Sobrien	  struct qty_table_elem *ent = &qty_table[i];
646590075Sobrien
646690075Sobrien	  if (ent->const_rtx != NULL_RTX
646790075Sobrien	      && (CONSTANT_P (ent->const_rtx)
646890075Sobrien		  || GET_CODE (ent->const_rtx) == REG))
646990075Sobrien	    {
647090075Sobrien	      rtx new = gen_lowpart_if_possible (GET_MODE (x), ent->const_rtx);
647190075Sobrien	      if (new)
647290075Sobrien		return new;
647390075Sobrien	    }
647418334Speter	}
647518334Speter
647618334Speter      /* Otherwise, canonicalize this register.  */
647718334Speter      return canon_reg (x, NULL_RTX);
647890075Sobrien
647950397Sobrien    default:
648050397Sobrien      break;
648118334Speter    }
648218334Speter
648318334Speter  for (i = 0; i < GET_RTX_LENGTH (code); i++)
648418334Speter    if (fmt[i] == 'e')
648518334Speter      validate_change (object, &XEXP (x, i),
648618334Speter		       cse_process_notes (XEXP (x, i), object), 0);
648718334Speter
648818334Speter  return x;
648918334Speter}
649018334Speter
649118334Speter/* Find common subexpressions between the end test of a loop and the beginning
649218334Speter   of the loop.  LOOP_START is the CODE_LABEL at the start of a loop.
649318334Speter
649418334Speter   Often we have a loop where an expression in the exit test is used
649518334Speter   in the body of the loop.  For example "while (*p) *q++ = *p++;".
649618334Speter   Because of the way we duplicate the loop exit test in front of the loop,
649718334Speter   however, we don't detect that common subexpression.  This will be caught
649818334Speter   when global cse is implemented, but this is a quite common case.
649918334Speter
650018334Speter   This function handles the most common cases of these common expressions.
650118334Speter   It is called after we have processed the basic block ending with the
650218334Speter   NOTE_INSN_LOOP_END note that ends a loop and the previous JUMP_INSN
650318334Speter   jumps to a label used only once.  */
650418334Speter
650518334Speterstatic void
650618334Spetercse_around_loop (loop_start)
650718334Speter     rtx loop_start;
650818334Speter{
650918334Speter  rtx insn;
651018334Speter  int i;
651118334Speter  struct table_elt *p;
651218334Speter
651318334Speter  /* If the jump at the end of the loop doesn't go to the start, we don't
651418334Speter     do anything.  */
651518334Speter  for (insn = PREV_INSN (loop_start);
651618334Speter       insn && (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) >= 0);
651718334Speter       insn = PREV_INSN (insn))
651818334Speter    ;
651918334Speter
652018334Speter  if (insn == 0
652118334Speter      || GET_CODE (insn) != NOTE
652218334Speter      || NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG)
652318334Speter    return;
652418334Speter
652518334Speter  /* If the last insn of the loop (the end test) was an NE comparison,
652618334Speter     we will interpret it as an EQ comparison, since we fell through
652718334Speter     the loop.  Any equivalences resulting from that comparison are
652818334Speter     therefore not valid and must be invalidated.  */
652918334Speter  if (last_jump_equiv_class)
653018334Speter    for (p = last_jump_equiv_class->first_same_value; p;
653118334Speter	 p = p->next_same_value)
653250397Sobrien      {
653390075Sobrien	if (GET_CODE (p->exp) == MEM || GET_CODE (p->exp) == REG
653450397Sobrien	    || (GET_CODE (p->exp) == SUBREG
653590075Sobrien		&& GET_CODE (SUBREG_REG (p->exp)) == REG))
653650397Sobrien	  invalidate (p->exp, VOIDmode);
653790075Sobrien	else if (GET_CODE (p->exp) == STRICT_LOW_PART
653890075Sobrien		 || GET_CODE (p->exp) == ZERO_EXTRACT)
653950397Sobrien	  invalidate (XEXP (p->exp, 0), GET_MODE (p->exp));
654050397Sobrien      }
654118334Speter
654218334Speter  /* Process insns starting after LOOP_START until we hit a CALL_INSN or
654318334Speter     a CODE_LABEL (we could handle a CALL_INSN, but it isn't worth it).
654418334Speter
654518334Speter     The only thing we do with SET_DEST is invalidate entries, so we
654618334Speter     can safely process each SET in order.  It is slightly less efficient
654750397Sobrien     to do so, but we only want to handle the most common cases.
654818334Speter
654950397Sobrien     The gen_move_insn call in cse_set_around_loop may create new pseudos.
655050397Sobrien     These pseudos won't have valid entries in any of the tables indexed
655150397Sobrien     by register number, such as reg_qty.  We avoid out-of-range array
655250397Sobrien     accesses by not processing any instructions created after cse started.  */
655350397Sobrien
655418334Speter  for (insn = NEXT_INSN (loop_start);
655518334Speter       GET_CODE (insn) != CALL_INSN && GET_CODE (insn) != CODE_LABEL
655650397Sobrien       && INSN_UID (insn) < max_insn_uid
655718334Speter       && ! (GET_CODE (insn) == NOTE
655818334Speter	     && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END);
655918334Speter       insn = NEXT_INSN (insn))
656018334Speter    {
656190075Sobrien      if (INSN_P (insn)
656218334Speter	  && (GET_CODE (PATTERN (insn)) == SET
656318334Speter	      || GET_CODE (PATTERN (insn)) == CLOBBER))
656418334Speter	cse_set_around_loop (PATTERN (insn), insn, loop_start);
656590075Sobrien      else if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == PARALLEL)
656618334Speter	for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
656718334Speter	  if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
656818334Speter	      || GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == CLOBBER)
656918334Speter	    cse_set_around_loop (XVECEXP (PATTERN (insn), 0, i), insn,
657018334Speter				 loop_start);
657118334Speter    }
657218334Speter}
657318334Speter
657418334Speter/* Process one SET of an insn that was skipped.  We ignore CLOBBERs
657518334Speter   since they are done elsewhere.  This function is called via note_stores.  */
657618334Speter
657718334Speterstatic void
657890075Sobrieninvalidate_skipped_set (dest, set, data)
657918334Speter     rtx set;
658018334Speter     rtx dest;
658190075Sobrien     void *data ATTRIBUTE_UNUSED;
658218334Speter{
658350397Sobrien  enum rtx_code code = GET_CODE (dest);
658418334Speter
658550397Sobrien  if (code == MEM
658690075Sobrien      && ! addr_affects_sp_p (dest)	/* If this is not a stack push ...  */
658750397Sobrien      /* There are times when an address can appear varying and be a PLUS
658850397Sobrien	 during this scan when it would be a fixed address were we to know
658950397Sobrien	 the proper equivalences.  So invalidate all memory if there is
659050397Sobrien	 a BLKmode or nonscalar memory reference or a reference to a
659150397Sobrien	 variable address.  */
659250397Sobrien      && (MEM_IN_STRUCT_P (dest) || GET_MODE (dest) == BLKmode
659390075Sobrien	  || cse_rtx_varies_p (XEXP (dest, 0), 0)))
659450397Sobrien    {
659550397Sobrien      invalidate_memory ();
659650397Sobrien      return;
659750397Sobrien    }
659818334Speter
659948743Sobrien  if (GET_CODE (set) == CLOBBER
660048743Sobrien#ifdef HAVE_cc0
660148743Sobrien      || dest == cc0_rtx
660248743Sobrien#endif
660348743Sobrien      || dest == pc_rtx)
660448743Sobrien    return;
660548743Sobrien
660650397Sobrien  if (code == STRICT_LOW_PART || code == ZERO_EXTRACT)
660750397Sobrien    invalidate (XEXP (dest, 0), GET_MODE (dest));
660850397Sobrien  else if (code == REG || code == SUBREG || code == MEM)
660918334Speter    invalidate (dest, VOIDmode);
661018334Speter}
661118334Speter
661218334Speter/* Invalidate all insns from START up to the end of the function or the
661318334Speter   next label.  This called when we wish to CSE around a block that is
661418334Speter   conditionally executed.  */
661518334Speter
661618334Speterstatic void
661718334Speterinvalidate_skipped_block (start)
661818334Speter     rtx start;
661918334Speter{
662018334Speter  rtx insn;
662118334Speter
662218334Speter  for (insn = start; insn && GET_CODE (insn) != CODE_LABEL;
662318334Speter       insn = NEXT_INSN (insn))
662418334Speter    {
662590075Sobrien      if (! INSN_P (insn))
662618334Speter	continue;
662718334Speter
662818334Speter      if (GET_CODE (insn) == CALL_INSN)
662918334Speter	{
663090075Sobrien	  if (! CONST_OR_PURE_CALL_P (insn))
663150397Sobrien	    invalidate_memory ();
663218334Speter	  invalidate_for_call ();
663318334Speter	}
663418334Speter
663550397Sobrien      invalidate_from_clobbers (PATTERN (insn));
663690075Sobrien      note_stores (PATTERN (insn), invalidate_skipped_set, NULL);
663718334Speter    }
663818334Speter}
663918334Speter
664090075Sobrien/* If modifying X will modify the value in *DATA (which is really an
664190075Sobrien   `rtx *'), indicate that fact by setting the pointed to value to
664290075Sobrien   NULL_RTX.  */
664318334Speter
664418334Speterstatic void
664590075Sobriencse_check_loop_start (x, set, data)
664618334Speter     rtx x;
664750397Sobrien     rtx set ATTRIBUTE_UNUSED;
664890075Sobrien     void *data;
664918334Speter{
665090075Sobrien  rtx *cse_check_loop_start_value = (rtx *) data;
665190075Sobrien
665290075Sobrien  if (*cse_check_loop_start_value == NULL_RTX
665318334Speter      || GET_CODE (x) == CC0 || GET_CODE (x) == PC)
665418334Speter    return;
665518334Speter
665690075Sobrien  if ((GET_CODE (x) == MEM && GET_CODE (*cse_check_loop_start_value) == MEM)
665790075Sobrien      || reg_overlap_mentioned_p (x, *cse_check_loop_start_value))
665890075Sobrien    *cse_check_loop_start_value = NULL_RTX;
665918334Speter}
666018334Speter
666118334Speter/* X is a SET or CLOBBER contained in INSN that was found near the start of
666218334Speter   a loop that starts with the label at LOOP_START.
666318334Speter
666418334Speter   If X is a SET, we see if its SET_SRC is currently in our hash table.
666518334Speter   If so, we see if it has a value equal to some register used only in the
666618334Speter   loop exit code (as marked by jump.c).
666718334Speter
666818334Speter   If those two conditions are true, we search backwards from the start of
666918334Speter   the loop to see if that same value was loaded into a register that still
667018334Speter   retains its value at the start of the loop.
667118334Speter
667218334Speter   If so, we insert an insn after the load to copy the destination of that
667318334Speter   load into the equivalent register and (try to) replace our SET_SRC with that
667418334Speter   register.
667518334Speter
667618334Speter   In any event, we invalidate whatever this SET or CLOBBER modifies.  */
667718334Speter
667818334Speterstatic void
667918334Spetercse_set_around_loop (x, insn, loop_start)
668018334Speter     rtx x;
668118334Speter     rtx insn;
668218334Speter     rtx loop_start;
668318334Speter{
668418334Speter  struct table_elt *src_elt;
668518334Speter
668618334Speter  /* If this is a SET, see if we can replace SET_SRC, but ignore SETs that
668718334Speter     are setting PC or CC0 or whose SET_SRC is already a register.  */
668818334Speter  if (GET_CODE (x) == SET
668918334Speter      && GET_CODE (SET_DEST (x)) != PC && GET_CODE (SET_DEST (x)) != CC0
669018334Speter      && GET_CODE (SET_SRC (x)) != REG)
669118334Speter    {
669218334Speter      src_elt = lookup (SET_SRC (x),
669318334Speter			HASH (SET_SRC (x), GET_MODE (SET_DEST (x))),
669418334Speter			GET_MODE (SET_DEST (x)));
669518334Speter
669618334Speter      if (src_elt)
669718334Speter	for (src_elt = src_elt->first_same_value; src_elt;
669818334Speter	     src_elt = src_elt->next_same_value)
669918334Speter	  if (GET_CODE (src_elt->exp) == REG && REG_LOOP_TEST_P (src_elt->exp)
670018334Speter	      && COST (src_elt->exp) < COST (SET_SRC (x)))
670118334Speter	    {
670218334Speter	      rtx p, set;
670318334Speter
670418334Speter	      /* Look for an insn in front of LOOP_START that sets
670518334Speter		 something in the desired mode to SET_SRC (x) before we hit
670618334Speter		 a label or CALL_INSN.  */
670718334Speter
670818334Speter	      for (p = prev_nonnote_insn (loop_start);
670918334Speter		   p && GET_CODE (p) != CALL_INSN
671018334Speter		   && GET_CODE (p) != CODE_LABEL;
671118334Speter		   p = prev_nonnote_insn  (p))
671218334Speter		if ((set = single_set (p)) != 0
671318334Speter		    && GET_CODE (SET_DEST (set)) == REG
671418334Speter		    && GET_MODE (SET_DEST (set)) == src_elt->mode
671518334Speter		    && rtx_equal_p (SET_SRC (set), SET_SRC (x)))
671618334Speter		  {
671718334Speter		    /* We now have to ensure that nothing between P
671818334Speter		       and LOOP_START modified anything referenced in
671918334Speter		       SET_SRC (x).  We know that nothing within the loop
672018334Speter		       can modify it, or we would have invalidated it in
672118334Speter		       the hash table.  */
672218334Speter		    rtx q;
672390075Sobrien		    rtx cse_check_loop_start_value = SET_SRC (x);
672418334Speter		    for (q = p; q != loop_start; q = NEXT_INSN (q))
672590075Sobrien		      if (INSN_P (q))
672690075Sobrien			note_stores (PATTERN (q),
672790075Sobrien				     cse_check_loop_start,
672890075Sobrien				     &cse_check_loop_start_value);
672918334Speter
673018334Speter		    /* If nothing was changed and we can replace our
673118334Speter		       SET_SRC, add an insn after P to copy its destination
673218334Speter		       to what we will be replacing SET_SRC with.  */
673318334Speter		    if (cse_check_loop_start_value
673418334Speter			&& validate_change (insn, &SET_SRC (x),
673518334Speter					    src_elt->exp, 0))
673650397Sobrien		      {
673750397Sobrien			/* If this creates new pseudos, this is unsafe,
673850397Sobrien			   because the regno of new pseudo is unsuitable
673950397Sobrien			   to index into reg_qty when cse_insn processes
674050397Sobrien			   the new insn.  Therefore, if a new pseudo was
674150397Sobrien			   created, discard this optimization.  */
674250397Sobrien			int nregs = max_reg_num ();
674350397Sobrien			rtx move
674450397Sobrien			  = gen_move_insn (src_elt->exp, SET_DEST (set));
674550397Sobrien			if (nregs != max_reg_num ())
674650397Sobrien			  {
674750397Sobrien			    if (! validate_change (insn, &SET_SRC (x),
674850397Sobrien						   SET_SRC (set), 0))
674950397Sobrien			      abort ();
675050397Sobrien			  }
675150397Sobrien			else
675250397Sobrien			  emit_insn_after (move, p);
675350397Sobrien		      }
675418334Speter		    break;
675518334Speter		  }
675618334Speter	    }
675718334Speter    }
675818334Speter
675990075Sobrien  /* Deal with the destination of X affecting the stack pointer.  */
676090075Sobrien  addr_affects_sp_p (SET_DEST (x));
676118334Speter
676290075Sobrien  /* See comment on similar code in cse_insn for explanation of these
676390075Sobrien     tests.  */
676418334Speter  if (GET_CODE (SET_DEST (x)) == REG || GET_CODE (SET_DEST (x)) == SUBREG
676550397Sobrien      || GET_CODE (SET_DEST (x)) == MEM)
676618334Speter    invalidate (SET_DEST (x), VOIDmode);
676718334Speter  else if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART
676818334Speter	   || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
676918334Speter    invalidate (XEXP (SET_DEST (x), 0), GET_MODE (SET_DEST (x)));
677018334Speter}
677118334Speter
677218334Speter/* Find the end of INSN's basic block and return its range,
677318334Speter   the total number of SETs in all the insns of the block, the last insn of the
677418334Speter   block, and the branch path.
677518334Speter
677618334Speter   The branch path indicates which branches should be followed.  If a non-zero
677718334Speter   path size is specified, the block should be rescanned and a different set
677818334Speter   of branches will be taken.  The branch path is only used if
677918334Speter   FLAG_CSE_FOLLOW_JUMPS or FLAG_CSE_SKIP_BLOCKS is non-zero.
678018334Speter
678118334Speter   DATA is a pointer to a struct cse_basic_block_data, defined below, that is
678218334Speter   used to describe the block.  It is filled in with the information about
678318334Speter   the current block.  The incoming structure's branch path, if any, is used
678418334Speter   to construct the output branch path.  */
678518334Speter
678618334Spetervoid
678718334Spetercse_end_of_basic_block (insn, data, follow_jumps, after_loop, skip_blocks)
678818334Speter     rtx insn;
678918334Speter     struct cse_basic_block_data *data;
679018334Speter     int follow_jumps;
679118334Speter     int after_loop;
679218334Speter     int skip_blocks;
679318334Speter{
679418334Speter  rtx p = insn, q;
679518334Speter  int nsets = 0;
679618334Speter  int low_cuid = INSN_CUID (insn), high_cuid = INSN_CUID (insn);
679790075Sobrien  rtx next = INSN_P (insn) ? insn : next_real_insn (insn);
679818334Speter  int path_size = data->path_size;
679918334Speter  int path_entry = 0;
680018334Speter  int i;
680118334Speter
680218334Speter  /* Update the previous branch path, if any.  If the last branch was
680318334Speter     previously TAKEN, mark it NOT_TAKEN.  If it was previously NOT_TAKEN,
680418334Speter     shorten the path by one and look at the previous branch.  We know that
680518334Speter     at least one branch must have been taken if PATH_SIZE is non-zero.  */
680618334Speter  while (path_size > 0)
680718334Speter    {
680818334Speter      if (data->path[path_size - 1].status != NOT_TAKEN)
680918334Speter	{
681018334Speter	  data->path[path_size - 1].status = NOT_TAKEN;
681118334Speter	  break;
681218334Speter	}
681318334Speter      else
681418334Speter	path_size--;
681518334Speter    }
681618334Speter
681790075Sobrien  /* If the first instruction is marked with QImode, that means we've
681890075Sobrien     already processed this block.  Our caller will look at DATA->LAST
681990075Sobrien     to figure out where to go next.  We want to return the next block
682090075Sobrien     in the instruction stream, not some branched-to block somewhere
682190075Sobrien     else.  We accomplish this by pretending our called forbid us to
682290075Sobrien     follow jumps, or skip blocks.  */
682390075Sobrien  if (GET_MODE (insn) == QImode)
682490075Sobrien    follow_jumps = skip_blocks = 0;
682590075Sobrien
682618334Speter  /* Scan to end of this basic block.  */
682718334Speter  while (p && GET_CODE (p) != CODE_LABEL)
682818334Speter    {
682918334Speter      /* Don't cse out the end of a loop.  This makes a difference
683018334Speter	 only for the unusual loops that always execute at least once;
683118334Speter	 all other loops have labels there so we will stop in any case.
683218334Speter	 Cse'ing out the end of the loop is dangerous because it
683318334Speter	 might cause an invariant expression inside the loop
683418334Speter	 to be reused after the end of the loop.  This would make it
683518334Speter	 hard to move the expression out of the loop in loop.c,
683618334Speter	 especially if it is one of several equivalent expressions
683718334Speter	 and loop.c would like to eliminate it.
683818334Speter
683918334Speter	 If we are running after loop.c has finished, we can ignore
684018334Speter	 the NOTE_INSN_LOOP_END.  */
684118334Speter
684218334Speter      if (! after_loop && GET_CODE (p) == NOTE
684318334Speter	  && NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)
684418334Speter	break;
684518334Speter
684690075Sobrien      /* Don't cse over a call to setjmp; on some machines (eg VAX)
684718334Speter	 the regs restored by the longjmp come from
684818334Speter	 a later time than the setjmp.  */
684990075Sobrien      if (PREV_INSN (p) && GET_CODE (PREV_INSN (p)) == CALL_INSN
685090075Sobrien	  && find_reg_note (PREV_INSN (p), REG_SETJMP, NULL))
685118334Speter	break;
685218334Speter
685318334Speter      /* A PARALLEL can have lots of SETs in it,
685418334Speter	 especially if it is really an ASM_OPERANDS.  */
685590075Sobrien      if (INSN_P (p) && GET_CODE (PATTERN (p)) == PARALLEL)
685618334Speter	nsets += XVECLEN (PATTERN (p), 0);
685718334Speter      else if (GET_CODE (p) != NOTE)
685818334Speter	nsets += 1;
685990075Sobrien
686018334Speter      /* Ignore insns made by CSE; they cannot affect the boundaries of
686118334Speter	 the basic block.  */
686218334Speter
686318334Speter      if (INSN_UID (p) <= max_uid && INSN_CUID (p) > high_cuid)
686418334Speter	high_cuid = INSN_CUID (p);
686518334Speter      if (INSN_UID (p) <= max_uid && INSN_CUID (p) < low_cuid)
686618334Speter	low_cuid = INSN_CUID (p);
686718334Speter
686818334Speter      /* See if this insn is in our branch path.  If it is and we are to
686918334Speter	 take it, do so.  */
687018334Speter      if (path_entry < path_size && data->path[path_entry].branch == p)
687118334Speter	{
687218334Speter	  if (data->path[path_entry].status != NOT_TAKEN)
687318334Speter	    p = JUMP_LABEL (p);
687490075Sobrien
687518334Speter	  /* Point to next entry in path, if any.  */
687618334Speter	  path_entry++;
687718334Speter	}
687818334Speter
687918334Speter      /* If this is a conditional jump, we can follow it if -fcse-follow-jumps
688018334Speter	 was specified, we haven't reached our maximum path length, there are
688118334Speter	 insns following the target of the jump, this is the only use of the
688218334Speter	 jump label, and the target label is preceded by a BARRIER.
688318334Speter
688418334Speter	 Alternatively, we can follow the jump if it branches around a
688518334Speter	 block of code and there are no other branches into the block.
688618334Speter	 In this case invalidate_skipped_block will be called to invalidate any
688718334Speter	 registers set in the block when following the jump.  */
688818334Speter
688918334Speter      else if ((follow_jumps || skip_blocks) && path_size < PATHLENGTH - 1
689018334Speter	       && GET_CODE (p) == JUMP_INSN
689190075Sobrien	       && GET_CODE (PATTERN (p)) == SET
689218334Speter	       && GET_CODE (SET_SRC (PATTERN (p))) == IF_THEN_ELSE
689350397Sobrien	       && JUMP_LABEL (p) != 0
689418334Speter	       && LABEL_NUSES (JUMP_LABEL (p)) == 1
689518334Speter	       && NEXT_INSN (JUMP_LABEL (p)) != 0)
689618334Speter	{
689718334Speter	  for (q = PREV_INSN (JUMP_LABEL (p)); q; q = PREV_INSN (q))
689818334Speter	    if ((GET_CODE (q) != NOTE
689990075Sobrien		 || NOTE_LINE_NUMBER (q) == NOTE_INSN_LOOP_END
690090075Sobrien		 || (PREV_INSN (q) && GET_CODE (PREV_INSN (q)) == CALL_INSN
690190075Sobrien		     && find_reg_note (PREV_INSN (q), REG_SETJMP, NULL)))
690290075Sobrien		&& (GET_CODE (q) != CODE_LABEL || LABEL_NUSES (q) != 0))
690318334Speter	      break;
690418334Speter
690518334Speter	  /* If we ran into a BARRIER, this code is an extension of the
690618334Speter	     basic block when the branch is taken.  */
690718334Speter	  if (follow_jumps && q != 0 && GET_CODE (q) == BARRIER)
690818334Speter	    {
690918334Speter	      /* Don't allow ourself to keep walking around an
691018334Speter		 always-executed loop.  */
691118334Speter	      if (next_real_insn (q) == next)
691218334Speter		{
691318334Speter		  p = NEXT_INSN (p);
691418334Speter		  continue;
691518334Speter		}
691618334Speter
691718334Speter	      /* Similarly, don't put a branch in our path more than once.  */
691818334Speter	      for (i = 0; i < path_entry; i++)
691918334Speter		if (data->path[i].branch == p)
692018334Speter		  break;
692118334Speter
692218334Speter	      if (i != path_entry)
692318334Speter		break;
692418334Speter
692518334Speter	      data->path[path_entry].branch = p;
692618334Speter	      data->path[path_entry++].status = TAKEN;
692718334Speter
692818334Speter	      /* This branch now ends our path.  It was possible that we
692918334Speter		 didn't see this branch the last time around (when the
693018334Speter		 insn in front of the target was a JUMP_INSN that was
693118334Speter		 turned into a no-op).  */
693218334Speter	      path_size = path_entry;
693318334Speter
693418334Speter	      p = JUMP_LABEL (p);
693518334Speter	      /* Mark block so we won't scan it again later.  */
693618334Speter	      PUT_MODE (NEXT_INSN (p), QImode);
693718334Speter	    }
693818334Speter	  /* Detect a branch around a block of code.  */
693918334Speter	  else if (skip_blocks && q != 0 && GET_CODE (q) != CODE_LABEL)
694018334Speter	    {
694190075Sobrien	      rtx tmp;
694218334Speter
694318334Speter	      if (next_real_insn (q) == next)
694418334Speter		{
694518334Speter		  p = NEXT_INSN (p);
694618334Speter		  continue;
694718334Speter		}
694818334Speter
694918334Speter	      for (i = 0; i < path_entry; i++)
695018334Speter		if (data->path[i].branch == p)
695118334Speter		  break;
695218334Speter
695318334Speter	      if (i != path_entry)
695418334Speter		break;
695518334Speter
695618334Speter	      /* This is no_labels_between_p (p, q) with an added check for
695718334Speter		 reaching the end of a function (in case Q precedes P).  */
695818334Speter	      for (tmp = NEXT_INSN (p); tmp && tmp != q; tmp = NEXT_INSN (tmp))
695918334Speter		if (GET_CODE (tmp) == CODE_LABEL)
696018334Speter		  break;
696190075Sobrien
696218334Speter	      if (tmp == q)
696318334Speter		{
696418334Speter		  data->path[path_entry].branch = p;
696518334Speter		  data->path[path_entry++].status = AROUND;
696618334Speter
696718334Speter		  path_size = path_entry;
696818334Speter
696918334Speter		  p = JUMP_LABEL (p);
697018334Speter		  /* Mark block so we won't scan it again later.  */
697118334Speter		  PUT_MODE (NEXT_INSN (p), QImode);
697218334Speter		}
697318334Speter	    }
697418334Speter	}
697518334Speter      p = NEXT_INSN (p);
697618334Speter    }
697718334Speter
697818334Speter  data->low_cuid = low_cuid;
697918334Speter  data->high_cuid = high_cuid;
698018334Speter  data->nsets = nsets;
698118334Speter  data->last = p;
698218334Speter
698318334Speter  /* If all jumps in the path are not taken, set our path length to zero
698418334Speter     so a rescan won't be done.  */
698518334Speter  for (i = path_size - 1; i >= 0; i--)
698618334Speter    if (data->path[i].status != NOT_TAKEN)
698718334Speter      break;
698818334Speter
698918334Speter  if (i == -1)
699018334Speter    data->path_size = 0;
699118334Speter  else
699218334Speter    data->path_size = path_size;
699318334Speter
699418334Speter  /* End the current branch path.  */
699518334Speter  data->path[path_size].branch = 0;
699618334Speter}
699718334Speter
699818334Speter/* Perform cse on the instructions of a function.
699918334Speter   F is the first instruction.
700018334Speter   NREGS is one plus the highest pseudo-reg number used in the instruction.
700118334Speter
700218334Speter   AFTER_LOOP is 1 if this is the cse call done after loop optimization
700318334Speter   (only if -frerun-cse-after-loop).
700418334Speter
700518334Speter   Returns 1 if jump_optimize should be redone due to simplifications
700618334Speter   in conditional jump instructions.  */
700718334Speter
700818334Speterint
700918334Spetercse_main (f, nregs, after_loop, file)
701018334Speter     rtx f;
701118334Speter     int nregs;
701218334Speter     int after_loop;
701318334Speter     FILE *file;
701418334Speter{
701518334Speter  struct cse_basic_block_data val;
701690075Sobrien  rtx insn = f;
701790075Sobrien  int i;
701818334Speter
701918334Speter  cse_jumps_altered = 0;
702018334Speter  recorded_label_ref = 0;
702118334Speter  constant_pool_entries_cost = 0;
702218334Speter  val.path_size = 0;
702318334Speter
702418334Speter  init_recog ();
702550397Sobrien  init_alias_analysis ();
702618334Speter
702718334Speter  max_reg = nregs;
702818334Speter
702950397Sobrien  max_insn_uid = get_max_uid ();
703050397Sobrien
703190075Sobrien  reg_eqv_table = (struct reg_eqv_elem *)
703290075Sobrien    xmalloc (nregs * sizeof (struct reg_eqv_elem));
703318334Speter
703418334Speter#ifdef LOAD_EXTEND_OP
703518334Speter
703618334Speter  /* Allocate scratch rtl here.  cse_insn will fill in the memory reference
703718334Speter     and change the code and mode as appropriate.  */
703850397Sobrien  memory_extend_rtx = gen_rtx_ZERO_EXTEND (VOIDmode, NULL_RTX);
703918334Speter#endif
704018334Speter
704190075Sobrien  /* Reset the counter indicating how many elements have been made
704290075Sobrien     thus far.  */
704318334Speter  n_elements_made = 0;
704418334Speter
704518334Speter  /* Find the largest uid.  */
704618334Speter
704718334Speter  max_uid = get_max_uid ();
704890075Sobrien  uid_cuid = (int *) xcalloc (max_uid + 1, sizeof (int));
704918334Speter
705018334Speter  /* Compute the mapping from uids to cuids.
705118334Speter     CUIDs are numbers assigned to insns, like uids,
705218334Speter     except that cuids increase monotonically through the code.
705318334Speter     Don't assign cuids to line-number NOTEs, so that the distance in cuids
705418334Speter     between two insns is not affected by -g.  */
705518334Speter
705618334Speter  for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
705718334Speter    {
705818334Speter      if (GET_CODE (insn) != NOTE
705918334Speter	  || NOTE_LINE_NUMBER (insn) < 0)
706018334Speter	INSN_CUID (insn) = ++i;
706118334Speter      else
706218334Speter	/* Give a line number note the same cuid as preceding insn.  */
706318334Speter	INSN_CUID (insn) = i;
706418334Speter    }
706518334Speter
706690075Sobrien  ggc_push_context ();
706718334Speter
706818334Speter  /* Loop over basic blocks.
706918334Speter     Compute the maximum number of qty's needed for each basic block
707018334Speter     (which is 2 for each SET).  */
707118334Speter  insn = f;
707218334Speter  while (insn)
707318334Speter    {
707490075Sobrien      cse_altered = 0;
707518334Speter      cse_end_of_basic_block (insn, &val, flag_cse_follow_jumps, after_loop,
707618334Speter			      flag_cse_skip_blocks);
707718334Speter
707818334Speter      /* If this basic block was already processed or has no sets, skip it.  */
707918334Speter      if (val.nsets == 0 || GET_MODE (insn) == QImode)
708018334Speter	{
708118334Speter	  PUT_MODE (insn, VOIDmode);
708218334Speter	  insn = (val.last ? NEXT_INSN (val.last) : 0);
708318334Speter	  val.path_size = 0;
708418334Speter	  continue;
708518334Speter	}
708618334Speter
708718334Speter      cse_basic_block_start = val.low_cuid;
708818334Speter      cse_basic_block_end = val.high_cuid;
708918334Speter      max_qty = val.nsets * 2;
709090075Sobrien
709118334Speter      if (file)
709252284Sobrien	fnotice (file, ";; Processing block from %d to %d, %d sets.\n",
709318334Speter		 INSN_UID (insn), val.last ? INSN_UID (val.last) : 0,
709418334Speter		 val.nsets);
709518334Speter
709618334Speter      /* Make MAX_QTY bigger to give us room to optimize
709718334Speter	 past the end of this basic block, if that should prove useful.  */
709818334Speter      if (max_qty < 500)
709918334Speter	max_qty = 500;
710018334Speter
710118334Speter      max_qty += max_reg;
710218334Speter
710318334Speter      /* If this basic block is being extended by following certain jumps,
710418334Speter         (see `cse_end_of_basic_block'), we reprocess the code from the start.
710518334Speter         Otherwise, we start after this basic block.  */
710618334Speter      if (val.path_size > 0)
710790075Sobrien	cse_basic_block (insn, val.last, val.path, 0);
710818334Speter      else
710918334Speter	{
711018334Speter	  int old_cse_jumps_altered = cse_jumps_altered;
711118334Speter	  rtx temp;
711218334Speter
711318334Speter	  /* When cse changes a conditional jump to an unconditional
711418334Speter	     jump, we want to reprocess the block, since it will give
711518334Speter	     us a new branch path to investigate.  */
711618334Speter	  cse_jumps_altered = 0;
711718334Speter	  temp = cse_basic_block (insn, val.last, val.path, ! after_loop);
711818334Speter	  if (cse_jumps_altered == 0
711918334Speter	      || (flag_cse_follow_jumps == 0 && flag_cse_skip_blocks == 0))
712018334Speter	    insn = temp;
712118334Speter
712218334Speter	  cse_jumps_altered |= old_cse_jumps_altered;
712318334Speter	}
712418334Speter
712590075Sobrien      if (cse_altered)
712690075Sobrien	ggc_collect ();
712790075Sobrien
712818334Speter#ifdef USE_C_ALLOCA
712918334Speter      alloca (0);
713018334Speter#endif
713118334Speter    }
713218334Speter
713390075Sobrien  ggc_pop_context ();
713418334Speter
713518334Speter  if (max_elements_made < n_elements_made)
713618334Speter    max_elements_made = n_elements_made;
713718334Speter
713890075Sobrien  /* Clean up.  */
713990075Sobrien  end_alias_analysis ();
714090075Sobrien  free (uid_cuid);
714190075Sobrien  free (reg_eqv_table);
714290075Sobrien
714318334Speter  return cse_jumps_altered || recorded_label_ref;
714418334Speter}
714518334Speter
714618334Speter/* Process a single basic block.  FROM and TO and the limits of the basic
714718334Speter   block.  NEXT_BRANCH points to the branch path when following jumps or
714818334Speter   a null path when not following jumps.
714918334Speter
715018334Speter   AROUND_LOOP is non-zero if we are to try to cse around to the start of a
715118334Speter   loop.  This is true when we are being called for the last time on a
715218334Speter   block and this CSE pass is before loop.c.  */
715318334Speter
715418334Speterstatic rtx
715518334Spetercse_basic_block (from, to, next_branch, around_loop)
715690075Sobrien     rtx from, to;
715718334Speter     struct branch_path *next_branch;
715818334Speter     int around_loop;
715918334Speter{
716090075Sobrien  rtx insn;
716118334Speter  int to_usage = 0;
716250397Sobrien  rtx libcall_insn = NULL_RTX;
716350397Sobrien  int num_insns = 0;
716418334Speter
716590075Sobrien  /* This array is undefined before max_reg, so only allocate
716690075Sobrien     the space actually needed and adjust the start.  */
716718334Speter
716890075Sobrien  qty_table
716990075Sobrien    = (struct qty_table_elem *) xmalloc ((max_qty - max_reg)
717090075Sobrien					 * sizeof (struct qty_table_elem));
717190075Sobrien  qty_table -= max_reg;
717218334Speter
717318334Speter  new_basic_block ();
717418334Speter
717518334Speter  /* TO might be a label.  If so, protect it from being deleted.  */
717618334Speter  if (to != 0 && GET_CODE (to) == CODE_LABEL)
717718334Speter    ++LABEL_NUSES (to);
717818334Speter
717918334Speter  for (insn = from; insn != to; insn = NEXT_INSN (insn))
718018334Speter    {
718190075Sobrien      enum rtx_code code = GET_CODE (insn);
718218334Speter
718350397Sobrien      /* If we have processed 1,000 insns, flush the hash table to
718450397Sobrien	 avoid extreme quadratic behavior.  We must not include NOTEs
718590075Sobrien	 in the count since there may be more of them when generating
718650397Sobrien	 debugging information.  If we clear the table at different
718750397Sobrien	 times, code generated with -g -O might be different than code
718850397Sobrien	 generated with -O but not -g.
718950397Sobrien
719050397Sobrien	 ??? This is a real kludge and needs to be done some other way.
719150397Sobrien	 Perhaps for 2.9.  */
719250397Sobrien      if (code != NOTE && num_insns++ > 1000)
719350397Sobrien	{
719452284Sobrien	  flush_hash_table ();
719550397Sobrien	  num_insns = 0;
719650397Sobrien	}
719750397Sobrien
719818334Speter      /* See if this is a branch that is part of the path.  If so, and it is
719918334Speter	 to be taken, do so.  */
720018334Speter      if (next_branch->branch == insn)
720118334Speter	{
720218334Speter	  enum taken status = next_branch++->status;
720318334Speter	  if (status != NOT_TAKEN)
720418334Speter	    {
720518334Speter	      if (status == TAKEN)
720618334Speter		record_jump_equiv (insn, 1);
720718334Speter	      else
720818334Speter		invalidate_skipped_block (NEXT_INSN (insn));
720918334Speter
721018334Speter	      /* Set the last insn as the jump insn; it doesn't affect cc0.
721118334Speter		 Then follow this branch.  */
721218334Speter#ifdef HAVE_cc0
721318334Speter	      prev_insn_cc0 = 0;
721418334Speter#endif
721518334Speter	      prev_insn = insn;
721618334Speter	      insn = JUMP_LABEL (insn);
721718334Speter	      continue;
721818334Speter	    }
721918334Speter	}
722090075Sobrien
722118334Speter      if (GET_MODE (insn) == QImode)
722218334Speter	PUT_MODE (insn, VOIDmode);
722318334Speter
722418334Speter      if (GET_RTX_CLASS (code) == 'i')
722518334Speter	{
722650397Sobrien	  rtx p;
722750397Sobrien
722818334Speter	  /* Process notes first so we have all notes in canonical forms when
722918334Speter	     looking for duplicate operations.  */
723018334Speter
723118334Speter	  if (REG_NOTES (insn))
723218334Speter	    REG_NOTES (insn) = cse_process_notes (REG_NOTES (insn), NULL_RTX);
723318334Speter
723418334Speter	  /* Track when we are inside in LIBCALL block.  Inside such a block,
723518334Speter	     we do not want to record destinations.  The last insn of a
723618334Speter	     LIBCALL block is not considered to be part of the block, since
723718334Speter	     its destination is the result of the block and hence should be
723818334Speter	     recorded.  */
723918334Speter
724090075Sobrien	  if (REG_NOTES (insn) != 0)
724190075Sobrien	    {
724290075Sobrien	      if ((p = find_reg_note (insn, REG_LIBCALL, NULL_RTX)))
724390075Sobrien		libcall_insn = XEXP (p, 0);
724490075Sobrien	      else if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
724590075Sobrien		libcall_insn = 0;
724690075Sobrien	    }
724718334Speter
724850397Sobrien	  cse_insn (insn, libcall_insn);
724990075Sobrien
725090075Sobrien	  /* If we haven't already found an insn where we added a LABEL_REF,
725190075Sobrien	     check this one.  */
725290075Sobrien	  if (GET_CODE (insn) == INSN && ! recorded_label_ref
725390075Sobrien	      && for_each_rtx (&PATTERN (insn), check_for_label_ref,
725490075Sobrien			       (void *) insn))
725590075Sobrien	    recorded_label_ref = 1;
725618334Speter	}
725718334Speter
725818334Speter      /* If INSN is now an unconditional jump, skip to the end of our
725918334Speter	 basic block by pretending that we just did the last insn in the
726018334Speter	 basic block.  If we are jumping to the end of our block, show
726118334Speter	 that we can have one usage of TO.  */
726218334Speter
726390075Sobrien      if (any_uncondjump_p (insn))
726418334Speter	{
726518334Speter	  if (to == 0)
726690075Sobrien	    {
726790075Sobrien	      free (qty_table + max_reg);
726890075Sobrien	      return 0;
726990075Sobrien	    }
727018334Speter
727118334Speter	  if (JUMP_LABEL (insn) == to)
727218334Speter	    to_usage = 1;
727318334Speter
727418334Speter	  /* Maybe TO was deleted because the jump is unconditional.
727518334Speter	     If so, there is nothing left in this basic block.  */
727618334Speter	  /* ??? Perhaps it would be smarter to set TO
727790075Sobrien	     to whatever follows this insn,
727818334Speter	     and pretend the basic block had always ended here.  */
727918334Speter	  if (INSN_DELETED_P (to))
728018334Speter	    break;
728118334Speter
728218334Speter	  insn = PREV_INSN (to);
728318334Speter	}
728418334Speter
728518334Speter      /* See if it is ok to keep on going past the label
728618334Speter	 which used to end our basic block.  Remember that we incremented
728718334Speter	 the count of that label, so we decrement it here.  If we made
728818334Speter	 a jump unconditional, TO_USAGE will be one; in that case, we don't
728918334Speter	 want to count the use in that jump.  */
729018334Speter
729118334Speter      if (to != 0 && NEXT_INSN (insn) == to
729218334Speter	  && GET_CODE (to) == CODE_LABEL && --LABEL_NUSES (to) == to_usage)
729318334Speter	{
729418334Speter	  struct cse_basic_block_data val;
729518334Speter	  rtx prev;
729618334Speter
729718334Speter	  insn = NEXT_INSN (to);
729818334Speter
729918334Speter	  /* If TO was the last insn in the function, we are done.  */
730018334Speter	  if (insn == 0)
730190075Sobrien	    {
730290075Sobrien	      free (qty_table + max_reg);
730390075Sobrien	      return 0;
730490075Sobrien	    }
730518334Speter
730618334Speter	  /* If TO was preceded by a BARRIER we are done with this block
730718334Speter	     because it has no continuation.  */
730818334Speter	  prev = prev_nonnote_insn (to);
730918334Speter	  if (prev && GET_CODE (prev) == BARRIER)
731090075Sobrien	    {
731190075Sobrien	      free (qty_table + max_reg);
731290075Sobrien	      return insn;
731390075Sobrien	    }
731418334Speter
731518334Speter	  /* Find the end of the following block.  Note that we won't be
731618334Speter	     following branches in this case.  */
731718334Speter	  to_usage = 0;
731818334Speter	  val.path_size = 0;
731918334Speter	  cse_end_of_basic_block (insn, &val, 0, 0, 0);
732018334Speter
732118334Speter	  /* If the tables we allocated have enough space left
732218334Speter	     to handle all the SETs in the next basic block,
732318334Speter	     continue through it.  Otherwise, return,
732418334Speter	     and that block will be scanned individually.  */
732518334Speter	  if (val.nsets * 2 + next_qty > max_qty)
732618334Speter	    break;
732718334Speter
732818334Speter	  cse_basic_block_start = val.low_cuid;
732918334Speter	  cse_basic_block_end = val.high_cuid;
733018334Speter	  to = val.last;
733118334Speter
733218334Speter	  /* Prevent TO from being deleted if it is a label.  */
733318334Speter	  if (to != 0 && GET_CODE (to) == CODE_LABEL)
733418334Speter	    ++LABEL_NUSES (to);
733518334Speter
733618334Speter	  /* Back up so we process the first insn in the extension.  */
733718334Speter	  insn = PREV_INSN (insn);
733818334Speter	}
733918334Speter    }
734018334Speter
734118334Speter  if (next_qty > max_qty)
734218334Speter    abort ();
734318334Speter
734418334Speter  /* If we are running before loop.c, we stopped on a NOTE_INSN_LOOP_END, and
734518334Speter     the previous insn is the only insn that branches to the head of a loop,
734618334Speter     we can cse into the loop.  Don't do this if we changed the jump
734718334Speter     structure of a loop unless we aren't going to be following jumps.  */
734818334Speter
734990075Sobrien  insn = prev_nonnote_insn(to);
735018334Speter  if ((cse_jumps_altered == 0
735118334Speter       || (flag_cse_follow_jumps == 0 && flag_cse_skip_blocks == 0))
735218334Speter      && around_loop && to != 0
735318334Speter      && GET_CODE (to) == NOTE && NOTE_LINE_NUMBER (to) == NOTE_INSN_LOOP_END
735490075Sobrien      && GET_CODE (insn) == JUMP_INSN
735590075Sobrien      && JUMP_LABEL (insn) != 0
735690075Sobrien      && LABEL_NUSES (JUMP_LABEL (insn)) == 1)
735790075Sobrien    cse_around_loop (JUMP_LABEL (insn));
735818334Speter
735990075Sobrien  free (qty_table + max_reg);
736090075Sobrien
736118334Speter  return to ? NEXT_INSN (to) : 0;
736218334Speter}
736318334Speter
736490075Sobrien/* Called via for_each_rtx to see if an insn is using a LABEL_REF for which
736590075Sobrien   there isn't a REG_LABEL note.  Return one if so.  DATA is the insn.  */
736690075Sobrien
736790075Sobrienstatic int
736890075Sobriencheck_for_label_ref (rtl, data)
736990075Sobrien     rtx *rtl;
737090075Sobrien     void *data;
737190075Sobrien{
737290075Sobrien  rtx insn = (rtx) data;
737390075Sobrien
737490075Sobrien  /* If this insn uses a LABEL_REF and there isn't a REG_LABEL note for it,
737590075Sobrien     we must rerun jump since it needs to place the note.  If this is a
737690075Sobrien     LABEL_REF for a CODE_LABEL that isn't in the insn chain, don't do this
737790075Sobrien     since no REG_LABEL will be added.  */
737890075Sobrien  return (GET_CODE (*rtl) == LABEL_REF
737990075Sobrien	  && ! LABEL_REF_NONLOCAL_P (*rtl)
738090075Sobrien	  && LABEL_P (XEXP (*rtl, 0))
738190075Sobrien	  && INSN_UID (XEXP (*rtl, 0)) != 0
738290075Sobrien	  && ! find_reg_note (insn, REG_LABEL, XEXP (*rtl, 0)));
738390075Sobrien}
738490075Sobrien
738518334Speter/* Count the number of times registers are used (not set) in X.
738618334Speter   COUNTS is an array in which we accumulate the count, INCR is how much
738790075Sobrien   we count each register usage.
738818334Speter
738990075Sobrien   Don't count a usage of DEST, which is the SET_DEST of a SET which
739018334Speter   contains X in its SET_SRC.  This is because such a SET does not
739118334Speter   modify the liveness of DEST.  */
739218334Speter
739318334Speterstatic void
739418334Spetercount_reg_usage (x, counts, dest, incr)
739518334Speter     rtx x;
739618334Speter     int *counts;
739718334Speter     rtx dest;
739818334Speter     int incr;
739918334Speter{
740018334Speter  enum rtx_code code;
740190075Sobrien  const char *fmt;
740218334Speter  int i, j;
740318334Speter
740418334Speter  if (x == 0)
740518334Speter    return;
740618334Speter
740718334Speter  switch (code = GET_CODE (x))
740818334Speter    {
740918334Speter    case REG:
741018334Speter      if (x != dest)
741118334Speter	counts[REGNO (x)] += incr;
741218334Speter      return;
741318334Speter
741418334Speter    case PC:
741518334Speter    case CC0:
741618334Speter    case CONST:
741718334Speter    case CONST_INT:
741818334Speter    case CONST_DOUBLE:
741918334Speter    case SYMBOL_REF:
742018334Speter    case LABEL_REF:
742118334Speter      return;
742218334Speter
742390075Sobrien    case CLOBBER:
742450397Sobrien      /* If we are clobbering a MEM, mark any registers inside the address
742550397Sobrien         as being used.  */
742650397Sobrien      if (GET_CODE (XEXP (x, 0)) == MEM)
742750397Sobrien	count_reg_usage (XEXP (XEXP (x, 0), 0), counts, NULL_RTX, incr);
742850397Sobrien      return;
742950397Sobrien
743018334Speter    case SET:
743118334Speter      /* Unless we are setting a REG, count everything in SET_DEST.  */
743218334Speter      if (GET_CODE (SET_DEST (x)) != REG)
743318334Speter	count_reg_usage (SET_DEST (x), counts, NULL_RTX, incr);
743418334Speter
743518334Speter      /* If SRC has side-effects, then we can't delete this insn, so the
743618334Speter	 usage of SET_DEST inside SRC counts.
743718334Speter
743818334Speter	 ??? Strictly-speaking, we might be preserving this insn
743918334Speter	 because some other SET has side-effects, but that's hard
744018334Speter	 to do and can't happen now.  */
744118334Speter      count_reg_usage (SET_SRC (x), counts,
744218334Speter		       side_effects_p (SET_SRC (x)) ? NULL_RTX : SET_DEST (x),
744318334Speter		       incr);
744418334Speter      return;
744518334Speter
744618334Speter    case CALL_INSN:
744718334Speter      count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, NULL_RTX, incr);
744890075Sobrien      /* Fall through.  */
744918334Speter
745018334Speter    case INSN:
745118334Speter    case JUMP_INSN:
745218334Speter      count_reg_usage (PATTERN (x), counts, NULL_RTX, incr);
745318334Speter
745418334Speter      /* Things used in a REG_EQUAL note aren't dead since loop may try to
745518334Speter	 use them.  */
745618334Speter
745718334Speter      count_reg_usage (REG_NOTES (x), counts, NULL_RTX, incr);
745818334Speter      return;
745918334Speter
746018334Speter    case EXPR_LIST:
746118334Speter    case INSN_LIST:
746218334Speter      if (REG_NOTE_KIND (x) == REG_EQUAL
746350397Sobrien	  || (REG_NOTE_KIND (x) != REG_NONNEG && GET_CODE (XEXP (x,0)) == USE))
746418334Speter	count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr);
746518334Speter      count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr);
746618334Speter      return;
746790075Sobrien
746850397Sobrien    default:
746950397Sobrien      break;
747018334Speter    }
747118334Speter
747218334Speter  fmt = GET_RTX_FORMAT (code);
747318334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
747418334Speter    {
747518334Speter      if (fmt[i] == 'e')
747618334Speter	count_reg_usage (XEXP (x, i), counts, dest, incr);
747718334Speter      else if (fmt[i] == 'E')
747818334Speter	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
747918334Speter	  count_reg_usage (XVECEXP (x, i, j), counts, dest, incr);
748018334Speter    }
748118334Speter}
748218334Speter
748390075Sobrien/* Return true if set is live.  */
748490075Sobrienstatic bool
748590075Sobrienset_live_p (set, insn, counts)
748690075Sobrien     rtx set;
748790075Sobrien     rtx insn ATTRIBUTE_UNUSED;	/* Only used with HAVE_cc0.  */
748890075Sobrien     int *counts;
748990075Sobrien{
749090075Sobrien#ifdef HAVE_cc0
749190075Sobrien  rtx tem;
749290075Sobrien#endif
749390075Sobrien
749490075Sobrien  if (set_noop_p (set))
749590075Sobrien    ;
749690075Sobrien
749790075Sobrien#ifdef HAVE_cc0
749890075Sobrien  else if (GET_CODE (SET_DEST (set)) == CC0
749990075Sobrien	   && !side_effects_p (SET_SRC (set))
750090075Sobrien	   && ((tem = next_nonnote_insn (insn)) == 0
750190075Sobrien	       || !INSN_P (tem)
750290075Sobrien	       || !reg_referenced_p (cc0_rtx, PATTERN (tem))))
750390075Sobrien    return false;
750490075Sobrien#endif
750590075Sobrien  else if (GET_CODE (SET_DEST (set)) != REG
750690075Sobrien	   || REGNO (SET_DEST (set)) < FIRST_PSEUDO_REGISTER
750790075Sobrien	   || counts[REGNO (SET_DEST (set))] != 0
750890075Sobrien	   || side_effects_p (SET_SRC (set))
750990075Sobrien	   /* An ADDRESSOF expression can turn into a use of the
751090075Sobrien	      internal arg pointer, so always consider the
751190075Sobrien	      internal arg pointer live.  If it is truly dead,
751290075Sobrien	      flow will delete the initializing insn.  */
751390075Sobrien	   || (SET_DEST (set) == current_function_internal_arg_pointer))
751490075Sobrien    return true;
751590075Sobrien  return false;
751690075Sobrien}
751790075Sobrien
751890075Sobrien/* Return true if insn is live.  */
751990075Sobrien
752090075Sobrienstatic bool
752190075Sobrieninsn_live_p (insn, counts)
752290075Sobrien     rtx insn;
752390075Sobrien     int *counts;
752490075Sobrien{
752590075Sobrien  int i;
752690075Sobrien  if (GET_CODE (PATTERN (insn)) == SET)
752790075Sobrien    return set_live_p (PATTERN (insn), insn, counts);
752890075Sobrien  else if (GET_CODE (PATTERN (insn)) == PARALLEL)
752990075Sobrien    {
753090075Sobrien      for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
753190075Sobrien	{
753290075Sobrien	  rtx elt = XVECEXP (PATTERN (insn), 0, i);
753390075Sobrien
753490075Sobrien	  if (GET_CODE (elt) == SET)
753590075Sobrien	    {
753690075Sobrien	      if (set_live_p (elt, insn, counts))
753790075Sobrien		return true;
753890075Sobrien	    }
753990075Sobrien	  else if (GET_CODE (elt) != CLOBBER && GET_CODE (elt) != USE)
754090075Sobrien	    return true;
754190075Sobrien	}
754290075Sobrien      return false;
754390075Sobrien    }
754490075Sobrien  else
754590075Sobrien    return true;
754690075Sobrien}
754790075Sobrien
754890075Sobrien/* Return true if libcall is dead as a whole.  */
754990075Sobrien
755090075Sobrienstatic bool
755190075Sobriendead_libcall_p (insn)
755290075Sobrien     rtx insn;
755390075Sobrien{
755490075Sobrien  rtx note;
755590075Sobrien  /* See if there's a REG_EQUAL note on this insn and try to
755690075Sobrien     replace the source with the REG_EQUAL expression.
755790075Sobrien
755890075Sobrien     We assume that insns with REG_RETVALs can only be reg->reg
755990075Sobrien     copies at this point.  */
756090075Sobrien  note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
756190075Sobrien  if (note)
756290075Sobrien    {
756390075Sobrien      rtx set = single_set (insn);
756490075Sobrien      rtx new = simplify_rtx (XEXP (note, 0));
756590075Sobrien
756690075Sobrien      if (!new)
756790075Sobrien	new = XEXP (note, 0);
756890075Sobrien
756990075Sobrien      if (set && validate_change (insn, &SET_SRC (set), new, 0))
757090075Sobrien	{
757190075Sobrien	  remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
757290075Sobrien	  return true;
757390075Sobrien	}
757490075Sobrien    }
757590075Sobrien  return false;
757690075Sobrien}
757790075Sobrien
757818334Speter/* Scan all the insns and delete any that are dead; i.e., they store a register
757918334Speter   that is never used or they copy a register to itself.
758018334Speter
758150397Sobrien   This is used to remove insns made obviously dead by cse, loop or other
758250397Sobrien   optimizations.  It improves the heuristics in loop since it won't try to
758350397Sobrien   move dead invariants out of loops or make givs for dead quantities.  The
758450397Sobrien   remaining passes of the compilation are also sped up.  */
758518334Speter
758618334Spetervoid
758790075Sobriendelete_trivially_dead_insns (insns, nreg, preserve_basic_blocks)
758818334Speter     rtx insns;
758918334Speter     int nreg;
759090075Sobrien     int preserve_basic_blocks;
759118334Speter{
759290075Sobrien  int *counts;
759318334Speter  rtx insn, prev;
759418334Speter  int i;
759550397Sobrien  int in_libcall = 0, dead_libcall = 0;
759690075Sobrien  basic_block bb;
759718334Speter
759818334Speter  /* First count the number of times each register is used.  */
759990075Sobrien  counts = (int *) xcalloc (nreg, sizeof (int));
760018334Speter  for (insn = next_real_insn (insns); insn; insn = next_real_insn (insn))
760118334Speter    count_reg_usage (insn, counts, NULL_RTX, 1);
760218334Speter
760318334Speter  /* Go from the last insn to the first and delete insns that only set unused
760418334Speter     registers or copy a register to itself.  As we delete an insn, remove
760590075Sobrien     usage counts for registers it uses.
760618334Speter
760790075Sobrien     The first jump optimization pass may leave a real insn as the last
760890075Sobrien     insn in the function.   We must not skip that insn or we may end
760990075Sobrien     up deleting code that is not really dead.  */
761090075Sobrien  insn = get_last_insn ();
761190075Sobrien  if (! INSN_P (insn))
761290075Sobrien    insn = prev_real_insn (insn);
761318334Speter
761490075Sobrien  if (!preserve_basic_blocks)
761590075Sobrien    for (; insn; insn = prev)
761690075Sobrien      {
761790075Sobrien	int live_insn = 0;
761850397Sobrien
761990075Sobrien	prev = prev_real_insn (insn);
762018334Speter
762190075Sobrien	/* Don't delete any insns that are part of a libcall block unless
762290075Sobrien	   we can delete the whole libcall block.
762318334Speter
762490075Sobrien	   Flow or loop might get confused if we did that.  Remember
762590075Sobrien	   that we are scanning backwards.  */
762690075Sobrien	if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
762790075Sobrien	  {
762890075Sobrien	    in_libcall = 1;
762918334Speter	    live_insn = 1;
763090075Sobrien	    dead_libcall = dead_libcall_p (insn);
763190075Sobrien	  }
763290075Sobrien	else if (in_libcall)
763390075Sobrien	  live_insn = ! dead_libcall;
763490075Sobrien	else
763590075Sobrien	  live_insn = insn_live_p (insn, counts);
763690075Sobrien
763790075Sobrien	/* If this is a dead insn, delete it and show registers in it aren't
763890075Sobrien	   being used.  */
763990075Sobrien
764090075Sobrien	if (! live_insn)
764118334Speter	  {
764290075Sobrien	    count_reg_usage (insn, counts, NULL_RTX, -1);
764390075Sobrien	    delete_related_insns (insn);
764490075Sobrien	  }
764518334Speter
764690075Sobrien	if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
764790075Sobrien	  {
764890075Sobrien	    in_libcall = 0;
764990075Sobrien	    dead_libcall = 0;
765090075Sobrien	  }
765190075Sobrien      }
765290075Sobrien  else
765390075Sobrien    for (i = 0; i < n_basic_blocks; i++)
765490075Sobrien      for (bb = BASIC_BLOCK (i), insn = bb->end; insn != bb->head; insn = prev)
765590075Sobrien	{
765690075Sobrien	  int live_insn = 0;
765718334Speter
765890075Sobrien	  prev = PREV_INSN (insn);
765990075Sobrien	  if (!INSN_P (insn))
766090075Sobrien	    continue;
766190075Sobrien
766290075Sobrien	  /* Don't delete any insns that are part of a libcall block unless
766390075Sobrien	     we can delete the whole libcall block.
766490075Sobrien
766590075Sobrien	     Flow or loop might get confused if we did that.  Remember
766690075Sobrien	     that we are scanning backwards.  */
766790075Sobrien	  if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
766890075Sobrien	    {
766990075Sobrien	      in_libcall = 1;
767018334Speter	      live_insn = 1;
767190075Sobrien	      dead_libcall = dead_libcall_p (insn);
767290075Sobrien	    }
767390075Sobrien	  else if (in_libcall)
767490075Sobrien	    live_insn = ! dead_libcall;
767590075Sobrien	  else
767690075Sobrien	    live_insn = insn_live_p (insn, counts);
767718334Speter
767890075Sobrien	  /* If this is a dead insn, delete it and show registers in it aren't
767990075Sobrien	     being used.  */
768018334Speter
768190075Sobrien	  if (! live_insn)
768290075Sobrien	    {
768390075Sobrien	      count_reg_usage (insn, counts, NULL_RTX, -1);
768490075Sobrien	      delete_insn (insn);
768590075Sobrien	    }
768690075Sobrien
768790075Sobrien	  if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
768890075Sobrien	    {
768990075Sobrien	      in_libcall = 0;
769090075Sobrien	      dead_libcall = 0;
769190075Sobrien	    }
769218334Speter	}
769318334Speter
769490075Sobrien  /* Clean up.  */
769590075Sobrien  free (counts);
769618334Speter}
7697