118334Speter/* Common subexpression elimination for GNU compiler.
290075Sobrien   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
3169689Skan   1999, 2000, 2001, 2002, 2003, 2004, 2005 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
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
2118334Speter
2218334Speter#include "config.h"
2350397Sobrien/* stdio.h must precede rtl.h for FFS.  */
2450397Sobrien#include "system.h"
25132718Skan#include "coretypes.h"
26132718Skan#include "tm.h"
2718334Speter#include "rtl.h"
2890075Sobrien#include "tm_p.h"
29169689Skan#include "hard-reg-set.h"
3018334Speter#include "regs.h"
3190075Sobrien#include "basic-block.h"
3218334Speter#include "flags.h"
3318334Speter#include "real.h"
3418334Speter#include "insn-config.h"
3518334Speter#include "recog.h"
3690075Sobrien#include "function.h"
3750397Sobrien#include "expr.h"
3850397Sobrien#include "toplev.h"
3950397Sobrien#include "output.h"
4090075Sobrien#include "ggc.h"
41117395Skan#include "timevar.h"
42132718Skan#include "except.h"
43132718Skan#include "target.h"
44132718Skan#include "params.h"
45169689Skan#include "rtlhooks-def.h"
46169689Skan#include "tree-pass.h"
4718334Speter
4818334Speter/* The basic idea of common subexpression elimination is to go
4918334Speter   through the code, keeping a record of expressions that would
5018334Speter   have the same value at the current scan point, and replacing
5118334Speter   expressions encountered with the cheapest equivalent expression.
5218334Speter
5318334Speter   It is too complicated to keep track of the different possibilities
5456385Sobrien   when control paths merge in this code; so, at each label, we forget all
5556385Sobrien   that is known and start fresh.  This can be described as processing each
5656385Sobrien   extended basic block separately.  We have a separate pass to perform
5756385Sobrien   global CSE.
5818334Speter
5956385Sobrien   Note CSE can turn a conditional or computed jump into a nop or
6056385Sobrien   an unconditional jump.  When this occurs we arrange to run the jump
6156385Sobrien   optimizer after CSE to delete the unreachable code.
6256385Sobrien
6318334Speter   We use two data structures to record the equivalent expressions:
6490075Sobrien   a hash table for most expressions, and a vector of "quantity
6590075Sobrien   numbers" to record equivalent (pseudo) registers.
6618334Speter
6718334Speter   The use of the special data structure for registers is desirable
6818334Speter   because it is faster.  It is possible because registers references
6918334Speter   contain a fairly small number, the register number, taken from
7018334Speter   a contiguously allocated series, and two register references are
7118334Speter   identical if they have the same number.  General expressions
7218334Speter   do not have any such thing, so the only way to retrieve the
7318334Speter   information recorded on an expression other than a register
7418334Speter   is to keep it in a hash table.
7518334Speter
7618334SpeterRegisters and "quantity numbers":
7790075Sobrien
7818334Speter   At the start of each basic block, all of the (hardware and pseudo)
7918334Speter   registers used in the function are given distinct quantity
8018334Speter   numbers to indicate their contents.  During scan, when the code
8118334Speter   copies one register into another, we copy the quantity number.
8218334Speter   When a register is loaded in any other way, we allocate a new
8318334Speter   quantity number to describe the value generated by this operation.
84169689Skan   `REG_QTY (N)' records what quantity register N is currently thought
8518334Speter   of as containing.
8618334Speter
87146895Skan   All real quantity numbers are greater than or equal to zero.
88169689Skan   If register N has not been assigned a quantity, `REG_QTY (N)' will
89146895Skan   equal -N - 1, which is always negative.
9018334Speter
91146895Skan   Quantity numbers below zero do not exist and none of the `qty_table'
92146895Skan   entries should be referenced with a negative index.
9318334Speter
9418334Speter   We also maintain a bidirectional chain of registers for each
9590075Sobrien   quantity number.  The `qty_table` members `first_reg' and `last_reg',
9690075Sobrien   and `reg_eqv_table' members `next' and `prev' hold these chains.
9718334Speter
9818334Speter   The first register in a chain is the one whose lifespan is least local.
9918334Speter   Among equals, it is the one that was seen first.
10018334Speter   We replace any equivalent register with that one.
10118334Speter
10218334Speter   If two registers have the same quantity number, it must be true that
10390075Sobrien   REG expressions with qty_table `mode' must be in the hash table for both
10418334Speter   registers and must be in the same class.
10518334Speter
10618334Speter   The converse is not true.  Since hard registers may be referenced in
10718334Speter   any mode, two REG expressions might be equivalent in the hash table
10818334Speter   but not have the same quantity number if the quantity number of one
10918334Speter   of the registers is not the same mode as those expressions.
11090075Sobrien
11118334SpeterConstants and quantity numbers
11218334Speter
11318334Speter   When a quantity has a known constant value, that value is stored
11490075Sobrien   in the appropriate qty_table `const_rtx'.  This is in addition to
11518334Speter   putting the constant in the hash table as is usual for non-regs.
11618334Speter
11718334Speter   Whether a reg or a constant is preferred is determined by the configuration
11818334Speter   macro CONST_COSTS and will often depend on the constant value.  In any
11918334Speter   event, expressions containing constants can be simplified, by fold_rtx.
12018334Speter
12118334Speter   When a quantity has a known nearly constant value (such as an address
12290075Sobrien   of a stack slot), that value is stored in the appropriate qty_table
12390075Sobrien   `const_rtx'.
12418334Speter
12518334Speter   Integer constants don't have a machine mode.  However, cse
12618334Speter   determines the intended machine mode from the destination
12718334Speter   of the instruction that moves the constant.  The machine mode
12818334Speter   is recorded in the hash table along with the actual RTL
12918334Speter   constant expression so that different modes are kept separate.
13018334Speter
13118334SpeterOther expressions:
13218334Speter
13318334Speter   To record known equivalences among expressions in general
13418334Speter   we use a hash table called `table'.  It has a fixed number of buckets
13518334Speter   that contain chains of `struct table_elt' elements for expressions.
13618334Speter   These chains connect the elements whose expressions have the same
13718334Speter   hash codes.
13818334Speter
13918334Speter   Other chains through the same elements connect the elements which
14018334Speter   currently have equivalent values.
14118334Speter
14218334Speter   Register references in an expression are canonicalized before hashing
14390075Sobrien   the expression.  This is done using `reg_qty' and qty_table `first_reg'.
14418334Speter   The hash code of a register reference is computed using the quantity
14518334Speter   number, not the register number.
14618334Speter
14718334Speter   When the value of an expression changes, it is necessary to remove from the
14818334Speter   hash table not just that expression but all expressions whose values
14918334Speter   could be different as a result.
15018334Speter
15118334Speter     1. If the value changing is in memory, except in special cases
15218334Speter     ANYTHING referring to memory could be changed.  That is because
15318334Speter     nobody knows where a pointer does not point.
15418334Speter     The function `invalidate_memory' removes what is necessary.
15518334Speter
15618334Speter     The special cases are when the address is constant or is
15718334Speter     a constant plus a fixed register such as the frame pointer
15818334Speter     or a static chain pointer.  When such addresses are stored in,
15918334Speter     we can tell exactly which other such addresses must be invalidated
16018334Speter     due to overlap.  `invalidate' does this.
16118334Speter     All expressions that refer to non-constant
16218334Speter     memory addresses are also invalidated.  `invalidate_memory' does this.
16318334Speter
16418334Speter     2. If the value changing is a register, all expressions
16518334Speter     containing references to that register, and only those,
16618334Speter     must be removed.
16718334Speter
16818334Speter   Because searching the entire hash table for expressions that contain
16918334Speter   a register is very slow, we try to figure out when it isn't necessary.
17018334Speter   Precisely, this is necessary only when expressions have been
17118334Speter   entered in the hash table using this register, and then the value has
17218334Speter   changed, and then another expression wants to be added to refer to
17318334Speter   the register's new value.  This sequence of circumstances is rare
17418334Speter   within any one basic block.
17518334Speter
176169689Skan   `REG_TICK' and `REG_IN_TABLE', accessors for members of
177169689Skan   cse_reg_info, are used to detect this case.  REG_TICK (i) is
178169689Skan   incremented whenever a value is stored in register i.
179169689Skan   REG_IN_TABLE (i) holds -1 if no references to register i have been
180169689Skan   entered in the table; otherwise, it contains the value REG_TICK (i)
181169689Skan   had when the references were entered.  If we want to enter a
182169689Skan   reference and REG_IN_TABLE (i) != REG_TICK (i), we must scan and
183169689Skan   remove old references.  Until we want to enter a new entry, the
184169689Skan   mere fact that the two vectors don't match makes the entries be
185169689Skan   ignored if anyone tries to match them.
18618334Speter
18718334Speter   Registers themselves are entered in the hash table as well as in
188169689Skan   the equivalent-register chains.  However, `REG_TICK' and
189169689Skan   `REG_IN_TABLE' do not apply to expressions which are simple
19018334Speter   register references.  These expressions are removed from the table
19118334Speter   immediately when they become invalid, and this can be done even if
19218334Speter   we do not immediately search for all the expressions that refer to
19318334Speter   the register.
19418334Speter
19518334Speter   A CLOBBER rtx in an instruction invalidates its operand for further
19618334Speter   reuse.  A CLOBBER or SET rtx whose operand is a MEM:BLK
19718334Speter   invalidates everything that resides in memory.
19818334Speter
19918334SpeterRelated expressions:
20018334Speter
20118334Speter   Constant expressions that differ only by an additive integer
20218334Speter   are called related.  When a constant expression is put in
20318334Speter   the table, the related expression with no constant term
20418334Speter   is also entered.  These are made to point at each other
20518334Speter   so that it is possible to find out if there exists any
20618334Speter   register equivalent to an expression related to a given expression.  */
20790075Sobrien
20890075Sobrien/* Length of qty_table vector.  We know in advance we will not need
20990075Sobrien   a quantity number this big.  */
21018334Speter
21118334Speterstatic int max_qty;
21218334Speter
21318334Speter/* Next quantity number to be allocated.
21418334Speter   This is 1 + the largest number needed so far.  */
21518334Speter
21618334Speterstatic int next_qty;
21718334Speter
21890075Sobrien/* Per-qty information tracking.
21918334Speter
22090075Sobrien   `first_reg' and `last_reg' track the head and tail of the
22190075Sobrien   chain of registers which currently contain this quantity.
22218334Speter
22390075Sobrien   `mode' contains the machine mode of this quantity.
22418334Speter
22590075Sobrien   `const_rtx' holds the rtx of the constant value of this
22690075Sobrien   quantity, if known.  A summations of the frame/arg pointer
22790075Sobrien   and a constant can also be entered here.  When this holds
22890075Sobrien   a known value, `const_insn' is the insn which stored the
22990075Sobrien   constant value.
23018334Speter
23190075Sobrien   `comparison_{code,const,qty}' are used to track when a
23290075Sobrien   comparison between a quantity and some constant or register has
23390075Sobrien   been passed.  In such a case, we know the results of the comparison
23490075Sobrien   in case we see it again.  These members record a comparison that
23590075Sobrien   is known to be true.  `comparison_code' holds the rtx code of such
23690075Sobrien   a comparison, else it is set to UNKNOWN and the other two
23790075Sobrien   comparison members are undefined.  `comparison_const' holds
23890075Sobrien   the constant being compared against, or zero if the comparison
23990075Sobrien   is not against a constant.  `comparison_qty' holds the quantity
24090075Sobrien   being compared against when the result is known.  If the comparison
24190075Sobrien   is not with a register, `comparison_qty' is -1.  */
24218334Speter
24390075Sobrienstruct qty_table_elem
24490075Sobrien{
24590075Sobrien  rtx const_rtx;
24690075Sobrien  rtx const_insn;
24790075Sobrien  rtx comparison_const;
24890075Sobrien  int comparison_qty;
24990075Sobrien  unsigned int first_reg, last_reg;
250132718Skan  /* The sizes of these fields should match the sizes of the
251132718Skan     code and mode fields of struct rtx_def (see rtl.h).  */
252132718Skan  ENUM_BITFIELD(rtx_code) comparison_code : 16;
253132718Skan  ENUM_BITFIELD(machine_mode) mode : 8;
25490075Sobrien};
25518334Speter
25690075Sobrien/* The table of all qtys, indexed by qty number.  */
25790075Sobrienstatic struct qty_table_elem *qty_table;
25818334Speter
259169689Skan/* Structure used to pass arguments via for_each_rtx to function
260169689Skan   cse_change_cc_mode.  */
261169689Skanstruct change_cc_mode_args
262169689Skan{
263169689Skan  rtx insn;
264169689Skan  rtx newreg;
265169689Skan};
266169689Skan
26718334Speter#ifdef HAVE_cc0
26818334Speter/* For machines that have a CC0, we do not record its value in the hash
26918334Speter   table since its use is guaranteed to be the insn immediately following
27018334Speter   its definition and any other insn is presumed to invalidate it.
27118334Speter
27218334Speter   Instead, we store below the value last assigned to CC0.  If it should
27318334Speter   happen to be a constant, it is stored in preference to the actual
27418334Speter   assigned value.  In case it is a constant, we store the mode in which
27518334Speter   the constant should be interpreted.  */
27618334Speter
27718334Speterstatic rtx prev_insn_cc0;
27818334Speterstatic enum machine_mode prev_insn_cc0_mode;
27918334Speter
28018334Speter/* Previous actual insn.  0 if at first insn of basic block.  */
28118334Speter
28218334Speterstatic rtx prev_insn;
283132718Skan#endif
28418334Speter
28518334Speter/* Insn being scanned.  */
28618334Speter
28718334Speterstatic rtx this_insn;
28818334Speter
28950397Sobrien/* Index by register number, gives the number of the next (or
29050397Sobrien   previous) register in the chain of registers sharing the same
29118334Speter   value.
29218334Speter
29318334Speter   Or -1 if this register is at the end of the chain.
29418334Speter
295169689Skan   If REG_QTY (N) == -N - 1, reg_eqv_table[N].next is undefined.  */
29618334Speter
29790075Sobrien/* Per-register equivalence chain.  */
29890075Sobrienstruct reg_eqv_elem
29990075Sobrien{
30090075Sobrien  int next, prev;
30190075Sobrien};
30218334Speter
30390075Sobrien/* The table of all register equivalence chains.  */
30490075Sobrienstatic struct reg_eqv_elem *reg_eqv_table;
30518334Speter
30690075Sobrienstruct cse_reg_info
30790075Sobrien{
308169689Skan  /* The timestamp at which this register is initialized.  */
309169689Skan  unsigned int timestamp;
31090075Sobrien
31190075Sobrien  /* The quantity number of the register's current contents.  */
31290075Sobrien  int reg_qty;
31390075Sobrien
31490075Sobrien  /* The number of times the register has been altered in the current
31590075Sobrien     basic block.  */
31690075Sobrien  int reg_tick;
31790075Sobrien
31852284Sobrien  /* The REG_TICK value at which rtx's containing this register are
31952284Sobrien     valid in the hash table.  If this does not equal the current
32052284Sobrien     reg_tick value, such expressions existing in the hash table are
32152284Sobrien     invalid.  */
32252284Sobrien  int reg_in_table;
323117395Skan
324117395Skan  /* The SUBREG that was set when REG_TICK was last incremented.  Set
325117395Skan     to -1 if the last store was to the whole register, not a subreg.  */
326117395Skan  unsigned int subreg_ticked;
32752284Sobrien};
32818334Speter
329169689Skan/* A table of cse_reg_info indexed by register numbers.  */
330169689Skanstatic struct cse_reg_info *cse_reg_info_table;
33118334Speter
332169689Skan/* The size of the above table.  */
333169689Skanstatic unsigned int cse_reg_info_table_size;
33490075Sobrien
335169689Skan/* The index of the first entry that has not been initialized.  */
336169689Skanstatic unsigned int cse_reg_info_table_first_uninitialized;
33752284Sobrien
338169689Skan/* The timestamp at the beginning of the current run of
339169689Skan   cse_basic_block.  We increment this variable at the beginning of
340169689Skan   the current run of cse_basic_block.  The timestamp field of a
341169689Skan   cse_reg_info entry matches the value of this variable if and only
342169689Skan   if the entry has been initialized during the current run of
343169689Skan   cse_basic_block.  */
344169689Skanstatic unsigned int cse_reg_info_timestamp;
34590075Sobrien
34690075Sobrien/* A HARD_REG_SET containing all the hard registers for which there is
34718334Speter   currently a REG expression in the hash table.  Note the difference
34818334Speter   from the above variables, which indicate if the REG is mentioned in some
34918334Speter   expression in the table.  */
35018334Speter
35118334Speterstatic HARD_REG_SET hard_regs_in_table;
35218334Speter
35318334Speter/* CUID of insn that starts the basic block currently being cse-processed.  */
35418334Speter
35518334Speterstatic int cse_basic_block_start;
35618334Speter
35718334Speter/* CUID of insn that ends the basic block currently being cse-processed.  */
35818334Speter
35918334Speterstatic int cse_basic_block_end;
36018334Speter
36118334Speter/* Vector mapping INSN_UIDs to cuids.
36218334Speter   The cuids are like uids but increase monotonically always.
36318334Speter   We use them to see whether a reg is used outside a given basic block.  */
36418334Speter
36518334Speterstatic int *uid_cuid;
36618334Speter
36718334Speter/* Highest UID in UID_CUID.  */
36818334Speterstatic int max_uid;
36918334Speter
37018334Speter/* Get the cuid of an insn.  */
37118334Speter
37218334Speter#define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])
37318334Speter
37490075Sobrien/* Nonzero if this pass has made changes, and therefore it's
37590075Sobrien   worthwhile to run the garbage collector.  */
37690075Sobrien
37790075Sobrienstatic int cse_altered;
37890075Sobrien
37918334Speter/* Nonzero if cse has altered conditional jump insns
38018334Speter   in such a way that jump optimization should be redone.  */
38118334Speter
38218334Speterstatic int cse_jumps_altered;
38318334Speter
38490075Sobrien/* Nonzero if we put a LABEL_REF into the hash table for an INSN without a
38590075Sobrien   REG_LABEL, we have to rerun jump after CSE to put in the note.  */
38618334Speterstatic int recorded_label_ref;
38718334Speter
38818334Speter/* canon_hash stores 1 in do_not_record
38918334Speter   if it notices a reference to CC0, PC, or some other volatile
39018334Speter   subexpression.  */
39118334Speter
39218334Speterstatic int do_not_record;
39318334Speter
39418334Speter/* canon_hash stores 1 in hash_arg_in_memory
39518334Speter   if it notices a reference to memory within the expression being hashed.  */
39618334Speter
39718334Speterstatic int hash_arg_in_memory;
39818334Speter
39918334Speter/* The hash table contains buckets which are chains of `struct table_elt's,
40018334Speter   each recording one expression's information.
40118334Speter   That expression is in the `exp' field.
40218334Speter
40390075Sobrien   The canon_exp field contains a canonical (from the point of view of
40490075Sobrien   alias analysis) version of the `exp' field.
40590075Sobrien
40618334Speter   Those elements with the same hash code are chained in both directions
40718334Speter   through the `next_same_hash' and `prev_same_hash' fields.
40818334Speter
40918334Speter   Each set of expressions with equivalent values
41018334Speter   are on a two-way chain through the `next_same_value'
41118334Speter   and `prev_same_value' fields, and all point with
41218334Speter   the `first_same_value' field at the first element in
41318334Speter   that chain.  The chain is in order of increasing cost.
41418334Speter   Each element's cost value is in its `cost' field.
41518334Speter
41618334Speter   The `in_memory' field is nonzero for elements that
41718334Speter   involve any reference to memory.  These elements are removed
41818334Speter   whenever a write is done to an unidentified location in memory.
41918334Speter   To be safe, we assume that a memory address is unidentified unless
42018334Speter   the address is either a symbol constant or a constant plus
42118334Speter   the frame pointer or argument pointer.
42218334Speter
42318334Speter   The `related_value' field is used to connect related expressions
42418334Speter   (that differ by adding an integer).
42518334Speter   The related expressions are chained in a circular fashion.
42618334Speter   `related_value' is zero for expressions for which this
42718334Speter   chain is not useful.
42818334Speter
42918334Speter   The `cost' field stores the cost of this element's expression.
43090075Sobrien   The `regcost' field stores the value returned by approx_reg_cost for
43190075Sobrien   this element's expression.
43218334Speter
43318334Speter   The `is_const' flag is set if the element is a constant (including
43418334Speter   a fixed address).
43518334Speter
43618334Speter   The `flag' field is used as a temporary during some search routines.
43718334Speter
43818334Speter   The `mode' field is usually the same as GET_MODE (`exp'), but
43918334Speter   if `exp' is a CONST_INT and has no machine mode then the `mode'
44018334Speter   field is the mode it was being used as.  Each constant is
44118334Speter   recorded separately for each mode it is used with.  */
44218334Speter
44318334Speterstruct table_elt
44418334Speter{
44518334Speter  rtx exp;
44690075Sobrien  rtx canon_exp;
44718334Speter  struct table_elt *next_same_hash;
44818334Speter  struct table_elt *prev_same_hash;
44918334Speter  struct table_elt *next_same_value;
45018334Speter  struct table_elt *prev_same_value;
45118334Speter  struct table_elt *first_same_value;
45218334Speter  struct table_elt *related_value;
45318334Speter  int cost;
45490075Sobrien  int regcost;
455132718Skan  /* The size of this field should match the size
456132718Skan     of the mode field of struct rtx_def (see rtl.h).  */
457132718Skan  ENUM_BITFIELD(machine_mode) mode : 8;
45818334Speter  char in_memory;
45918334Speter  char is_const;
46018334Speter  char flag;
46118334Speter};
46218334Speter
46318334Speter/* We don't want a lot of buckets, because we rarely have very many
46418334Speter   things stored in the hash table, and a lot of buckets slows
46518334Speter   down a lot of loops that happen frequently.  */
46690075Sobrien#define HASH_SHIFT	5
46790075Sobrien#define HASH_SIZE	(1 << HASH_SHIFT)
46890075Sobrien#define HASH_MASK	(HASH_SIZE - 1)
46918334Speter
47018334Speter/* Compute hash code of X in mode M.  Special-case case where X is a pseudo
47118334Speter   register (hard registers may require `do_not_record' to be set).  */
47218334Speter
47318334Speter#define HASH(X, M)	\
474169689Skan ((REG_P (X) && REGNO (X) >= FIRST_PSEUDO_REGISTER	\
47590075Sobrien  ? (((unsigned) REG << 7) + (unsigned) REG_QTY (REGNO (X)))	\
47690075Sobrien  : canon_hash (X, M)) & HASH_MASK)
47718334Speter
478169689Skan/* Like HASH, but without side-effects.  */
479169689Skan#define SAFE_HASH(X, M)	\
480169689Skan ((REG_P (X) && REGNO (X) >= FIRST_PSEUDO_REGISTER	\
481169689Skan  ? (((unsigned) REG << 7) + (unsigned) REG_QTY (REGNO (X)))	\
482169689Skan  : safe_hash (X, M)) & HASH_MASK)
483169689Skan
48490075Sobrien/* Determine whether register number N is considered a fixed register for the
48590075Sobrien   purpose of approximating register costs.
48618334Speter   It is desirable to replace other regs with fixed regs, to reduce need for
48718334Speter   non-fixed hard regs.
48890075Sobrien   A reg wins if it is either the frame pointer or designated as fixed.  */
48918334Speter#define FIXED_REGNO_P(N)  \
49018334Speter  ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \
49118334Speter   || fixed_regs[N] || global_regs[N])
49218334Speter
49318334Speter/* Compute cost of X, as stored in the `cost' field of a table_elt.  Fixed
49418334Speter   hard registers and pointers into the frame are the cheapest with a cost
49518334Speter   of 0.  Next come pseudos with a cost of one and other hard registers with
49618334Speter   a cost of 2.  Aside from these special cases, call `rtx_cost'.  */
49718334Speter
498169689Skan#define CHEAP_REGNO(N)							\
499169689Skan  (REGNO_PTR_FRAME_P(N)							\
500169689Skan   || (HARD_REGISTER_NUM_P (N)						\
50118334Speter       && FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS))
50218334Speter
503169689Skan#define COST(X) (REG_P (X) ? 0 : notreg_cost (X, SET))
504169689Skan#define COST_IN(X,OUTER) (REG_P (X) ? 0 : notreg_cost (X, OUTER))
50518334Speter
50652284Sobrien/* Get the number of times this register has been updated in this
50752284Sobrien   basic block.  */
50852284Sobrien
509169689Skan#define REG_TICK(N) (get_cse_reg_info (N)->reg_tick)
51052284Sobrien
51152284Sobrien/* Get the point at which REG was recorded in the table.  */
51252284Sobrien
513169689Skan#define REG_IN_TABLE(N) (get_cse_reg_info (N)->reg_in_table)
51452284Sobrien
515117395Skan/* Get the SUBREG set at the last increment to REG_TICK (-1 if not a
516117395Skan   SUBREG).  */
517117395Skan
518169689Skan#define SUBREG_TICKED(N) (get_cse_reg_info (N)->subreg_ticked)
519117395Skan
52052284Sobrien/* Get the quantity number for REG.  */
52152284Sobrien
522169689Skan#define REG_QTY(N) (get_cse_reg_info (N)->reg_qty)
52352284Sobrien
52418334Speter/* Determine if the quantity number for register X represents a valid index
52590075Sobrien   into the qty_table.  */
52618334Speter
527146895Skan#define REGNO_QTY_VALID_P(N) (REG_QTY (N) >= 0)
52818334Speter
52990075Sobrienstatic struct table_elt *table[HASH_SIZE];
53050397Sobrien
531169689Skan/* Number of elements in the hash table.  */
532169689Skan
533169689Skanstatic unsigned int table_size;
534169689Skan
53518334Speter/* Chain of `struct table_elt's made so far for this function
53618334Speter   but currently removed from the table.  */
53718334Speter
53818334Speterstatic struct table_elt *free_element_chain;
53918334Speter
54018334Speter/* Set to the cost of a constant pool reference if one was found for a
54118334Speter   symbolic constant.  If this was found, it means we should try to
54218334Speter   convert constants into constant pool entries if they don't fit in
54318334Speter   the insn.  */
54418334Speter
54518334Speterstatic int constant_pool_entries_cost;
546132718Skanstatic int constant_pool_entries_regcost;
54718334Speter
54818334Speter/* This data describes a block that will be processed by cse_basic_block.  */
54918334Speter
55090075Sobrienstruct cse_basic_block_data
55190075Sobrien{
55218334Speter  /* Lowest CUID value of insns in block.  */
55318334Speter  int low_cuid;
55418334Speter  /* Highest CUID value of insns in block.  */
55518334Speter  int high_cuid;
55618334Speter  /* Total number of SETs in block.  */
55718334Speter  int nsets;
55818334Speter  /* Last insn in the block.  */
55918334Speter  rtx last;
56018334Speter  /* Size of current branch path, if any.  */
56118334Speter  int path_size;
56218334Speter  /* Current branch path, indicating which branches will be taken.  */
56390075Sobrien  struct branch_path
56490075Sobrien    {
56590075Sobrien      /* The branch insn.  */
56690075Sobrien      rtx branch;
56790075Sobrien      /* Whether it should be taken or not.  AROUND is the same as taken
56890075Sobrien	 except that it is used when the destination label is not preceded
56918334Speter       by a BARRIER.  */
570169689Skan      enum taken {PATH_TAKEN, PATH_NOT_TAKEN, PATH_AROUND} status;
571132718Skan    } *path;
57218334Speter};
57318334Speter
574132718Skanstatic bool fixed_base_plus_p (rtx x);
575132718Skanstatic int notreg_cost (rtx, enum rtx_code);
576132718Skanstatic int approx_reg_cost_1 (rtx *, void *);
577132718Skanstatic int approx_reg_cost (rtx);
578169689Skanstatic int preferable (int, int, int, int);
579132718Skanstatic void new_basic_block (void);
580132718Skanstatic void make_new_qty (unsigned int, enum machine_mode);
581132718Skanstatic void make_regs_eqv (unsigned int, unsigned int);
582132718Skanstatic void delete_reg_equiv (unsigned int);
583132718Skanstatic int mention_regs (rtx);
584132718Skanstatic int insert_regs (rtx, struct table_elt *, int);
585132718Skanstatic void remove_from_table (struct table_elt *, unsigned);
586235965Spfgstatic void remove_pseudo_from_table (rtx, unsigned);
587235965Spfgstatic struct table_elt *lookup (rtx, unsigned, enum machine_mode);
588132718Skanstatic struct table_elt *lookup_for_remove (rtx, unsigned, enum machine_mode);
589132718Skanstatic rtx lookup_as_function (rtx, enum rtx_code);
590132718Skanstatic struct table_elt *insert (rtx, struct table_elt *, unsigned,
591132718Skan				 enum machine_mode);
592132718Skanstatic void merge_equiv_classes (struct table_elt *, struct table_elt *);
593132718Skanstatic void invalidate (rtx, enum machine_mode);
594132718Skanstatic int cse_rtx_varies_p (rtx, int);
595132718Skanstatic void remove_invalid_refs (unsigned int);
596132718Skanstatic void remove_invalid_subreg_refs (unsigned int, unsigned int,
597132718Skan					enum machine_mode);
598132718Skanstatic void rehash_using_reg (rtx);
599132718Skanstatic void invalidate_memory (void);
600132718Skanstatic void invalidate_for_call (void);
601132718Skanstatic rtx use_related_value (rtx, struct table_elt *);
602169689Skan
603169689Skanstatic inline unsigned canon_hash (rtx, enum machine_mode);
604169689Skanstatic inline unsigned safe_hash (rtx, enum machine_mode);
605169689Skanstatic unsigned hash_rtx_string (const char *);
606169689Skan
607132718Skanstatic rtx canon_reg (rtx, rtx);
608132718Skanstatic void find_best_addr (rtx, rtx *, enum machine_mode);
609132718Skanstatic enum rtx_code find_comparison_args (enum rtx_code, rtx *, rtx *,
610132718Skan					   enum machine_mode *,
611132718Skan					   enum machine_mode *);
612132718Skanstatic rtx fold_rtx (rtx, rtx);
613132718Skanstatic rtx equiv_constant (rtx);
614132718Skanstatic void record_jump_equiv (rtx, int);
615132718Skanstatic void record_jump_cond (enum rtx_code, enum machine_mode, rtx, rtx,
616132718Skan			      int);
617132718Skanstatic void cse_insn (rtx, rtx);
618169689Skanstatic void cse_end_of_basic_block (rtx, struct cse_basic_block_data *,
619169689Skan				    int, int);
620132718Skanstatic int addr_affects_sp_p (rtx);
621132718Skanstatic void invalidate_from_clobbers (rtx);
622132718Skanstatic rtx cse_process_notes (rtx, rtx);
623132718Skanstatic void invalidate_skipped_set (rtx, rtx, void *);
624132718Skanstatic void invalidate_skipped_block (rtx);
625169689Skanstatic rtx cse_basic_block (rtx, rtx, struct branch_path *);
626169689Skanstatic void count_reg_usage (rtx, int *, rtx, int);
627132718Skanstatic int check_for_label_ref (rtx *, void *);
628132718Skanextern void dump_class (struct table_elt*);
629169689Skanstatic void get_cse_reg_info_1 (unsigned int regno);
630169689Skanstatic struct cse_reg_info * get_cse_reg_info (unsigned int regno);
631132718Skanstatic int check_dependence (rtx *, void *);
632132718Skan
633132718Skanstatic void flush_hash_table (void);
634132718Skanstatic bool insn_live_p (rtx, int *);
635132718Skanstatic bool set_live_p (rtx, rtx, int *);
636132718Skanstatic bool dead_libcall_p (rtx, int *);
637132718Skanstatic int cse_change_cc_mode (rtx *, void *);
638169689Skanstatic void cse_change_cc_mode_insn (rtx, rtx);
639132718Skanstatic void cse_change_cc_mode_insns (rtx, rtx, rtx);
640132718Skanstatic enum machine_mode cse_cc_succs (basic_block, rtx, rtx, bool);
641132718Skan
642169689Skan
643169689Skan#undef RTL_HOOKS_GEN_LOWPART
644169689Skan#define RTL_HOOKS_GEN_LOWPART		gen_lowpart_if_possible
645169689Skan
646169689Skanstatic const struct rtl_hooks cse_rtl_hooks = RTL_HOOKS_INITIALIZER;
647169689Skan
64818334Speter/* Nonzero if X has the form (PLUS frame-pointer integer).  We check for
64918334Speter   virtual regs here because the simplify_*_operation routines are called
650132718Skan   by integrate.c, which is called before virtual register instantiation.  */
65118334Speter
652132718Skanstatic bool
653132718Skanfixed_base_plus_p (rtx x)
654132718Skan{
655132718Skan  switch (GET_CODE (x))
656132718Skan    {
657132718Skan    case REG:
658132718Skan      if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx)
659132718Skan	return true;
660132718Skan      if (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM])
661132718Skan	return true;
662132718Skan      if (REGNO (x) >= FIRST_VIRTUAL_REGISTER
663132718Skan	  && REGNO (x) <= LAST_VIRTUAL_REGISTER)
664132718Skan	return true;
665132718Skan      return false;
66690075Sobrien
667132718Skan    case PLUS:
668132718Skan      if (GET_CODE (XEXP (x, 1)) != CONST_INT)
669132718Skan	return false;
670132718Skan      return fixed_base_plus_p (XEXP (x, 0));
67118334Speter
672132718Skan    default:
673132718Skan      return false;
674132718Skan    }
675132718Skan}
67618334Speter
67752284Sobrien/* Dump the expressions in the equivalence class indicated by CLASSP.
67852284Sobrien   This function is used only for debugging.  */
67952284Sobrienvoid
680132718Skandump_class (struct table_elt *classp)
68152284Sobrien{
68252284Sobrien  struct table_elt *elt;
68352284Sobrien
68452284Sobrien  fprintf (stderr, "Equivalence chain for ");
68552284Sobrien  print_rtl (stderr, classp->exp);
68652284Sobrien  fprintf (stderr, ": \n");
68790075Sobrien
68852284Sobrien  for (elt = classp->first_same_value; elt; elt = elt->next_same_value)
68952284Sobrien    {
69052284Sobrien      print_rtl (stderr, elt->exp);
69152284Sobrien      fprintf (stderr, "\n");
69252284Sobrien    }
69352284Sobrien}
69452284Sobrien
69590075Sobrien/* Subroutine of approx_reg_cost; called through for_each_rtx.  */
69618334Speter
69790075Sobrienstatic int
698132718Skanapprox_reg_cost_1 (rtx *xp, void *data)
69990075Sobrien{
70090075Sobrien  rtx x = *xp;
701117395Skan  int *cost_p = data;
70290075Sobrien
703169689Skan  if (x && REG_P (x))
704117395Skan    {
705117395Skan      unsigned int regno = REGNO (x);
706117395Skan
707117395Skan      if (! CHEAP_REGNO (regno))
708117395Skan	{
709117395Skan	  if (regno < FIRST_PSEUDO_REGISTER)
710117395Skan	    {
711117395Skan	      if (SMALL_REGISTER_CLASSES)
712117395Skan		return 1;
713117395Skan	      *cost_p += 2;
714117395Skan	    }
715117395Skan	  else
716117395Skan	    *cost_p += 1;
717117395Skan	}
718117395Skan    }
719117395Skan
72090075Sobrien  return 0;
72190075Sobrien}
72290075Sobrien
72390075Sobrien/* Return an estimate of the cost of the registers used in an rtx.
72490075Sobrien   This is mostly the number of different REG expressions in the rtx;
72590075Sobrien   however for some exceptions like fixed registers we use a cost of
72690075Sobrien   0.  If any other hard register reference occurs, return MAX_COST.  */
72790075Sobrien
72890075Sobrienstatic int
729132718Skanapprox_reg_cost (rtx x)
73090075Sobrien{
73190075Sobrien  int cost = 0;
73290075Sobrien
733117395Skan  if (for_each_rtx (&x, approx_reg_cost_1, (void *) &cost))
734117395Skan    return MAX_COST;
73590075Sobrien
736117395Skan  return cost;
73790075Sobrien}
73890075Sobrien
739169689Skan/* Returns a canonical version of X for the address, from the point of view,
740169689Skan   that all multiplications are represented as MULT instead of the multiply
741169689Skan   by a power of 2 being represented as ASHIFT.  */
742169689Skan
743169689Skanstatic rtx
744169689Skancanon_for_address (rtx x)
745169689Skan{
746169689Skan  enum rtx_code code;
747169689Skan  enum machine_mode mode;
748169689Skan  rtx new = 0;
749169689Skan  int i;
750169689Skan  const char *fmt;
751169689Skan
752169689Skan  if (!x)
753169689Skan    return x;
754169689Skan
755169689Skan  code = GET_CODE (x);
756169689Skan  mode = GET_MODE (x);
757169689Skan
758169689Skan  switch (code)
759169689Skan    {
760169689Skan    case ASHIFT:
761169689Skan      if (GET_CODE (XEXP (x, 1)) == CONST_INT
762169689Skan	  && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (mode)
763169689Skan	  && INTVAL (XEXP (x, 1)) >= 0)
764169689Skan        {
765169689Skan	  new = canon_for_address (XEXP (x, 0));
766169689Skan	  new = gen_rtx_MULT (mode, new,
767169689Skan			      gen_int_mode ((HOST_WIDE_INT) 1
768169689Skan				            << INTVAL (XEXP (x, 1)),
769169689Skan					    mode));
770169689Skan	}
771169689Skan      break;
772169689Skan    default:
773169689Skan      break;
774169689Skan
775169689Skan    }
776169689Skan  if (new)
777169689Skan    return new;
778169689Skan
779169689Skan  /* Now recursively process each operand of this operation.  */
780169689Skan  fmt = GET_RTX_FORMAT (code);
781169689Skan  for (i = 0; i < GET_RTX_LENGTH (code); i++)
782169689Skan    if (fmt[i] == 'e')
783169689Skan      {
784169689Skan	new = canon_for_address (XEXP (x, i));
785169689Skan	XEXP (x, i) = new;
786169689Skan      }
787169689Skan  return x;
788169689Skan}
789169689Skan
79090075Sobrien/* Return a negative value if an rtx A, whose costs are given by COST_A
79190075Sobrien   and REGCOST_A, is more desirable than an rtx B.
79290075Sobrien   Return a positive value if A is less desirable, or 0 if the two are
79390075Sobrien   equally good.  */
79490075Sobrienstatic int
795169689Skanpreferable (int cost_a, int regcost_a, int cost_b, int regcost_b)
79690075Sobrien{
797117395Skan  /* First, get rid of cases involving expressions that are entirely
79890075Sobrien     unwanted.  */
79990075Sobrien  if (cost_a != cost_b)
80090075Sobrien    {
80190075Sobrien      if (cost_a == MAX_COST)
80290075Sobrien	return 1;
80390075Sobrien      if (cost_b == MAX_COST)
80490075Sobrien	return -1;
80590075Sobrien    }
80690075Sobrien
80790075Sobrien  /* Avoid extending lifetimes of hardregs.  */
80890075Sobrien  if (regcost_a != regcost_b)
80990075Sobrien    {
81090075Sobrien      if (regcost_a == MAX_COST)
81190075Sobrien	return 1;
81290075Sobrien      if (regcost_b == MAX_COST)
81390075Sobrien	return -1;
81490075Sobrien    }
81590075Sobrien
81690075Sobrien  /* Normal operation costs take precedence.  */
81790075Sobrien  if (cost_a != cost_b)
81890075Sobrien    return cost_a - cost_b;
81990075Sobrien  /* Only if these are identical consider effects on register pressure.  */
82090075Sobrien  if (regcost_a != regcost_b)
82190075Sobrien    return regcost_a - regcost_b;
82290075Sobrien  return 0;
82390075Sobrien}
82490075Sobrien
82550397Sobrien/* Internal function, to compute cost when X is not a register; called
82650397Sobrien   from COST macro to keep it simple.  */
82750397Sobrien
82850397Sobrienstatic int
829132718Skannotreg_cost (rtx x, enum rtx_code outer)
83050397Sobrien{
83150397Sobrien  return ((GET_CODE (x) == SUBREG
832169689Skan	   && REG_P (SUBREG_REG (x))
83350397Sobrien	   && GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
83450397Sobrien	   && GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_INT
83550397Sobrien	   && (GET_MODE_SIZE (GET_MODE (x))
83650397Sobrien	       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
83750397Sobrien	   && subreg_lowpart_p (x)
83850397Sobrien	   && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (x)),
83950397Sobrien				     GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))))
84090075Sobrien	  ? 0
84190075Sobrien	  : rtx_cost (x, outer) * 2);
84250397Sobrien}
84350397Sobrien
844169689Skan
845169689Skan/* Initialize CSE_REG_INFO_TABLE.  */
84618334Speter
847169689Skanstatic void
848169689Skaninit_cse_reg_info (unsigned int nregs)
84918334Speter{
850169689Skan  /* Do we need to grow the table?  */
851169689Skan  if (nregs > cse_reg_info_table_size)
852169689Skan    {
853169689Skan      unsigned int new_size;
85418334Speter
855169689Skan      if (cse_reg_info_table_size < 2048)
856169689Skan	{
857169689Skan	  /* Compute a new size that is a power of 2 and no smaller
858169689Skan	     than the large of NREGS and 64.  */
859169689Skan	  new_size = (cse_reg_info_table_size
860169689Skan		      ? cse_reg_info_table_size : 64);
86118334Speter
862169689Skan	  while (new_size < nregs)
863169689Skan	    new_size *= 2;
864169689Skan	}
865169689Skan      else
866169689Skan	{
867169689Skan	  /* If we need a big table, allocate just enough to hold
868169689Skan	     NREGS registers.  */
869169689Skan	  new_size = nregs;
870169689Skan	}
87118334Speter
872169689Skan      /* Reallocate the table with NEW_SIZE entries.  */
873169689Skan      if (cse_reg_info_table)
874169689Skan	free (cse_reg_info_table);
875169689Skan      cse_reg_info_table = XNEWVEC (struct cse_reg_info, new_size);
876169689Skan      cse_reg_info_table_size = new_size;
877169689Skan      cse_reg_info_table_first_uninitialized = 0;
87818334Speter    }
87918334Speter
880169689Skan  /* Do we have all of the first NREGS entries initialized?  */
881169689Skan  if (cse_reg_info_table_first_uninitialized < nregs)
88218334Speter    {
883169689Skan      unsigned int old_timestamp = cse_reg_info_timestamp - 1;
884169689Skan      unsigned int i;
88518334Speter
886169689Skan      /* Put the old timestamp on newly allocated entries so that they
887169689Skan	 will all be considered out of date.  We do not touch those
888169689Skan	 entries beyond the first NREGS entries to be nice to the
889169689Skan	 virtual memory.  */
890169689Skan      for (i = cse_reg_info_table_first_uninitialized; i < nregs; i++)
891169689Skan	cse_reg_info_table[i].timestamp = old_timestamp;
89290075Sobrien
893169689Skan      cse_reg_info_table_first_uninitialized = nregs;
89418334Speter    }
895169689Skan}
89618334Speter
897169689Skan/* Given REGNO, initialize the cse_reg_info entry for REGNO.  */
89818334Speter
899169689Skanstatic void
900169689Skanget_cse_reg_info_1 (unsigned int regno)
90190075Sobrien{
902169689Skan  /* Set TIMESTAMP field to CSE_REG_INFO_TIMESTAMP so that this
903169689Skan     entry will be considered to have been initialized.  */
904169689Skan  cse_reg_info_table[regno].timestamp = cse_reg_info_timestamp;
90590075Sobrien
906169689Skan  /* Initialize the rest of the entry.  */
907169689Skan  cse_reg_info_table[regno].reg_tick = 1;
908169689Skan  cse_reg_info_table[regno].reg_in_table = -1;
909169689Skan  cse_reg_info_table[regno].subreg_ticked = -1;
910169689Skan  cse_reg_info_table[regno].reg_qty = -regno - 1;
911132718Skan}
912132718Skan
913169689Skan/* Find a cse_reg_info entry for REGNO.  */
914132718Skan
915169689Skanstatic inline struct cse_reg_info *
916132718Skanget_cse_reg_info (unsigned int regno)
91752284Sobrien{
918169689Skan  struct cse_reg_info *p = &cse_reg_info_table[regno];
91952284Sobrien
920169689Skan  /* If this entry has not been initialized, go ahead and initialize
921169689Skan     it.  */
922169689Skan  if (p->timestamp != cse_reg_info_timestamp)
923169689Skan    get_cse_reg_info_1 (regno);
92490075Sobrien
92590075Sobrien  return p;
92652284Sobrien}
92752284Sobrien
92818334Speter/* Clear the hash table and initialize each register with its own quantity,
92918334Speter   for a new basic block.  */
93018334Speter
93118334Speterstatic void
932132718Skannew_basic_block (void)
93318334Speter{
93490075Sobrien  int i;
93518334Speter
936146895Skan  next_qty = 0;
93718334Speter
938169689Skan  /* Invalidate cse_reg_info_table.  */
939169689Skan  cse_reg_info_timestamp++;
940169689Skan
94190075Sobrien  /* Clear out hash table state for this pass.  */
94218334Speter  CLEAR_HARD_REG_SET (hard_regs_in_table);
94318334Speter
94418334Speter  /* The per-quantity values used to be initialized here, but it is
94518334Speter     much faster to initialize each as it is made in `make_new_qty'.  */
94618334Speter
94790075Sobrien  for (i = 0; i < HASH_SIZE; i++)
94818334Speter    {
94990075Sobrien      struct table_elt *first;
95090075Sobrien
95190075Sobrien      first = table[i];
95290075Sobrien      if (first != NULL)
95318334Speter	{
95490075Sobrien	  struct table_elt *last = first;
95590075Sobrien
95690075Sobrien	  table[i] = NULL;
95790075Sobrien
95890075Sobrien	  while (last->next_same_hash != NULL)
95990075Sobrien	    last = last->next_same_hash;
96090075Sobrien
96190075Sobrien	  /* Now relink this hash entire chain into
96290075Sobrien	     the free element list.  */
96390075Sobrien
96490075Sobrien	  last->next_same_hash = free_element_chain;
96590075Sobrien	  free_element_chain = first;
96618334Speter	}
96718334Speter    }
96818334Speter
969169689Skan  table_size = 0;
970169689Skan
971132718Skan#ifdef HAVE_cc0
97218334Speter  prev_insn = 0;
97318334Speter  prev_insn_cc0 = 0;
97418334Speter#endif
97518334Speter}
97618334Speter
97790075Sobrien/* Say that register REG contains a quantity in mode MODE not in any
97890075Sobrien   register before and initialize that quantity.  */
97918334Speter
98018334Speterstatic void
981132718Skanmake_new_qty (unsigned int reg, enum machine_mode mode)
98218334Speter{
98390075Sobrien  int q;
98490075Sobrien  struct qty_table_elem *ent;
98590075Sobrien  struct reg_eqv_elem *eqv;
98618334Speter
987169689Skan  gcc_assert (next_qty < max_qty);
98818334Speter
98952284Sobrien  q = REG_QTY (reg) = next_qty++;
99090075Sobrien  ent = &qty_table[q];
99190075Sobrien  ent->first_reg = reg;
99290075Sobrien  ent->last_reg = reg;
99390075Sobrien  ent->mode = mode;
99490075Sobrien  ent->const_rtx = ent->const_insn = NULL_RTX;
99590075Sobrien  ent->comparison_code = UNKNOWN;
99618334Speter
99790075Sobrien  eqv = &reg_eqv_table[reg];
99890075Sobrien  eqv->next = eqv->prev = -1;
99918334Speter}
100018334Speter
100118334Speter/* Make reg NEW equivalent to reg OLD.
100218334Speter   OLD is not changing; NEW is.  */
100318334Speter
100418334Speterstatic void
1005132718Skanmake_regs_eqv (unsigned int new, unsigned int old)
100618334Speter{
100790075Sobrien  unsigned int lastr, firstr;
100890075Sobrien  int q = REG_QTY (old);
100990075Sobrien  struct qty_table_elem *ent;
101018334Speter
101190075Sobrien  ent = &qty_table[q];
101290075Sobrien
101318334Speter  /* Nothing should become eqv until it has a "non-invalid" qty number.  */
1014169689Skan  gcc_assert (REGNO_QTY_VALID_P (old));
101518334Speter
101652284Sobrien  REG_QTY (new) = q;
101790075Sobrien  firstr = ent->first_reg;
101890075Sobrien  lastr = ent->last_reg;
101918334Speter
102018334Speter  /* Prefer fixed hard registers to anything.  Prefer pseudo regs to other
102118334Speter     hard regs.  Among pseudos, if NEW will live longer than any other reg
102218334Speter     of the same qty, and that is beyond the current basic block,
102318334Speter     make it the new canonical replacement for this qty.  */
102418334Speter  if (! (firstr < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (firstr))
102518334Speter      /* Certain fixed registers might be of the class NO_REGS.  This means
102618334Speter	 that not only can they not be allocated by the compiler, but
102718334Speter	 they cannot be used in substitutions or canonicalizations
102818334Speter	 either.  */
102918334Speter      && (new >= FIRST_PSEUDO_REGISTER || REGNO_REG_CLASS (new) != NO_REGS)
103018334Speter      && ((new < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (new))
103118334Speter	  || (new >= FIRST_PSEUDO_REGISTER
103218334Speter	      && (firstr < FIRST_PSEUDO_REGISTER
103350397Sobrien		  || ((uid_cuid[REGNO_LAST_UID (new)] > cse_basic_block_end
103450397Sobrien		       || (uid_cuid[REGNO_FIRST_UID (new)]
103518334Speter			   < cse_basic_block_start))
103650397Sobrien		      && (uid_cuid[REGNO_LAST_UID (new)]
103750397Sobrien			  > uid_cuid[REGNO_LAST_UID (firstr)]))))))
103818334Speter    {
103990075Sobrien      reg_eqv_table[firstr].prev = new;
104090075Sobrien      reg_eqv_table[new].next = firstr;
104190075Sobrien      reg_eqv_table[new].prev = -1;
104290075Sobrien      ent->first_reg = new;
104318334Speter    }
104418334Speter  else
104518334Speter    {
104618334Speter      /* If NEW is a hard reg (known to be non-fixed), insert at end.
104718334Speter	 Otherwise, insert before any non-fixed hard regs that are at the
104818334Speter	 end.  Registers of class NO_REGS cannot be used as an
104918334Speter	 equivalent for anything.  */
105090075Sobrien      while (lastr < FIRST_PSEUDO_REGISTER && reg_eqv_table[lastr].prev >= 0
105118334Speter	     && (REGNO_REG_CLASS (lastr) == NO_REGS || ! FIXED_REGNO_P (lastr))
105218334Speter	     && new >= FIRST_PSEUDO_REGISTER)
105390075Sobrien	lastr = reg_eqv_table[lastr].prev;
105490075Sobrien      reg_eqv_table[new].next = reg_eqv_table[lastr].next;
105590075Sobrien      if (reg_eqv_table[lastr].next >= 0)
105690075Sobrien	reg_eqv_table[reg_eqv_table[lastr].next].prev = new;
105718334Speter      else
105890075Sobrien	qty_table[q].last_reg = new;
105990075Sobrien      reg_eqv_table[lastr].next = new;
106090075Sobrien      reg_eqv_table[new].prev = lastr;
106118334Speter    }
106218334Speter}
106318334Speter
106418334Speter/* Remove REG from its equivalence class.  */
106518334Speter
106618334Speterstatic void
1067132718Skandelete_reg_equiv (unsigned int reg)
106818334Speter{
106990075Sobrien  struct qty_table_elem *ent;
107090075Sobrien  int q = REG_QTY (reg);
107190075Sobrien  int p, n;
107218334Speter
107318334Speter  /* If invalid, do nothing.  */
1074146895Skan  if (! REGNO_QTY_VALID_P (reg))
107518334Speter    return;
107618334Speter
107790075Sobrien  ent = &qty_table[q];
107818334Speter
107990075Sobrien  p = reg_eqv_table[reg].prev;
108090075Sobrien  n = reg_eqv_table[reg].next;
108190075Sobrien
108218334Speter  if (n != -1)
108390075Sobrien    reg_eqv_table[n].prev = p;
108418334Speter  else
108590075Sobrien    ent->last_reg = p;
108618334Speter  if (p != -1)
108790075Sobrien    reg_eqv_table[p].next = n;
108818334Speter  else
108990075Sobrien    ent->first_reg = n;
109018334Speter
1091146895Skan  REG_QTY (reg) = -reg - 1;
109218334Speter}
109318334Speter
109418334Speter/* Remove any invalid expressions from the hash table
109518334Speter   that refer to any of the registers contained in expression X.
109618334Speter
109718334Speter   Make sure that newly inserted references to those registers
109818334Speter   as subexpressions will be considered valid.
109918334Speter
110018334Speter   mention_regs is not called when a register itself
110118334Speter   is being stored in the table.
110218334Speter
110318334Speter   Return 1 if we have done something that may have changed the hash code
110418334Speter   of X.  */
110518334Speter
110618334Speterstatic int
1107132718Skanmention_regs (rtx x)
110818334Speter{
110990075Sobrien  enum rtx_code code;
111090075Sobrien  int i, j;
111190075Sobrien  const char *fmt;
111290075Sobrien  int changed = 0;
111318334Speter
111418334Speter  if (x == 0)
111518334Speter    return 0;
111618334Speter
111718334Speter  code = GET_CODE (x);
111818334Speter  if (code == REG)
111918334Speter    {
112090075Sobrien      unsigned int regno = REGNO (x);
112190075Sobrien      unsigned int endregno
112218334Speter	= regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
1123169689Skan		   : hard_regno_nregs[regno][GET_MODE (x)]);
112490075Sobrien      unsigned int i;
112518334Speter
112618334Speter      for (i = regno; i < endregno; i++)
112718334Speter	{
112852284Sobrien	  if (REG_IN_TABLE (i) >= 0 && REG_IN_TABLE (i) != REG_TICK (i))
112918334Speter	    remove_invalid_refs (i);
113018334Speter
113152284Sobrien	  REG_IN_TABLE (i) = REG_TICK (i);
1132117395Skan	  SUBREG_TICKED (i) = -1;
113318334Speter	}
113418334Speter
113518334Speter      return 0;
113618334Speter    }
113718334Speter
113852284Sobrien  /* If this is a SUBREG, we don't want to discard other SUBREGs of the same
113952284Sobrien     pseudo if they don't use overlapping words.  We handle only pseudos
114052284Sobrien     here for simplicity.  */
1141169689Skan  if (code == SUBREG && REG_P (SUBREG_REG (x))
114252284Sobrien      && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
114352284Sobrien    {
114490075Sobrien      unsigned int i = REGNO (SUBREG_REG (x));
114552284Sobrien
114652284Sobrien      if (REG_IN_TABLE (i) >= 0 && REG_IN_TABLE (i) != REG_TICK (i))
114752284Sobrien	{
1148117395Skan	  /* If REG_IN_TABLE (i) differs from REG_TICK (i) by one, and
1149117395Skan	     the last store to this register really stored into this
1150117395Skan	     subreg, then remove the memory of this subreg.
1151117395Skan	     Otherwise, remove any memory of the entire register and
1152117395Skan	     all its subregs from the table.  */
1153117395Skan	  if (REG_TICK (i) - REG_IN_TABLE (i) > 1
1154117395Skan	      || SUBREG_TICKED (i) != REGNO (SUBREG_REG (x)))
115552284Sobrien	    remove_invalid_refs (i);
115652284Sobrien	  else
115790075Sobrien	    remove_invalid_subreg_refs (i, SUBREG_BYTE (x), GET_MODE (x));
115852284Sobrien	}
115952284Sobrien
116052284Sobrien      REG_IN_TABLE (i) = REG_TICK (i);
1161117395Skan      SUBREG_TICKED (i) = REGNO (SUBREG_REG (x));
116252284Sobrien      return 0;
116352284Sobrien    }
116452284Sobrien
116518334Speter  /* If X is a comparison or a COMPARE and either operand is a register
116618334Speter     that does not have a quantity, give it one.  This is so that a later
116718334Speter     call to record_jump_equiv won't cause X to be assigned a different
116818334Speter     hash code and not found in the table after that call.
116918334Speter
117018334Speter     It is not necessary to do this here, since rehash_using_reg can
117118334Speter     fix up the table later, but doing this here eliminates the need to
117218334Speter     call that expensive function in the most common case where the only
117318334Speter     use of the register is in the comparison.  */
117418334Speter
1175169689Skan  if (code == COMPARE || COMPARISON_P (x))
117618334Speter    {
1177169689Skan      if (REG_P (XEXP (x, 0))
117818334Speter	  && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))))
117990075Sobrien	if (insert_regs (XEXP (x, 0), NULL, 0))
118018334Speter	  {
118118334Speter	    rehash_using_reg (XEXP (x, 0));
118218334Speter	    changed = 1;
118318334Speter	  }
118418334Speter
1185169689Skan      if (REG_P (XEXP (x, 1))
118618334Speter	  && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))))
118790075Sobrien	if (insert_regs (XEXP (x, 1), NULL, 0))
118818334Speter	  {
118918334Speter	    rehash_using_reg (XEXP (x, 1));
119018334Speter	    changed = 1;
119118334Speter	  }
119218334Speter    }
119318334Speter
119418334Speter  fmt = GET_RTX_FORMAT (code);
119518334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
119618334Speter    if (fmt[i] == 'e')
119718334Speter      changed |= mention_regs (XEXP (x, i));
119818334Speter    else if (fmt[i] == 'E')
119918334Speter      for (j = 0; j < XVECLEN (x, i); j++)
120018334Speter	changed |= mention_regs (XVECEXP (x, i, j));
120118334Speter
120218334Speter  return changed;
120318334Speter}
120418334Speter
120518334Speter/* Update the register quantities for inserting X into the hash table
120618334Speter   with a value equivalent to CLASSP.
120718334Speter   (If the class does not contain a REG, it is irrelevant.)
120818334Speter   If MODIFIED is nonzero, X is a destination; it is being modified.
120918334Speter   Note that delete_reg_equiv should be called on a register
121018334Speter   before insert_regs is done on that register with MODIFIED != 0.
121118334Speter
121218334Speter   Nonzero value means that elements of reg_qty have changed
121318334Speter   so X's hash code may be different.  */
121418334Speter
121518334Speterstatic int
1216132718Skaninsert_regs (rtx x, struct table_elt *classp, int modified)
121718334Speter{
1218169689Skan  if (REG_P (x))
121918334Speter    {
122090075Sobrien      unsigned int regno = REGNO (x);
122190075Sobrien      int qty_valid;
122218334Speter
122318334Speter      /* If REGNO is in the equivalence table already but is of the
122418334Speter	 wrong mode for that equivalence, don't do anything here.  */
122518334Speter
122690075Sobrien      qty_valid = REGNO_QTY_VALID_P (regno);
122790075Sobrien      if (qty_valid)
122890075Sobrien	{
122990075Sobrien	  struct qty_table_elem *ent = &qty_table[REG_QTY (regno)];
123018334Speter
123190075Sobrien	  if (ent->mode != GET_MODE (x))
123290075Sobrien	    return 0;
123390075Sobrien	}
123490075Sobrien
123590075Sobrien      if (modified || ! qty_valid)
123618334Speter	{
123718334Speter	  if (classp)
123818334Speter	    for (classp = classp->first_same_value;
123918334Speter		 classp != 0;
124018334Speter		 classp = classp->next_same_value)
1241169689Skan	      if (REG_P (classp->exp)
124218334Speter		  && GET_MODE (classp->exp) == GET_MODE (x))
124318334Speter		{
1244169689Skan		  unsigned c_regno = REGNO (classp->exp);
1245169689Skan
1246169689Skan		  gcc_assert (REGNO_QTY_VALID_P (c_regno));
1247169689Skan
1248169689Skan		  /* Suppose that 5 is hard reg and 100 and 101 are
1249169689Skan		     pseudos.  Consider
1250169689Skan
1251169689Skan		     (set (reg:si 100) (reg:si 5))
1252169689Skan		     (set (reg:si 5) (reg:si 100))
1253169689Skan		     (set (reg:di 101) (reg:di 5))
1254169689Skan
1255169689Skan		     We would now set REG_QTY (101) = REG_QTY (5), but the
1256169689Skan		     entry for 5 is in SImode.  When we use this later in
1257169689Skan		     copy propagation, we get the register in wrong mode.  */
1258169689Skan		  if (qty_table[REG_QTY (c_regno)].mode != GET_MODE (x))
1259169689Skan		    continue;
1260169689Skan
1261169689Skan		  make_regs_eqv (regno, c_regno);
126218334Speter		  return 1;
126318334Speter		}
126418334Speter
126590075Sobrien	  /* Mention_regs for a SUBREG checks if REG_TICK is exactly one larger
126690075Sobrien	     than REG_IN_TABLE to find out if there was only a single preceding
126790075Sobrien	     invalidation - for the SUBREG - or another one, which would be
126890075Sobrien	     for the full register.  However, if we find here that REG_TICK
126990075Sobrien	     indicates that the register is invalid, it means that it has
127090075Sobrien	     been invalidated in a separate operation.  The SUBREG might be used
127190075Sobrien	     now (then this is a recursive call), or we might use the full REG
127290075Sobrien	     now and a SUBREG of it later.  So bump up REG_TICK so that
127390075Sobrien	     mention_regs will do the right thing.  */
127490075Sobrien	  if (! modified
127590075Sobrien	      && REG_IN_TABLE (regno) >= 0
127690075Sobrien	      && REG_TICK (regno) == REG_IN_TABLE (regno) + 1)
127790075Sobrien	    REG_TICK (regno)++;
127890075Sobrien	  make_new_qty (regno, GET_MODE (x));
127918334Speter	  return 1;
128018334Speter	}
128118334Speter
128218334Speter      return 0;
128318334Speter    }
128418334Speter
128518334Speter  /* If X is a SUBREG, we will likely be inserting the inner register in the
128618334Speter     table.  If that register doesn't have an assigned quantity number at
128718334Speter     this point but does later, the insertion that we will be doing now will
128818334Speter     not be accessible because its hash code will have changed.  So assign
128918334Speter     a quantity number now.  */
129018334Speter
1291169689Skan  else if (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
129218334Speter	   && ! REGNO_QTY_VALID_P (REGNO (SUBREG_REG (x))))
129318334Speter    {
129490075Sobrien      insert_regs (SUBREG_REG (x), NULL, 0);
129552284Sobrien      mention_regs (x);
129618334Speter      return 1;
129718334Speter    }
129818334Speter  else
129918334Speter    return mention_regs (x);
130018334Speter}
130118334Speter
130218334Speter/* Look in or update the hash table.  */
130318334Speter
130418334Speter/* Remove table element ELT from use in the table.
130518334Speter   HASH is its hash code, made using the HASH macro.
130618334Speter   It's an argument because often that is known in advance
130718334Speter   and we save much time not recomputing it.  */
130818334Speter
130918334Speterstatic void
1310132718Skanremove_from_table (struct table_elt *elt, unsigned int hash)
131118334Speter{
131218334Speter  if (elt == 0)
131318334Speter    return;
131418334Speter
131518334Speter  /* Mark this element as removed.  See cse_insn.  */
131618334Speter  elt->first_same_value = 0;
131718334Speter
131818334Speter  /* Remove the table element from its equivalence class.  */
131990075Sobrien
132018334Speter  {
132190075Sobrien    struct table_elt *prev = elt->prev_same_value;
132290075Sobrien    struct table_elt *next = elt->next_same_value;
132318334Speter
132490075Sobrien    if (next)
132590075Sobrien      next->prev_same_value = prev;
132618334Speter
132718334Speter    if (prev)
132818334Speter      prev->next_same_value = next;
132918334Speter    else
133018334Speter      {
133190075Sobrien	struct table_elt *newfirst = next;
133218334Speter	while (next)
133318334Speter	  {
133418334Speter	    next->first_same_value = newfirst;
133518334Speter	    next = next->next_same_value;
133618334Speter	  }
133718334Speter      }
133818334Speter  }
133918334Speter
134018334Speter  /* Remove the table element from its hash bucket.  */
134118334Speter
134218334Speter  {
134390075Sobrien    struct table_elt *prev = elt->prev_same_hash;
134490075Sobrien    struct table_elt *next = elt->next_same_hash;
134518334Speter
134690075Sobrien    if (next)
134790075Sobrien      next->prev_same_hash = prev;
134818334Speter
134918334Speter    if (prev)
135018334Speter      prev->next_same_hash = next;
135118334Speter    else if (table[hash] == elt)
135218334Speter      table[hash] = next;
135318334Speter    else
135418334Speter      {
135518334Speter	/* This entry is not in the proper hash bucket.  This can happen
135618334Speter	   when two classes were merged by `merge_equiv_classes'.  Search
135718334Speter	   for the hash bucket that it heads.  This happens only very
135818334Speter	   rarely, so the cost is acceptable.  */
135990075Sobrien	for (hash = 0; hash < HASH_SIZE; hash++)
136018334Speter	  if (table[hash] == elt)
136118334Speter	    table[hash] = next;
136218334Speter      }
136318334Speter  }
136418334Speter
136518334Speter  /* Remove the table element from its related-value circular chain.  */
136618334Speter
136718334Speter  if (elt->related_value != 0 && elt->related_value != elt)
136818334Speter    {
136990075Sobrien      struct table_elt *p = elt->related_value;
137090075Sobrien
137118334Speter      while (p->related_value != elt)
137218334Speter	p = p->related_value;
137318334Speter      p->related_value = elt->related_value;
137418334Speter      if (p->related_value == p)
137518334Speter	p->related_value = 0;
137618334Speter    }
137718334Speter
137890075Sobrien  /* Now add it to the free element chain.  */
137990075Sobrien  elt->next_same_hash = free_element_chain;
138090075Sobrien  free_element_chain = elt;
1381169689Skan
1382169689Skan  table_size--;
138318334Speter}
138418334Speter
1385235965Spfg/* Same as above, but X is a pseudo-register.  */
1386235965Spfg
1387235965Spfgstatic void
1388235965Spfgremove_pseudo_from_table (rtx x, unsigned int hash)
1389235965Spfg{
1390235965Spfg  struct table_elt *elt;
1391235965Spfg
1392235965Spfg  /* Because a pseudo-register can be referenced in more than one
1393235965Spfg     mode, we might have to remove more than one table entry.  */
1394235965Spfg  while ((elt = lookup_for_remove (x, hash, VOIDmode)))
1395235965Spfg    remove_from_table (elt, hash);
1396235965Spfg}
1397235965Spfg
139818334Speter/* Look up X in the hash table and return its table element,
139918334Speter   or 0 if X is not in the table.
140018334Speter
140118334Speter   MODE is the machine-mode of X, or if X is an integer constant
140218334Speter   with VOIDmode then MODE is the mode with which X will be used.
140318334Speter
140418334Speter   Here we are satisfied to find an expression whose tree structure
140518334Speter   looks like X.  */
140618334Speter
140718334Speterstatic struct table_elt *
1408132718Skanlookup (rtx x, unsigned int hash, enum machine_mode mode)
140918334Speter{
141090075Sobrien  struct table_elt *p;
141118334Speter
141218334Speter  for (p = table[hash]; p; p = p->next_same_hash)
1413169689Skan    if (mode == p->mode && ((x == p->exp && REG_P (x))
1414169689Skan			    || exp_equiv_p (x, p->exp, !REG_P (x), false)))
141518334Speter      return p;
141618334Speter
141718334Speter  return 0;
141818334Speter}
141918334Speter
142018334Speter/* Like `lookup' but don't care whether the table element uses invalid regs.
142118334Speter   Also ignore discrepancies in the machine mode of a register.  */
142218334Speter
142318334Speterstatic struct table_elt *
1424132718Skanlookup_for_remove (rtx x, unsigned int hash, enum machine_mode mode)
142518334Speter{
142690075Sobrien  struct table_elt *p;
142718334Speter
1428169689Skan  if (REG_P (x))
142918334Speter    {
143090075Sobrien      unsigned int regno = REGNO (x);
143190075Sobrien
143218334Speter      /* Don't check the machine mode when comparing registers;
143318334Speter	 invalidating (REG:SI 0) also invalidates (REG:DF 0).  */
143418334Speter      for (p = table[hash]; p; p = p->next_same_hash)
1435169689Skan	if (REG_P (p->exp)
143618334Speter	    && REGNO (p->exp) == regno)
143718334Speter	  return p;
143818334Speter    }
143918334Speter  else
144018334Speter    {
144118334Speter      for (p = table[hash]; p; p = p->next_same_hash)
1442169689Skan	if (mode == p->mode
1443169689Skan	    && (x == p->exp || exp_equiv_p (x, p->exp, 0, false)))
144418334Speter	  return p;
144518334Speter    }
144618334Speter
144718334Speter  return 0;
144818334Speter}
144918334Speter
145018334Speter/* Look for an expression equivalent to X and with code CODE.
145118334Speter   If one is found, return that expression.  */
145218334Speter
145318334Speterstatic rtx
1454132718Skanlookup_as_function (rtx x, enum rtx_code code)
145518334Speter{
145690075Sobrien  struct table_elt *p
1457169689Skan    = lookup (x, SAFE_HASH (x, VOIDmode), GET_MODE (x));
145890075Sobrien
145952284Sobrien  /* If we are looking for a CONST_INT, the mode doesn't really matter, as
146052284Sobrien     long as we are narrowing.  So if we looked in vain for a mode narrower
146152284Sobrien     than word_mode before, look for word_mode now.  */
146252284Sobrien  if (p == 0 && code == CONST_INT
146352284Sobrien      && GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (word_mode))
146452284Sobrien    {
146552284Sobrien      x = copy_rtx (x);
146652284Sobrien      PUT_MODE (x, word_mode);
1467169689Skan      p = lookup (x, SAFE_HASH (x, VOIDmode), word_mode);
146852284Sobrien    }
146952284Sobrien
147018334Speter  if (p == 0)
147118334Speter    return 0;
147218334Speter
147318334Speter  for (p = p->first_same_value; p; p = p->next_same_value)
147490075Sobrien    if (GET_CODE (p->exp) == code
147590075Sobrien	/* Make sure this is a valid entry in the table.  */
1476169689Skan	&& exp_equiv_p (p->exp, p->exp, 1, false))
147790075Sobrien      return p->exp;
147890075Sobrien
147918334Speter  return 0;
148018334Speter}
148118334Speter
148218334Speter/* Insert X in the hash table, assuming HASH is its hash code
148318334Speter   and CLASSP is an element of the class it should go in
148418334Speter   (or 0 if a new class should be made).
148518334Speter   It is inserted at the proper position to keep the class in
148618334Speter   the order cheapest first.
148718334Speter
148818334Speter   MODE is the machine-mode of X, or if X is an integer constant
148918334Speter   with VOIDmode then MODE is the mode with which X will be used.
149018334Speter
149118334Speter   For elements of equal cheapness, the most recent one
149218334Speter   goes in front, except that the first element in the list
149318334Speter   remains first unless a cheaper element is added.  The order of
149418334Speter   pseudo-registers does not matter, as canon_reg will be called to
149518334Speter   find the cheapest when a register is retrieved from the table.
149618334Speter
149718334Speter   The in_memory field in the hash table element is set to 0.
149818334Speter   The caller must set it nonzero if appropriate.
149918334Speter
150018334Speter   You should call insert_regs (X, CLASSP, MODIFY) before calling here,
150118334Speter   and if insert_regs returns a nonzero value
150218334Speter   you must then recompute its hash code before calling here.
150318334Speter
150418334Speter   If necessary, update table showing constant values of quantities.  */
150518334Speter
150690075Sobrien#define CHEAPER(X, Y) \
1507169689Skan (preferable ((X)->cost, (X)->regcost, (Y)->cost, (Y)->regcost) < 0)
150818334Speter
150918334Speterstatic struct table_elt *
1510132718Skaninsert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mode)
151118334Speter{
151290075Sobrien  struct table_elt *elt;
151318334Speter
151418334Speter  /* If X is a register and we haven't made a quantity for it,
151518334Speter     something is wrong.  */
1516169689Skan  gcc_assert (!REG_P (x) || REGNO_QTY_VALID_P (REGNO (x)));
151718334Speter
151818334Speter  /* If X is a hard register, show it is being put in the table.  */
1519169689Skan  if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
152018334Speter    {
152190075Sobrien      unsigned int regno = REGNO (x);
1522169689Skan      unsigned int endregno = regno + hard_regno_nregs[regno][GET_MODE (x)];
152390075Sobrien      unsigned int i;
152418334Speter
152518334Speter      for (i = regno; i < endregno; i++)
152690075Sobrien	SET_HARD_REG_BIT (hard_regs_in_table, i);
152718334Speter    }
152818334Speter
152918334Speter  /* Put an element for X into the right hash bucket.  */
153018334Speter
153190075Sobrien  elt = free_element_chain;
153290075Sobrien  if (elt)
153390075Sobrien    free_element_chain = elt->next_same_hash;
153490075Sobrien  else
1535169689Skan    elt = XNEW (struct table_elt);
153690075Sobrien
153718334Speter  elt->exp = x;
153890075Sobrien  elt->canon_exp = NULL_RTX;
153918334Speter  elt->cost = COST (x);
154090075Sobrien  elt->regcost = approx_reg_cost (x);
154118334Speter  elt->next_same_value = 0;
154218334Speter  elt->prev_same_value = 0;
154318334Speter  elt->next_same_hash = table[hash];
154418334Speter  elt->prev_same_hash = 0;
154518334Speter  elt->related_value = 0;
154618334Speter  elt->in_memory = 0;
154718334Speter  elt->mode = mode;
1548169689Skan  elt->is_const = (CONSTANT_P (x) || fixed_base_plus_p (x));
154918334Speter
155018334Speter  if (table[hash])
155118334Speter    table[hash]->prev_same_hash = elt;
155218334Speter  table[hash] = elt;
155318334Speter
155418334Speter  /* Put it into the proper value-class.  */
155518334Speter  if (classp)
155618334Speter    {
155718334Speter      classp = classp->first_same_value;
155818334Speter      if (CHEAPER (elt, classp))
1559132718Skan	/* Insert at the head of the class.  */
156018334Speter	{
156190075Sobrien	  struct table_elt *p;
156218334Speter	  elt->next_same_value = classp;
156318334Speter	  classp->prev_same_value = elt;
156418334Speter	  elt->first_same_value = elt;
156518334Speter
156618334Speter	  for (p = classp; p; p = p->next_same_value)
156718334Speter	    p->first_same_value = elt;
156818334Speter	}
156918334Speter      else
157018334Speter	{
157118334Speter	  /* Insert not at head of the class.  */
157218334Speter	  /* Put it after the last element cheaper than X.  */
157390075Sobrien	  struct table_elt *p, *next;
157490075Sobrien
157518334Speter	  for (p = classp; (next = p->next_same_value) && CHEAPER (next, elt);
157618334Speter	       p = next);
157790075Sobrien
157818334Speter	  /* Put it after P and before NEXT.  */
157918334Speter	  elt->next_same_value = next;
158018334Speter	  if (next)
158118334Speter	    next->prev_same_value = elt;
158290075Sobrien
158318334Speter	  elt->prev_same_value = p;
158418334Speter	  p->next_same_value = elt;
158518334Speter	  elt->first_same_value = classp;
158618334Speter	}
158718334Speter    }
158818334Speter  else
158918334Speter    elt->first_same_value = elt;
159018334Speter
159118334Speter  /* If this is a constant being set equivalent to a register or a register
159218334Speter     being set equivalent to a constant, note the constant equivalence.
159318334Speter
159418334Speter     If this is a constant, it cannot be equivalent to a different constant,
159518334Speter     and a constant is the only thing that can be cheaper than a register.  So
159618334Speter     we know the register is the head of the class (before the constant was
159718334Speter     inserted).
159818334Speter
159918334Speter     If this is a register that is not already known equivalent to a
160018334Speter     constant, we must check the entire class.
160118334Speter
160218334Speter     If this is a register that is already known equivalent to an insn,
160390075Sobrien     update the qtys `const_insn' to show that `this_insn' is the latest
160418334Speter     insn making that quantity equivalent to the constant.  */
160518334Speter
1606169689Skan  if (elt->is_const && classp && REG_P (classp->exp)
1607169689Skan      && !REG_P (x))
160818334Speter    {
160990075Sobrien      int exp_q = REG_QTY (REGNO (classp->exp));
161090075Sobrien      struct qty_table_elem *exp_ent = &qty_table[exp_q];
161190075Sobrien
1612169689Skan      exp_ent->const_rtx = gen_lowpart (exp_ent->mode, x);
161390075Sobrien      exp_ent->const_insn = this_insn;
161418334Speter    }
161518334Speter
1616169689Skan  else if (REG_P (x)
161790075Sobrien	   && classp
161890075Sobrien	   && ! qty_table[REG_QTY (REGNO (x))].const_rtx
161918334Speter	   && ! elt->is_const)
162018334Speter    {
162190075Sobrien      struct table_elt *p;
162218334Speter
162318334Speter      for (p = classp; p != 0; p = p->next_same_value)
162418334Speter	{
1625169689Skan	  if (p->is_const && !REG_P (p->exp))
162618334Speter	    {
162790075Sobrien	      int x_q = REG_QTY (REGNO (x));
162890075Sobrien	      struct qty_table_elem *x_ent = &qty_table[x_q];
162990075Sobrien
163090075Sobrien	      x_ent->const_rtx
1631169689Skan		= gen_lowpart (GET_MODE (x), p->exp);
163290075Sobrien	      x_ent->const_insn = this_insn;
163318334Speter	      break;
163418334Speter	    }
163518334Speter	}
163618334Speter    }
163718334Speter
1638169689Skan  else if (REG_P (x)
163990075Sobrien	   && qty_table[REG_QTY (REGNO (x))].const_rtx
164090075Sobrien	   && GET_MODE (x) == qty_table[REG_QTY (REGNO (x))].mode)
164190075Sobrien    qty_table[REG_QTY (REGNO (x))].const_insn = this_insn;
164218334Speter
164318334Speter  /* If this is a constant with symbolic value,
164418334Speter     and it has a term with an explicit integer value,
164518334Speter     link it up with related expressions.  */
164618334Speter  if (GET_CODE (x) == CONST)
164718334Speter    {
164818334Speter      rtx subexp = get_related_value (x);
164918334Speter      unsigned subhash;
165018334Speter      struct table_elt *subelt, *subelt_prev;
165118334Speter
165218334Speter      if (subexp != 0)
165318334Speter	{
165418334Speter	  /* Get the integer-free subexpression in the hash table.  */
1655169689Skan	  subhash = SAFE_HASH (subexp, mode);
165618334Speter	  subelt = lookup (subexp, subhash, mode);
165718334Speter	  if (subelt == 0)
165890075Sobrien	    subelt = insert (subexp, NULL, subhash, mode);
165918334Speter	  /* Initialize SUBELT's circular chain if it has none.  */
166018334Speter	  if (subelt->related_value == 0)
166118334Speter	    subelt->related_value = subelt;
166218334Speter	  /* Find the element in the circular chain that precedes SUBELT.  */
166318334Speter	  subelt_prev = subelt;
166418334Speter	  while (subelt_prev->related_value != subelt)
166518334Speter	    subelt_prev = subelt_prev->related_value;
166618334Speter	  /* Put new ELT into SUBELT's circular chain just before SUBELT.
166718334Speter	     This way the element that follows SUBELT is the oldest one.  */
166818334Speter	  elt->related_value = subelt_prev->related_value;
166918334Speter	  subelt_prev->related_value = elt;
167018334Speter	}
167118334Speter    }
167218334Speter
1673169689Skan  table_size++;
1674169689Skan
167518334Speter  return elt;
167618334Speter}
167718334Speter
167818334Speter/* Given two equivalence classes, CLASS1 and CLASS2, put all the entries from
167918334Speter   CLASS2 into CLASS1.  This is done when we have reached an insn which makes
168018334Speter   the two classes equivalent.
168118334Speter
168218334Speter   CLASS1 will be the surviving class; CLASS2 should not be used after this
168318334Speter   call.
168418334Speter
168518334Speter   Any invalid entries in CLASS2 will not be copied.  */
168618334Speter
168718334Speterstatic void
1688132718Skanmerge_equiv_classes (struct table_elt *class1, struct table_elt *class2)
168918334Speter{
169018334Speter  struct table_elt *elt, *next, *new;
169118334Speter
169218334Speter  /* Ensure we start with the head of the classes.  */
169318334Speter  class1 = class1->first_same_value;
169418334Speter  class2 = class2->first_same_value;
169518334Speter
169618334Speter  /* If they were already equal, forget it.  */
169718334Speter  if (class1 == class2)
169818334Speter    return;
169918334Speter
170018334Speter  for (elt = class2; elt; elt = next)
170118334Speter    {
170290075Sobrien      unsigned int hash;
170318334Speter      rtx exp = elt->exp;
170418334Speter      enum machine_mode mode = elt->mode;
170518334Speter
170618334Speter      next = elt->next_same_value;
170718334Speter
170818334Speter      /* Remove old entry, make a new one in CLASS1's class.
170918334Speter	 Don't do this for invalid entries as we cannot find their
171050397Sobrien	 hash code (it also isn't necessary).  */
1711169689Skan      if (REG_P (exp) || exp_equiv_p (exp, exp, 1, false))
171218334Speter	{
1713132718Skan	  bool need_rehash = false;
1714132718Skan
171518334Speter	  hash_arg_in_memory = 0;
171618334Speter	  hash = HASH (exp, mode);
171790075Sobrien
1718169689Skan	  if (REG_P (exp))
1719132718Skan	    {
1720146895Skan	      need_rehash = REGNO_QTY_VALID_P (REGNO (exp));
1721132718Skan	      delete_reg_equiv (REGNO (exp));
1722132718Skan	    }
172390075Sobrien
1724235965Spfg	  if (REG_P (exp) && REGNO (exp) >= FIRST_PSEUDO_REGISTER)
1725235965Spfg	    remove_pseudo_from_table (exp, hash);
1726235965Spfg	  else
1727235965Spfg	    remove_from_table (elt, hash);
172818334Speter
1729132718Skan	  if (insert_regs (exp, class1, 0) || need_rehash)
173018334Speter	    {
173118334Speter	      rehash_using_reg (exp);
173218334Speter	      hash = HASH (exp, mode);
173318334Speter	    }
173418334Speter	  new = insert (exp, class1, hash, mode);
173518334Speter	  new->in_memory = hash_arg_in_memory;
173618334Speter	}
173718334Speter    }
173818334Speter}
173918334Speter
174052284Sobrien/* Flush the entire hash table.  */
174152284Sobrien
174252284Sobrienstatic void
1743132718Skanflush_hash_table (void)
174452284Sobrien{
174552284Sobrien  int i;
174652284Sobrien  struct table_elt *p;
174752284Sobrien
174890075Sobrien  for (i = 0; i < HASH_SIZE; i++)
174952284Sobrien    for (p = table[i]; p; p = table[i])
175052284Sobrien      {
175152284Sobrien	/* Note that invalidate can remove elements
175252284Sobrien	   after P in the current hash chain.  */
1753169689Skan	if (REG_P (p->exp))
1754169689Skan	  invalidate (p->exp, VOIDmode);
175552284Sobrien	else
175652284Sobrien	  remove_from_table (p, i);
175752284Sobrien      }
175852284Sobrien}
175990075Sobrien
176090075Sobrien/* Function called for each rtx to check whether true dependence exist.  */
176190075Sobrienstruct check_dependence_data
176290075Sobrien{
176390075Sobrien  enum machine_mode mode;
176490075Sobrien  rtx exp;
1765132718Skan  rtx addr;
176690075Sobrien};
176752284Sobrien
176890075Sobrienstatic int
1769132718Skancheck_dependence (rtx *x, void *data)
177090075Sobrien{
177190075Sobrien  struct check_dependence_data *d = (struct check_dependence_data *) data;
1772169689Skan  if (*x && MEM_P (*x))
1773132718Skan    return canon_true_dependence (d->exp, d->mode, d->addr, *x,
1774132718Skan		    		  cse_rtx_varies_p);
177590075Sobrien  else
177690075Sobrien    return 0;
177790075Sobrien}
177890075Sobrien
177990075Sobrien/* Remove from the hash table, or mark as invalid, all expressions whose
178090075Sobrien   values could be altered by storing in X.  X is a register, a subreg, or
178190075Sobrien   a memory reference with nonvarying address (because, when a memory
178290075Sobrien   reference with a varying address is stored in, all memory references are
178390075Sobrien   removed by invalidate_memory so specific invalidation is superfluous).
178490075Sobrien   FULL_MODE, if not VOIDmode, indicates that this much should be
178590075Sobrien   invalidated instead of just the amount indicated by the mode of X.  This
178690075Sobrien   is only used for bitfield stores into memory.
178752284Sobrien
178890075Sobrien   A nonvarying address may be just a register or just a symbol reference,
178990075Sobrien   or it may be either of those plus a numeric offset.  */
179018334Speter
179118334Speterstatic void
1792132718Skaninvalidate (rtx x, enum machine_mode full_mode)
179318334Speter{
179490075Sobrien  int i;
179590075Sobrien  struct table_elt *p;
1796132718Skan  rtx addr;
179718334Speter
179890075Sobrien  switch (GET_CODE (x))
179918334Speter    {
180090075Sobrien    case REG:
180190075Sobrien      {
180290075Sobrien	/* If X is a register, dependencies on its contents are recorded
180390075Sobrien	   through the qty number mechanism.  Just change the qty number of
180490075Sobrien	   the register, mark it as invalid for expressions that refer to it,
180590075Sobrien	   and remove it itself.  */
180690075Sobrien	unsigned int regno = REGNO (x);
180790075Sobrien	unsigned int hash = HASH (x, GET_MODE (x));
180818334Speter
180990075Sobrien	/* Remove REGNO from any quantity list it might be on and indicate
181090075Sobrien	   that its value might have changed.  If it is a pseudo, remove its
181190075Sobrien	   entry from the hash table.
181218334Speter
181390075Sobrien	   For a hard register, we do the first two actions above for any
181490075Sobrien	   additional hard registers corresponding to X.  Then, if any of these
181590075Sobrien	   registers are in the table, we must remove any REG entries that
181690075Sobrien	   overlap these registers.  */
181718334Speter
181890075Sobrien	delete_reg_equiv (regno);
181990075Sobrien	REG_TICK (regno)++;
1820117395Skan	SUBREG_TICKED (regno) = -1;
182118334Speter
182290075Sobrien	if (regno >= FIRST_PSEUDO_REGISTER)
1823235965Spfg	  remove_pseudo_from_table (x, hash);
182490075Sobrien	else
182590075Sobrien	  {
182690075Sobrien	    HOST_WIDE_INT in_table
182790075Sobrien	      = TEST_HARD_REG_BIT (hard_regs_in_table, regno);
182890075Sobrien	    unsigned int endregno
1829169689Skan	      = regno + hard_regno_nregs[regno][GET_MODE (x)];
183090075Sobrien	    unsigned int tregno, tendregno, rn;
183190075Sobrien	    struct table_elt *p, *next;
183218334Speter
183390075Sobrien	    CLEAR_HARD_REG_BIT (hard_regs_in_table, regno);
183418334Speter
183590075Sobrien	    for (rn = regno + 1; rn < endregno; rn++)
183690075Sobrien	      {
183790075Sobrien		in_table |= TEST_HARD_REG_BIT (hard_regs_in_table, rn);
183890075Sobrien		CLEAR_HARD_REG_BIT (hard_regs_in_table, rn);
183990075Sobrien		delete_reg_equiv (rn);
184090075Sobrien		REG_TICK (rn)++;
1841117395Skan		SUBREG_TICKED (rn) = -1;
184290075Sobrien	      }
184318334Speter
184490075Sobrien	    if (in_table)
184590075Sobrien	      for (hash = 0; hash < HASH_SIZE; hash++)
184690075Sobrien		for (p = table[hash]; p; p = next)
184790075Sobrien		  {
184890075Sobrien		    next = p->next_same_hash;
184918334Speter
1850169689Skan		    if (!REG_P (p->exp)
185190075Sobrien			|| REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
185290075Sobrien		      continue;
185318334Speter
185490075Sobrien		    tregno = REGNO (p->exp);
185590075Sobrien		    tendregno
1856169689Skan		      = tregno + hard_regno_nregs[tregno][GET_MODE (p->exp)];
185790075Sobrien		    if (tendregno > regno && tregno < endregno)
185890075Sobrien		      remove_from_table (p, hash);
185990075Sobrien		  }
186090075Sobrien	  }
186190075Sobrien      }
186218334Speter      return;
186318334Speter
186490075Sobrien    case SUBREG:
186518334Speter      invalidate (SUBREG_REG (x), VOIDmode);
186618334Speter      return;
186718334Speter
186890075Sobrien    case PARALLEL:
186990075Sobrien      for (i = XVECLEN (x, 0) - 1; i >= 0; --i)
187050397Sobrien	invalidate (XVECEXP (x, 0, i), VOIDmode);
187150397Sobrien      return;
187250397Sobrien
187390075Sobrien    case EXPR_LIST:
187490075Sobrien      /* This is part of a disjoint return value; extract the location in
187590075Sobrien	 question ignoring the offset.  */
187650397Sobrien      invalidate (XEXP (x, 0), VOIDmode);
187750397Sobrien      return;
187850397Sobrien
187990075Sobrien    case MEM:
1880132718Skan      addr = canon_rtx (get_addr (XEXP (x, 0)));
188190075Sobrien      /* Calculate the canonical version of X here so that
188290075Sobrien	 true_dependence doesn't generate new RTL for X on each call.  */
188390075Sobrien      x = canon_rtx (x);
188418334Speter
188590075Sobrien      /* Remove all hash table elements that refer to overlapping pieces of
188690075Sobrien	 memory.  */
188790075Sobrien      if (full_mode == VOIDmode)
188890075Sobrien	full_mode = GET_MODE (x);
188918334Speter
189090075Sobrien      for (i = 0; i < HASH_SIZE; i++)
189190075Sobrien	{
189290075Sobrien	  struct table_elt *next;
189318334Speter
189490075Sobrien	  for (p = table[i]; p; p = next)
189590075Sobrien	    {
189690075Sobrien	      next = p->next_same_hash;
189790075Sobrien	      if (p->in_memory)
189890075Sobrien		{
189990075Sobrien		  struct check_dependence_data d;
190090075Sobrien
190190075Sobrien		  /* Just canonicalize the expression once;
190290075Sobrien		     otherwise each time we call invalidate
190390075Sobrien		     true_dependence will canonicalize the
190490075Sobrien		     expression again.  */
190590075Sobrien		  if (!p->canon_exp)
190690075Sobrien		    p->canon_exp = canon_rtx (p->exp);
190790075Sobrien		  d.exp = x;
1908132718Skan		  d.addr = addr;
190990075Sobrien		  d.mode = full_mode;
191090075Sobrien		  if (for_each_rtx (&p->canon_exp, check_dependence, &d))
191190075Sobrien		    remove_from_table (p, i);
191290075Sobrien		}
191390075Sobrien	    }
191418334Speter	}
191590075Sobrien      return;
191690075Sobrien
191790075Sobrien    default:
1918169689Skan      gcc_unreachable ();
191918334Speter    }
192018334Speter}
192190075Sobrien
192218334Speter/* Remove all expressions that refer to register REGNO,
192318334Speter   since they are already invalid, and we are about to
192418334Speter   mark that register valid again and don't want the old
192518334Speter   expressions to reappear as valid.  */
192618334Speter
192718334Speterstatic void
1928132718Skanremove_invalid_refs (unsigned int regno)
192918334Speter{
193090075Sobrien  unsigned int i;
193190075Sobrien  struct table_elt *p, *next;
193218334Speter
193390075Sobrien  for (i = 0; i < HASH_SIZE; i++)
193418334Speter    for (p = table[i]; p; p = next)
193518334Speter      {
193618334Speter	next = p->next_same_hash;
1937169689Skan	if (!REG_P (p->exp)
1938117395Skan	    && refers_to_regno_p (regno, regno + 1, p->exp, (rtx *) 0))
193918334Speter	  remove_from_table (p, i);
194018334Speter      }
194118334Speter}
194252284Sobrien
194390075Sobrien/* Likewise for a subreg with subreg_reg REGNO, subreg_byte OFFSET,
194490075Sobrien   and mode MODE.  */
194552284Sobrienstatic void
1946132718Skanremove_invalid_subreg_refs (unsigned int regno, unsigned int offset,
1947132718Skan			    enum machine_mode mode)
194852284Sobrien{
194990075Sobrien  unsigned int i;
195090075Sobrien  struct table_elt *p, *next;
195190075Sobrien  unsigned int end = offset + (GET_MODE_SIZE (mode) - 1);
195252284Sobrien
195390075Sobrien  for (i = 0; i < HASH_SIZE; i++)
195452284Sobrien    for (p = table[i]; p; p = next)
195552284Sobrien      {
195690075Sobrien	rtx exp = p->exp;
195752284Sobrien	next = p->next_same_hash;
195890075Sobrien
1959169689Skan	if (!REG_P (exp)
196052284Sobrien	    && (GET_CODE (exp) != SUBREG
1961169689Skan		|| !REG_P (SUBREG_REG (exp))
196252284Sobrien		|| REGNO (SUBREG_REG (exp)) != regno
196390075Sobrien		|| (((SUBREG_BYTE (exp)
196490075Sobrien		      + (GET_MODE_SIZE (GET_MODE (exp)) - 1)) >= offset)
196590075Sobrien		    && SUBREG_BYTE (exp) <= end))
1966117395Skan	    && refers_to_regno_p (regno, regno + 1, p->exp, (rtx *) 0))
196752284Sobrien	  remove_from_table (p, i);
196852284Sobrien      }
196952284Sobrien}
197018334Speter
197118334Speter/* Recompute the hash codes of any valid entries in the hash table that
197218334Speter   reference X, if X is a register, or SUBREG_REG (X) if X is a SUBREG.
197318334Speter
197418334Speter   This is called when we make a jump equivalence.  */
197518334Speter
197618334Speterstatic void
1977132718Skanrehash_using_reg (rtx x)
197818334Speter{
197952284Sobrien  unsigned int i;
198018334Speter  struct table_elt *p, *next;
198118334Speter  unsigned hash;
198218334Speter
198318334Speter  if (GET_CODE (x) == SUBREG)
198418334Speter    x = SUBREG_REG (x);
198518334Speter
198618334Speter  /* If X is not a register or if the register is known not to be in any
198718334Speter     valid entries in the table, we have no work to do.  */
198818334Speter
1989169689Skan  if (!REG_P (x)
199052284Sobrien      || REG_IN_TABLE (REGNO (x)) < 0
199152284Sobrien      || REG_IN_TABLE (REGNO (x)) != REG_TICK (REGNO (x)))
199218334Speter    return;
199318334Speter
199418334Speter  /* Scan all hash chains looking for valid entries that mention X.
1995132718Skan     If we find one and it is in the wrong hash chain, move it.  */
199618334Speter
199790075Sobrien  for (i = 0; i < HASH_SIZE; i++)
199818334Speter    for (p = table[i]; p; p = next)
199918334Speter      {
200018334Speter	next = p->next_same_hash;
2001132718Skan	if (reg_mentioned_p (x, p->exp)
2002169689Skan	    && exp_equiv_p (p->exp, p->exp, 1, false)
2003169689Skan	    && i != (hash = SAFE_HASH (p->exp, p->mode)))
200418334Speter	  {
200518334Speter	    if (p->next_same_hash)
200618334Speter	      p->next_same_hash->prev_same_hash = p->prev_same_hash;
200718334Speter
200818334Speter	    if (p->prev_same_hash)
200918334Speter	      p->prev_same_hash->next_same_hash = p->next_same_hash;
201018334Speter	    else
201118334Speter	      table[i] = p->next_same_hash;
201218334Speter
201318334Speter	    p->next_same_hash = table[hash];
201418334Speter	    p->prev_same_hash = 0;
201518334Speter	    if (table[hash])
201618334Speter	      table[hash]->prev_same_hash = p;
201718334Speter	    table[hash] = p;
201818334Speter	  }
201918334Speter      }
202018334Speter}
202118334Speter
202218334Speter/* Remove from the hash table any expression that is a call-clobbered
202318334Speter   register.  Also update their TICK values.  */
202418334Speter
202518334Speterstatic void
2026132718Skaninvalidate_for_call (void)
202718334Speter{
202890075Sobrien  unsigned int regno, endregno;
202990075Sobrien  unsigned int i;
203018334Speter  unsigned hash;
203118334Speter  struct table_elt *p, *next;
203218334Speter  int in_table = 0;
203318334Speter
203418334Speter  /* Go through all the hard registers.  For each that is clobbered in
203518334Speter     a CALL_INSN, remove the register from quantity chains and update
203618334Speter     reg_tick if defined.  Also see if any of these registers is currently
203718334Speter     in the table.  */
203818334Speter
203918334Speter  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
204018334Speter    if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
204118334Speter      {
204218334Speter	delete_reg_equiv (regno);
204352284Sobrien	if (REG_TICK (regno) >= 0)
2044117395Skan	  {
2045117395Skan	    REG_TICK (regno)++;
2046117395Skan	    SUBREG_TICKED (regno) = -1;
2047117395Skan	  }
204818334Speter
204918334Speter	in_table |= (TEST_HARD_REG_BIT (hard_regs_in_table, regno) != 0);
205018334Speter      }
205118334Speter
205218334Speter  /* In the case where we have no call-clobbered hard registers in the
205318334Speter     table, we are done.  Otherwise, scan the table and remove any
205418334Speter     entry that overlaps a call-clobbered register.  */
205518334Speter
205618334Speter  if (in_table)
205790075Sobrien    for (hash = 0; hash < HASH_SIZE; hash++)
205818334Speter      for (p = table[hash]; p; p = next)
205918334Speter	{
206018334Speter	  next = p->next_same_hash;
206118334Speter
2062169689Skan	  if (!REG_P (p->exp)
206318334Speter	      || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
206418334Speter	    continue;
206518334Speter
206618334Speter	  regno = REGNO (p->exp);
2067169689Skan	  endregno = regno + hard_regno_nregs[regno][GET_MODE (p->exp)];
206818334Speter
206918334Speter	  for (i = regno; i < endregno; i++)
207018334Speter	    if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
207118334Speter	      {
207218334Speter		remove_from_table (p, hash);
207318334Speter		break;
207418334Speter	      }
207518334Speter	}
207618334Speter}
207718334Speter
207818334Speter/* Given an expression X of type CONST,
207918334Speter   and ELT which is its table entry (or 0 if it
208018334Speter   is not in the hash table),
208118334Speter   return an alternate expression for X as a register plus integer.
208218334Speter   If none can be found, return 0.  */
208318334Speter
208418334Speterstatic rtx
2085132718Skanuse_related_value (rtx x, struct table_elt *elt)
208618334Speter{
208790075Sobrien  struct table_elt *relt = 0;
208890075Sobrien  struct table_elt *p, *q;
208918334Speter  HOST_WIDE_INT offset;
209018334Speter
209118334Speter  /* First, is there anything related known?
209218334Speter     If we have a table element, we can tell from that.
209318334Speter     Otherwise, must look it up.  */
209418334Speter
209518334Speter  if (elt != 0 && elt->related_value != 0)
209618334Speter    relt = elt;
209718334Speter  else if (elt == 0 && GET_CODE (x) == CONST)
209818334Speter    {
209918334Speter      rtx subexp = get_related_value (x);
210018334Speter      if (subexp != 0)
210118334Speter	relt = lookup (subexp,
2102169689Skan		       SAFE_HASH (subexp, GET_MODE (subexp)),
210318334Speter		       GET_MODE (subexp));
210418334Speter    }
210518334Speter
210618334Speter  if (relt == 0)
210718334Speter    return 0;
210818334Speter
210918334Speter  /* Search all related table entries for one that has an
211018334Speter     equivalent register.  */
211118334Speter
211218334Speter  p = relt;
211318334Speter  while (1)
211418334Speter    {
211518334Speter      /* This loop is strange in that it is executed in two different cases.
211618334Speter	 The first is when X is already in the table.  Then it is searching
211718334Speter	 the RELATED_VALUE list of X's class (RELT).  The second case is when
211818334Speter	 X is not in the table.  Then RELT points to a class for the related
211918334Speter	 value.
212018334Speter
212118334Speter	 Ensure that, whatever case we are in, that we ignore classes that have
212218334Speter	 the same value as X.  */
212318334Speter
212418334Speter      if (rtx_equal_p (x, p->exp))
212518334Speter	q = 0;
212618334Speter      else
212718334Speter	for (q = p->first_same_value; q; q = q->next_same_value)
2128169689Skan	  if (REG_P (q->exp))
212918334Speter	    break;
213018334Speter
213118334Speter      if (q)
213218334Speter	break;
213318334Speter
213418334Speter      p = p->related_value;
213518334Speter
213618334Speter      /* We went all the way around, so there is nothing to be found.
213718334Speter	 Alternatively, perhaps RELT was in the table for some other reason
213818334Speter	 and it has no related values recorded.  */
213918334Speter      if (p == relt || p == 0)
214018334Speter	break;
214118334Speter    }
214218334Speter
214318334Speter  if (q == 0)
214418334Speter    return 0;
214518334Speter
214618334Speter  offset = (get_integer_term (x) - get_integer_term (p->exp));
214718334Speter  /* Note: OFFSET may be 0 if P->xexp and X are related by commutativity.  */
214818334Speter  return plus_constant (q->exp, offset);
214918334Speter}
215018334Speter
215190075Sobrien/* Hash a string.  Just add its bytes up.  */
215290075Sobrienstatic inline unsigned
2153169689Skanhash_rtx_string (const char *ps)
215490075Sobrien{
215590075Sobrien  unsigned hash = 0;
2156117395Skan  const unsigned char *p = (const unsigned char *) ps;
2157117395Skan
215890075Sobrien  if (p)
215990075Sobrien    while (*p)
216090075Sobrien      hash += *p++;
216190075Sobrien
216290075Sobrien  return hash;
216390075Sobrien}
216490075Sobrien
216518334Speter/* Hash an rtx.  We are careful to make sure the value is never negative.
216618334Speter   Equivalent registers hash identically.
216718334Speter   MODE is used in hashing for CONST_INTs only;
216818334Speter   otherwise the mode of X is used.
216918334Speter
2170169689Skan   Store 1 in DO_NOT_RECORD_P if any subexpression is volatile.
217118334Speter
2172169689Skan   If HASH_ARG_IN_MEMORY_P is not NULL, store 1 in it if X contains
2173169689Skan   a MEM rtx which does not have the RTX_UNCHANGING_P bit set.
217418334Speter
217518334Speter   Note that cse_insn knows that the hash code of a MEM expression
217618334Speter   is just (int) MEM plus the hash code of the address.  */
217718334Speter
2178169689Skanunsigned
2179169689Skanhash_rtx (rtx x, enum machine_mode mode, int *do_not_record_p,
2180169689Skan	  int *hash_arg_in_memory_p, bool have_reg_qty)
218118334Speter{
218290075Sobrien  int i, j;
218390075Sobrien  unsigned hash = 0;
218490075Sobrien  enum rtx_code code;
218590075Sobrien  const char *fmt;
218618334Speter
2187169689Skan  /* Used to turn recursion into iteration.  We can't rely on GCC's
2188169689Skan     tail-recursion elimination since we need to keep accumulating values
2189169689Skan     in HASH.  */
219018334Speter repeat:
219118334Speter  if (x == 0)
219218334Speter    return hash;
219318334Speter
219418334Speter  code = GET_CODE (x);
219518334Speter  switch (code)
219618334Speter    {
219718334Speter    case REG:
219818334Speter      {
219990075Sobrien	unsigned int regno = REGNO (x);
220018334Speter
2201169689Skan	if (!reload_completed)
2202169689Skan	  {
2203169689Skan	    /* On some machines, we can't record any non-fixed hard register,
2204169689Skan	       because extending its life will cause reload problems.  We
2205169689Skan	       consider ap, fp, sp, gp to be fixed for this purpose.
220652284Sobrien
2207169689Skan	       We also consider CCmode registers to be fixed for this purpose;
2208169689Skan	       failure to do so leads to failure to simplify 0<100 type of
2209169689Skan	       conditionals.
221052284Sobrien
2211169689Skan	       On all machines, we can't record any global registers.
2212169689Skan	       Nor should we record any register that is in a small
2213169689Skan	       class, as defined by CLASS_LIKELY_SPILLED_P.  */
2214169689Skan	    bool record;
221518334Speter
2216169689Skan	    if (regno >= FIRST_PSEUDO_REGISTER)
2217169689Skan	      record = true;
2218169689Skan	    else if (x == frame_pointer_rtx
2219169689Skan		     || x == hard_frame_pointer_rtx
2220169689Skan		     || x == arg_pointer_rtx
2221169689Skan		     || x == stack_pointer_rtx
2222169689Skan		     || x == pic_offset_table_rtx)
2223169689Skan	      record = true;
2224169689Skan	    else if (global_regs[regno])
2225169689Skan	      record = false;
2226169689Skan	    else if (fixed_regs[regno])
2227169689Skan	      record = true;
2228169689Skan	    else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC)
2229169689Skan	      record = true;
2230169689Skan	    else if (SMALL_REGISTER_CLASSES)
2231169689Skan	      record = false;
2232169689Skan	    else if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno)))
2233169689Skan	      record = false;
2234169689Skan	    else
2235169689Skan	      record = true;
2236132718Skan
2237169689Skan	    if (!record)
2238169689Skan	      {
2239169689Skan		*do_not_record_p = 1;
2240169689Skan		return 0;
2241169689Skan	      }
224218334Speter	  }
224390075Sobrien
2244169689Skan	hash += ((unsigned int) REG << 7);
2245169689Skan        hash += (have_reg_qty ? (unsigned) REG_QTY (regno) : regno);
224618334Speter	return hash;
224718334Speter      }
224818334Speter
224952284Sobrien    /* We handle SUBREG of a REG specially because the underlying
225052284Sobrien       reg changes its hash value with every value change; we don't
225152284Sobrien       want to have to forget unrelated subregs when one subreg changes.  */
225252284Sobrien    case SUBREG:
225352284Sobrien      {
2254169689Skan	if (REG_P (SUBREG_REG (x)))
225552284Sobrien	  {
2256169689Skan	    hash += (((unsigned int) SUBREG << 7)
225790075Sobrien		     + REGNO (SUBREG_REG (x))
225890075Sobrien		     + (SUBREG_BYTE (x) / UNITS_PER_WORD));
225952284Sobrien	    return hash;
226052284Sobrien	  }
226152284Sobrien	break;
226252284Sobrien      }
226352284Sobrien
226418334Speter    case CONST_INT:
2265169689Skan      hash += (((unsigned int) CONST_INT << 7) + (unsigned int) mode
2266169689Skan               + (unsigned int) INTVAL (x));
2267169689Skan      return hash;
226818334Speter
226918334Speter    case CONST_DOUBLE:
227018334Speter      /* This is like the general case, except that it only counts
227118334Speter	 the integers representing the constant.  */
2272169689Skan      hash += (unsigned int) code + (unsigned int) GET_MODE (x);
227318334Speter      if (GET_MODE (x) != VOIDmode)
2274117395Skan	hash += real_hash (CONST_DOUBLE_REAL_VALUE (x));
227518334Speter      else
2276169689Skan	hash += ((unsigned int) CONST_DOUBLE_LOW (x)
2277169689Skan		 + (unsigned int) CONST_DOUBLE_HIGH (x));
227818334Speter      return hash;
227918334Speter
228096263Sobrien    case CONST_VECTOR:
228196263Sobrien      {
228296263Sobrien	int units;
228396263Sobrien	rtx elt;
228496263Sobrien
228596263Sobrien	units = CONST_VECTOR_NUNITS (x);
228696263Sobrien
228796263Sobrien	for (i = 0; i < units; ++i)
228896263Sobrien	  {
228996263Sobrien	    elt = CONST_VECTOR_ELT (x, i);
2290169689Skan	    hash += hash_rtx (elt, GET_MODE (elt), do_not_record_p,
2291169689Skan			      hash_arg_in_memory_p, have_reg_qty);
229296263Sobrien	  }
229396263Sobrien
229496263Sobrien	return hash;
229596263Sobrien      }
229696263Sobrien
229718334Speter      /* Assume there is only one rtx object for any given label.  */
229818334Speter    case LABEL_REF:
2299169689Skan      /* We don't hash on the address of the CODE_LABEL to avoid bootstrap
2300169689Skan	 differences and differences between each stage's debugging dumps.  */
2301169689Skan	 hash += (((unsigned int) LABEL_REF << 7)
2302169689Skan		  + CODE_LABEL_NUMBER (XEXP (x, 0)));
230318334Speter      return hash;
230418334Speter
230518334Speter    case SYMBOL_REF:
2306169689Skan      {
2307169689Skan	/* Don't hash on the symbol's address to avoid bootstrap differences.
2308169689Skan	   Different hash values may cause expressions to be recorded in
2309169689Skan	   different orders and thus different registers to be used in the
2310169689Skan	   final assembler.  This also avoids differences in the dump files
2311169689Skan	   between various stages.  */
2312169689Skan	unsigned int h = 0;
2313169689Skan	const unsigned char *p = (const unsigned char *) XSTR (x, 0);
231418334Speter
2315169689Skan	while (*p)
2316169689Skan	  h += (h << 7) + *p++; /* ??? revisit */
2317169689Skan
2318169689Skan	hash += ((unsigned int) SYMBOL_REF << 7) + h;
2319169689Skan	return hash;
2320169689Skan      }
2321169689Skan
232218334Speter    case MEM:
232390075Sobrien      /* We don't record if marked volatile or if BLKmode since we don't
232490075Sobrien	 know the size of the move.  */
232590075Sobrien      if (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode)
232618334Speter	{
2327169689Skan	  *do_not_record_p = 1;
232818334Speter	  return 0;
232918334Speter	}
2330169689Skan      if (hash_arg_in_memory_p && !MEM_READONLY_P (x))
2331169689Skan	*hash_arg_in_memory_p = 1;
2332132718Skan
233318334Speter      /* Now that we have already found this special case,
233418334Speter	 might as well speed it up as much as possible.  */
233518334Speter      hash += (unsigned) MEM;
233618334Speter      x = XEXP (x, 0);
233718334Speter      goto repeat;
233818334Speter
233990075Sobrien    case USE:
234090075Sobrien      /* A USE that mentions non-volatile memory needs special
234190075Sobrien	 handling since the MEM may be BLKmode which normally
234290075Sobrien	 prevents an entry from being made.  Pure calls are
2343169689Skan	 marked by a USE which mentions BLKmode memory.
2344169689Skan	 See calls.c:emit_call_1.  */
2345169689Skan      if (MEM_P (XEXP (x, 0))
234690075Sobrien	  && ! MEM_VOLATILE_P (XEXP (x, 0)))
234790075Sobrien	{
2348117395Skan	  hash += (unsigned) USE;
234990075Sobrien	  x = XEXP (x, 0);
235090075Sobrien
2351169689Skan	  if (hash_arg_in_memory_p && !MEM_READONLY_P (x))
2352169689Skan	    *hash_arg_in_memory_p = 1;
235390075Sobrien
235490075Sobrien	  /* Now that we have already found this special case,
235590075Sobrien	     might as well speed it up as much as possible.  */
235690075Sobrien	  hash += (unsigned) MEM;
235790075Sobrien	  x = XEXP (x, 0);
235890075Sobrien	  goto repeat;
235990075Sobrien	}
236090075Sobrien      break;
236190075Sobrien
236218334Speter    case PRE_DEC:
236318334Speter    case PRE_INC:
236418334Speter    case POST_DEC:
236518334Speter    case POST_INC:
236690075Sobrien    case PRE_MODIFY:
236790075Sobrien    case POST_MODIFY:
236818334Speter    case PC:
236918334Speter    case CC0:
237018334Speter    case CALL:
237118334Speter    case UNSPEC_VOLATILE:
2372169689Skan      *do_not_record_p = 1;
237318334Speter      return 0;
237418334Speter
237518334Speter    case ASM_OPERANDS:
237618334Speter      if (MEM_VOLATILE_P (x))
237718334Speter	{
2378169689Skan	  *do_not_record_p = 1;
237918334Speter	  return 0;
238018334Speter	}
238190075Sobrien      else
238290075Sobrien	{
238390075Sobrien	  /* We don't want to take the filename and line into account.  */
238490075Sobrien	  hash += (unsigned) code + (unsigned) GET_MODE (x)
2385169689Skan	    + hash_rtx_string (ASM_OPERANDS_TEMPLATE (x))
2386169689Skan	    + hash_rtx_string (ASM_OPERANDS_OUTPUT_CONSTRAINT (x))
238790075Sobrien	    + (unsigned) ASM_OPERANDS_OUTPUT_IDX (x);
238890075Sobrien
238990075Sobrien	  if (ASM_OPERANDS_INPUT_LENGTH (x))
239090075Sobrien	    {
239190075Sobrien	      for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
239290075Sobrien		{
2393169689Skan		  hash += (hash_rtx (ASM_OPERANDS_INPUT (x, i),
2394169689Skan				     GET_MODE (ASM_OPERANDS_INPUT (x, i)),
2395169689Skan				     do_not_record_p, hash_arg_in_memory_p,
2396169689Skan				     have_reg_qty)
2397169689Skan			   + hash_rtx_string
2398169689Skan				(ASM_OPERANDS_INPUT_CONSTRAINT (x, i)));
239990075Sobrien		}
240090075Sobrien
2401169689Skan	      hash += hash_rtx_string (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0));
240290075Sobrien	      x = ASM_OPERANDS_INPUT (x, 0);
240390075Sobrien	      mode = GET_MODE (x);
240490075Sobrien	      goto repeat;
240590075Sobrien	    }
240690075Sobrien
240790075Sobrien	  return hash;
240890075Sobrien	}
240950397Sobrien      break;
241090075Sobrien
241150397Sobrien    default:
241250397Sobrien      break;
241318334Speter    }
241418334Speter
241518334Speter  i = GET_RTX_LENGTH (code) - 1;
241618334Speter  hash += (unsigned) code + (unsigned) GET_MODE (x);
241718334Speter  fmt = GET_RTX_FORMAT (code);
241818334Speter  for (; i >= 0; i--)
241918334Speter    {
2420169689Skan      switch (fmt[i])
242118334Speter	{
2422169689Skan	case 'e':
242318334Speter	  /* If we are about to do the last recursive call
242418334Speter	     needed at this level, change it into iteration.
242518334Speter	     This function  is called enough to be worth it.  */
242618334Speter	  if (i == 0)
242718334Speter	    {
2428169689Skan	      x = XEXP (x, i);
242918334Speter	      goto repeat;
243018334Speter	    }
2431169689Skan
2432169689Skan	  hash += hash_rtx (XEXP (x, i), 0, do_not_record_p,
2433169689Skan			    hash_arg_in_memory_p, have_reg_qty);
2434169689Skan	  break;
2435169689Skan
2436169689Skan	case 'E':
2437169689Skan	  for (j = 0; j < XVECLEN (x, i); j++)
2438169689Skan	    hash += hash_rtx (XVECEXP (x, i, j), 0, do_not_record_p,
2439169689Skan			      hash_arg_in_memory_p, have_reg_qty);
2440169689Skan	  break;
2441169689Skan
2442169689Skan	case 's':
2443169689Skan	  hash += hash_rtx_string (XSTR (x, i));
2444169689Skan	  break;
2445169689Skan
2446169689Skan	case 'i':
2447169689Skan	  hash += (unsigned int) XINT (x, i);
2448169689Skan	  break;
2449169689Skan
2450169689Skan	case '0': case 't':
2451169689Skan	  /* Unused.  */
2452169689Skan	  break;
2453169689Skan
2454169689Skan	default:
2455169689Skan	  gcc_unreachable ();
245618334Speter	}
245718334Speter    }
2458169689Skan
245918334Speter  return hash;
246018334Speter}
246118334Speter
2462169689Skan/* Hash an rtx X for cse via hash_rtx.
2463169689Skan   Stores 1 in do_not_record if any subexpression is volatile.
2464169689Skan   Stores 1 in hash_arg_in_memory if X contains a mem rtx which
2465169689Skan   does not have the RTX_UNCHANGING_P bit set.  */
246618334Speter
2467169689Skanstatic inline unsigned
2468169689Skancanon_hash (rtx x, enum machine_mode mode)
2469169689Skan{
2470169689Skan  return hash_rtx (x, mode, &do_not_record, &hash_arg_in_memory, true);
2471169689Skan}
2472169689Skan
2473169689Skan/* Like canon_hash but with no side effects, i.e. do_not_record
2474169689Skan   and hash_arg_in_memory are not changed.  */
2475169689Skan
2476169689Skanstatic inline unsigned
2477132718Skansafe_hash (rtx x, enum machine_mode mode)
247818334Speter{
2479169689Skan  int dummy_do_not_record;
2480169689Skan  return hash_rtx (x, mode, &dummy_do_not_record, NULL, true);
248118334Speter}
248218334Speter
248318334Speter/* Return 1 iff X and Y would canonicalize into the same thing,
248418334Speter   without actually constructing the canonicalization of either one.
248518334Speter   If VALIDATE is nonzero,
248618334Speter   we assume X is an expression being processed from the rtl
248718334Speter   and Y was found in the hash table.  We check register refs
248818334Speter   in Y for being marked as valid.
248918334Speter
2490169689Skan   If FOR_GCSE is true, we compare X and Y for equivalence for GCSE.  */
249118334Speter
2492169689Skanint
2493169689Skanexp_equiv_p (rtx x, rtx y, int validate, bool for_gcse)
249418334Speter{
249590075Sobrien  int i, j;
249690075Sobrien  enum rtx_code code;
249790075Sobrien  const char *fmt;
249818334Speter
249918334Speter  /* Note: it is incorrect to assume an expression is equivalent to itself
250018334Speter     if VALIDATE is nonzero.  */
250118334Speter  if (x == y && !validate)
250218334Speter    return 1;
2503169689Skan
250418334Speter  if (x == 0 || y == 0)
250518334Speter    return x == y;
250618334Speter
250718334Speter  code = GET_CODE (x);
250818334Speter  if (code != GET_CODE (y))
2509169689Skan    return 0;
251018334Speter
251118334Speter  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
251218334Speter  if (GET_MODE (x) != GET_MODE (y))
251318334Speter    return 0;
251418334Speter
251518334Speter  switch (code)
251618334Speter    {
251718334Speter    case PC:
251818334Speter    case CC0:
251990075Sobrien    case CONST_INT:
2520169689Skan    case CONST_DOUBLE:
252118334Speter      return x == y;
252218334Speter
252318334Speter    case LABEL_REF:
252418334Speter      return XEXP (x, 0) == XEXP (y, 0);
252518334Speter
252618334Speter    case SYMBOL_REF:
252718334Speter      return XSTR (x, 0) == XSTR (y, 0);
252818334Speter
252918334Speter    case REG:
2530169689Skan      if (for_gcse)
2531169689Skan	return REGNO (x) == REGNO (y);
2532169689Skan      else
2533169689Skan	{
2534169689Skan	  unsigned int regno = REGNO (y);
2535169689Skan	  unsigned int i;
2536169689Skan	  unsigned int endregno
2537169689Skan	    = regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
2538169689Skan		       : hard_regno_nregs[regno][GET_MODE (y)]);
253918334Speter
2540169689Skan	  /* If the quantities are not the same, the expressions are not
2541169689Skan	     equivalent.  If there are and we are not to validate, they
2542169689Skan	     are equivalent.  Otherwise, ensure all regs are up-to-date.  */
254318334Speter
2544169689Skan	  if (REG_QTY (REGNO (x)) != REG_QTY (regno))
2545169689Skan	    return 0;
254618334Speter
2547169689Skan	  if (! validate)
2548169689Skan	    return 1;
2549169689Skan
2550169689Skan	  for (i = regno; i < endregno; i++)
2551169689Skan	    if (REG_IN_TABLE (i) != REG_TICK (i))
2552169689Skan	      return 0;
2553169689Skan
255418334Speter	  return 1;
2555169689Skan	}
255618334Speter
2557169689Skan    case MEM:
2558169689Skan      if (for_gcse)
2559169689Skan	{
2560169689Skan	  /* A volatile mem should not be considered equivalent to any
2561169689Skan	     other.  */
2562169689Skan	  if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
256318334Speter	    return 0;
256418334Speter
2565169689Skan	  /* Can't merge two expressions in different alias sets, since we
2566169689Skan	     can decide that the expression is transparent in a block when
2567169689Skan	     it isn't, due to it being set with the different alias set.
256818334Speter
2569169689Skan	     Also, can't merge two expressions with different MEM_ATTRS.
2570169689Skan	     They could e.g. be two different entities allocated into the
2571169689Skan	     same space on the stack (see e.g. PR25130).  In that case, the
2572169689Skan	     MEM addresses can be the same, even though the two MEMs are
2573169689Skan	     absolutely not equivalent.
2574169689Skan
2575169689Skan	     But because really all MEM attributes should be the same for
2576169689Skan	     equivalent MEMs, we just use the invariant that MEMs that have
2577169689Skan	     the same attributes share the same mem_attrs data structure.  */
2578169689Skan	  if (MEM_ATTRS (x) != MEM_ATTRS (y))
2579169689Skan	    return 0;
2580169689Skan	}
2581169689Skan      break;
2582169689Skan
258318334Speter    /*  For commutative operations, check both orders.  */
258418334Speter    case PLUS:
258518334Speter    case MULT:
258618334Speter    case AND:
258718334Speter    case IOR:
258818334Speter    case XOR:
258918334Speter    case NE:
259018334Speter    case EQ:
2591169689Skan      return ((exp_equiv_p (XEXP (x, 0), XEXP (y, 0),
2592169689Skan			     validate, for_gcse)
259318334Speter	       && exp_equiv_p (XEXP (x, 1), XEXP (y, 1),
2594169689Skan				validate, for_gcse))
259518334Speter	      || (exp_equiv_p (XEXP (x, 0), XEXP (y, 1),
2596169689Skan				validate, for_gcse)
259718334Speter		  && exp_equiv_p (XEXP (x, 1), XEXP (y, 0),
2598169689Skan				   validate, for_gcse)));
259990075Sobrien
260090075Sobrien    case ASM_OPERANDS:
260190075Sobrien      /* We don't use the generic code below because we want to
260290075Sobrien	 disregard filename and line numbers.  */
260390075Sobrien
260490075Sobrien      /* A volatile asm isn't equivalent to any other.  */
260590075Sobrien      if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
260690075Sobrien	return 0;
260790075Sobrien
260890075Sobrien      if (GET_MODE (x) != GET_MODE (y)
260990075Sobrien	  || strcmp (ASM_OPERANDS_TEMPLATE (x), ASM_OPERANDS_TEMPLATE (y))
261090075Sobrien	  || strcmp (ASM_OPERANDS_OUTPUT_CONSTRAINT (x),
261190075Sobrien		     ASM_OPERANDS_OUTPUT_CONSTRAINT (y))
261290075Sobrien	  || ASM_OPERANDS_OUTPUT_IDX (x) != ASM_OPERANDS_OUTPUT_IDX (y)
261390075Sobrien	  || ASM_OPERANDS_INPUT_LENGTH (x) != ASM_OPERANDS_INPUT_LENGTH (y))
261490075Sobrien	return 0;
261590075Sobrien
261690075Sobrien      if (ASM_OPERANDS_INPUT_LENGTH (x))
261790075Sobrien	{
261890075Sobrien	  for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
261990075Sobrien	    if (! exp_equiv_p (ASM_OPERANDS_INPUT (x, i),
262090075Sobrien			       ASM_OPERANDS_INPUT (y, i),
2621169689Skan			       validate, for_gcse)
262290075Sobrien		|| strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i),
262390075Sobrien			   ASM_OPERANDS_INPUT_CONSTRAINT (y, i)))
262490075Sobrien	      return 0;
262590075Sobrien	}
262690075Sobrien
262790075Sobrien      return 1;
262890075Sobrien
262950397Sobrien    default:
263050397Sobrien      break;
263118334Speter    }
263218334Speter
263318334Speter  /* Compare the elements.  If any pair of corresponding elements
2634169689Skan     fail to match, return 0 for the whole thing.  */
263518334Speter
263618334Speter  fmt = GET_RTX_FORMAT (code);
263718334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
263818334Speter    {
263918334Speter      switch (fmt[i])
264018334Speter	{
264118334Speter	case 'e':
2642169689Skan	  if (! exp_equiv_p (XEXP (x, i), XEXP (y, i),
2643169689Skan			      validate, for_gcse))
264418334Speter	    return 0;
264518334Speter	  break;
264618334Speter
264718334Speter	case 'E':
264818334Speter	  if (XVECLEN (x, i) != XVECLEN (y, i))
264918334Speter	    return 0;
265018334Speter	  for (j = 0; j < XVECLEN (x, i); j++)
265118334Speter	    if (! exp_equiv_p (XVECEXP (x, i, j), XVECEXP (y, i, j),
2652169689Skan				validate, for_gcse))
265318334Speter	      return 0;
265418334Speter	  break;
265518334Speter
265618334Speter	case 's':
265718334Speter	  if (strcmp (XSTR (x, i), XSTR (y, i)))
265818334Speter	    return 0;
265918334Speter	  break;
266018334Speter
266118334Speter	case 'i':
266218334Speter	  if (XINT (x, i) != XINT (y, i))
266318334Speter	    return 0;
266418334Speter	  break;
266518334Speter
266618334Speter	case 'w':
266718334Speter	  if (XWINT (x, i) != XWINT (y, i))
266818334Speter	    return 0;
266990075Sobrien	  break;
267018334Speter
267118334Speter	case '0':
267290075Sobrien	case 't':
267318334Speter	  break;
267418334Speter
267518334Speter	default:
2676169689Skan	  gcc_unreachable ();
267718334Speter	}
267890075Sobrien    }
267918334Speter
268018334Speter  return 1;
268118334Speter}
268218334Speter
268350397Sobrien/* Return 1 if X has a value that can vary even between two
268450397Sobrien   executions of the program.  0 means X can be compared reliably
268550397Sobrien   against certain constants or near-constants.  */
268618334Speter
268718334Speterstatic int
2688132718Skancse_rtx_varies_p (rtx x, int from_alias)
268918334Speter{
269018334Speter  /* We need not check for X and the equivalence class being of the same
269118334Speter     mode because if X is equivalent to a constant in some mode, it
269218334Speter     doesn't vary in any mode.  */
269318334Speter
2694169689Skan  if (REG_P (x)
269590075Sobrien      && REGNO_QTY_VALID_P (REGNO (x)))
269690075Sobrien    {
269790075Sobrien      int x_q = REG_QTY (REGNO (x));
269890075Sobrien      struct qty_table_elem *x_ent = &qty_table[x_q];
269950397Sobrien
270090075Sobrien      if (GET_MODE (x) == x_ent->mode
270190075Sobrien	  && x_ent->const_rtx != NULL_RTX)
270290075Sobrien	return 0;
270390075Sobrien    }
270490075Sobrien
270550397Sobrien  if (GET_CODE (x) == PLUS
270650397Sobrien      && GET_CODE (XEXP (x, 1)) == CONST_INT
2707169689Skan      && REG_P (XEXP (x, 0))
270890075Sobrien      && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))))
270990075Sobrien    {
271090075Sobrien      int x0_q = REG_QTY (REGNO (XEXP (x, 0)));
271190075Sobrien      struct qty_table_elem *x0_ent = &qty_table[x0_q];
271218334Speter
271390075Sobrien      if ((GET_MODE (XEXP (x, 0)) == x0_ent->mode)
271490075Sobrien	  && x0_ent->const_rtx != NULL_RTX)
271590075Sobrien	return 0;
271690075Sobrien    }
271790075Sobrien
271818334Speter  /* This can happen as the result of virtual register instantiation, if
271918334Speter     the initial constant is too large to be a valid address.  This gives
272018334Speter     us a three instruction sequence, load large offset into a register,
272118334Speter     load fp minus a constant into a register, then a MEM which is the
272218334Speter     sum of the two `constant' registers.  */
272350397Sobrien  if (GET_CODE (x) == PLUS
2724169689Skan      && REG_P (XEXP (x, 0))
2725169689Skan      && REG_P (XEXP (x, 1))
272650397Sobrien      && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0)))
272790075Sobrien      && REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))))
272890075Sobrien    {
272990075Sobrien      int x0_q = REG_QTY (REGNO (XEXP (x, 0)));
273090075Sobrien      int x1_q = REG_QTY (REGNO (XEXP (x, 1)));
273190075Sobrien      struct qty_table_elem *x0_ent = &qty_table[x0_q];
273290075Sobrien      struct qty_table_elem *x1_ent = &qty_table[x1_q];
273318334Speter
273490075Sobrien      if ((GET_MODE (XEXP (x, 0)) == x0_ent->mode)
273590075Sobrien	  && x0_ent->const_rtx != NULL_RTX
273690075Sobrien	  && (GET_MODE (XEXP (x, 1)) == x1_ent->mode)
273790075Sobrien	  && x1_ent->const_rtx != NULL_RTX)
273890075Sobrien	return 0;
273990075Sobrien    }
274090075Sobrien
274190075Sobrien  return rtx_varies_p (x, from_alias);
274218334Speter}
274318334Speter
2744169689Skan/* Subroutine of canon_reg.  Pass *XLOC through canon_reg, and validate
2745169689Skan   the result if necessary.  INSN is as for canon_reg.  */
2746169689Skan
2747169689Skanstatic void
2748169689Skanvalidate_canon_reg (rtx *xloc, rtx insn)
2749169689Skan{
2750169689Skan  rtx new = canon_reg (*xloc, insn);
2751169689Skan
2752169689Skan  /* If replacing pseudo with hard reg or vice versa, ensure the
2753169689Skan     insn remains valid.  Likewise if the insn has MATCH_DUPs.  */
2754169689Skan  if (insn != 0 && new != 0)
2755169689Skan    validate_change (insn, xloc, new, 1);
2756169689Skan  else
2757169689Skan    *xloc = new;
2758169689Skan}
2759169689Skan
276018334Speter/* Canonicalize an expression:
276118334Speter   replace each register reference inside it
276218334Speter   with the "oldest" equivalent register.
276318334Speter
2764169689Skan   If INSN is nonzero validate_change is used to ensure that INSN remains valid
2765117395Skan   after we make our substitution.  The calls are made with IN_GROUP nonzero
276618334Speter   so apply_change_group must be called upon the outermost return from this
276718334Speter   function (unless INSN is zero).  The result of apply_change_group can
276818334Speter   generally be discarded since the changes we are making are optional.  */
276918334Speter
277018334Speterstatic rtx
2771132718Skancanon_reg (rtx x, rtx insn)
277218334Speter{
277390075Sobrien  int i;
277490075Sobrien  enum rtx_code code;
277590075Sobrien  const char *fmt;
277618334Speter
277718334Speter  if (x == 0)
277818334Speter    return x;
277918334Speter
278018334Speter  code = GET_CODE (x);
278118334Speter  switch (code)
278218334Speter    {
278318334Speter    case PC:
278418334Speter    case CC0:
278518334Speter    case CONST:
278618334Speter    case CONST_INT:
278718334Speter    case CONST_DOUBLE:
278896263Sobrien    case CONST_VECTOR:
278918334Speter    case SYMBOL_REF:
279018334Speter    case LABEL_REF:
279118334Speter    case ADDR_VEC:
279218334Speter    case ADDR_DIFF_VEC:
279318334Speter      return x;
279418334Speter
279518334Speter    case REG:
279618334Speter      {
279790075Sobrien	int first;
279890075Sobrien	int q;
279990075Sobrien	struct qty_table_elem *ent;
280018334Speter
280118334Speter	/* Never replace a hard reg, because hard regs can appear
280218334Speter	   in more than one machine mode, and we must preserve the mode
280318334Speter	   of each occurrence.  Also, some hard regs appear in
280418334Speter	   MEMs that are shared and mustn't be altered.  Don't try to
280518334Speter	   replace any reg that maps to a reg of class NO_REGS.  */
280618334Speter	if (REGNO (x) < FIRST_PSEUDO_REGISTER
280718334Speter	    || ! REGNO_QTY_VALID_P (REGNO (x)))
280818334Speter	  return x;
280918334Speter
281090075Sobrien	q = REG_QTY (REGNO (x));
281190075Sobrien	ent = &qty_table[q];
281290075Sobrien	first = ent->first_reg;
281318334Speter	return (first >= FIRST_PSEUDO_REGISTER ? regno_reg_rtx[first]
281418334Speter		: REGNO_REG_CLASS (first) == NO_REGS ? x
281590075Sobrien		: gen_rtx_REG (ent->mode, first));
281618334Speter      }
281790075Sobrien
281850397Sobrien    default:
281950397Sobrien      break;
282018334Speter    }
282118334Speter
282218334Speter  fmt = GET_RTX_FORMAT (code);
282318334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
282418334Speter    {
282590075Sobrien      int j;
282618334Speter
282718334Speter      if (fmt[i] == 'e')
2828169689Skan	validate_canon_reg (&XEXP (x, i), insn);
282918334Speter      else if (fmt[i] == 'E')
283018334Speter	for (j = 0; j < XVECLEN (x, i); j++)
2831169689Skan	  validate_canon_reg (&XVECEXP (x, i, j), insn);
283218334Speter    }
283318334Speter
283418334Speter  return x;
283518334Speter}
283618334Speter
283750397Sobrien/* LOC is a location within INSN that is an operand address (the contents of
283818334Speter   a MEM).  Find the best equivalent address to use that is valid for this
283918334Speter   insn.
284018334Speter
284118334Speter   On most CISC machines, complicated address modes are costly, and rtx_cost
284218334Speter   is a good approximation for that cost.  However, most RISC machines have
284318334Speter   only a few (usually only one) memory reference formats.  If an address is
284418334Speter   valid at all, it is often just as cheap as any other address.  Hence, for
2845132718Skan   RISC machines, we use `address_cost' to compare the costs of various
2846132718Skan   addresses.  For two addresses of equal cost, choose the one with the
2847132718Skan   highest `rtx_cost' value as that has the potential of eliminating the
2848132718Skan   most insns.  For equal costs, we choose the first in the equivalence
2849132718Skan   class.  Note that we ignore the fact that pseudo registers are cheaper than
2850132718Skan   hard registers here because we would also prefer the pseudo registers.  */
285118334Speter
285218334Speterstatic void
2853132718Skanfind_best_addr (rtx insn, rtx *loc, enum machine_mode mode)
285418334Speter{
285550397Sobrien  struct table_elt *elt;
285618334Speter  rtx addr = *loc;
285750397Sobrien  struct table_elt *p;
285818334Speter  int found_better = 1;
285918334Speter  int save_do_not_record = do_not_record;
286018334Speter  int save_hash_arg_in_memory = hash_arg_in_memory;
286118334Speter  int addr_volatile;
286218334Speter  int regno;
286318334Speter  unsigned hash;
286418334Speter
286518334Speter  /* Do not try to replace constant addresses or addresses of local and
286618334Speter     argument slots.  These MEM expressions are made only once and inserted
286718334Speter     in many instructions, as well as being used to control symbol table
286818334Speter     output.  It is not safe to clobber them.
286918334Speter
287018334Speter     There are some uncommon cases where the address is already in a register
287118334Speter     for some reason, but we cannot take advantage of that because we have
287218334Speter     no easy way to unshare the MEM.  In addition, looking up all stack
287318334Speter     addresses is costly.  */
287418334Speter  if ((GET_CODE (addr) == PLUS
2875169689Skan       && REG_P (XEXP (addr, 0))
287618334Speter       && GET_CODE (XEXP (addr, 1)) == CONST_INT
287718334Speter       && (regno = REGNO (XEXP (addr, 0)),
287818334Speter	   regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM
287918334Speter	   || regno == ARG_POINTER_REGNUM))
2880169689Skan      || (REG_P (addr)
288118334Speter	  && (regno = REGNO (addr), regno == FRAME_POINTER_REGNUM
288218334Speter	      || regno == HARD_FRAME_POINTER_REGNUM
288318334Speter	      || regno == ARG_POINTER_REGNUM))
288418334Speter      || CONSTANT_ADDRESS_P (addr))
288518334Speter    return;
288618334Speter
288718334Speter  /* If this address is not simply a register, try to fold it.  This will
288818334Speter     sometimes simplify the expression.  Many simplifications
288918334Speter     will not be valid, but some, usually applying the associative rule, will
289018334Speter     be valid and produce better code.  */
2891169689Skan  if (!REG_P (addr))
289250397Sobrien    {
2893169689Skan      rtx folded = canon_for_address (fold_rtx (addr, NULL_RTX));
289450397Sobrien
2895169689Skan      if (folded != addr)
2896169689Skan	{
2897169689Skan	  int addr_folded_cost = address_cost (folded, mode);
2898169689Skan	  int addr_cost = address_cost (addr, mode);
2899169689Skan
2900169689Skan	  if ((addr_folded_cost < addr_cost
2901169689Skan	       || (addr_folded_cost == addr_cost
2902169689Skan		   /* ??? The rtx_cost comparison is left over from an older
2903169689Skan		      version of this code.  It is probably no longer helpful.*/
2904169689Skan		   && (rtx_cost (folded, MEM) > rtx_cost (addr, MEM)
2905169689Skan		       || approx_reg_cost (folded) < approx_reg_cost (addr))))
2906169689Skan	      && validate_change (insn, loc, folded, 0))
2907169689Skan	    addr = folded;
2908169689Skan	}
290950397Sobrien    }
291090075Sobrien
291118334Speter  /* If this address is not in the hash table, we can't look for equivalences
291218334Speter     of the whole address.  Also, ignore if volatile.  */
291318334Speter
291418334Speter  do_not_record = 0;
291518334Speter  hash = HASH (addr, Pmode);
291618334Speter  addr_volatile = do_not_record;
291718334Speter  do_not_record = save_do_not_record;
291818334Speter  hash_arg_in_memory = save_hash_arg_in_memory;
291918334Speter
292018334Speter  if (addr_volatile)
292118334Speter    return;
292218334Speter
292318334Speter  elt = lookup (addr, hash, Pmode);
292418334Speter
292518334Speter  if (elt)
292618334Speter    {
292718334Speter      /* We need to find the best (under the criteria documented above) entry
292818334Speter	 in the class that is valid.  We use the `flag' field to indicate
292918334Speter	 choices that were invalid and iterate until we can't find a better
293018334Speter	 one that hasn't already been tried.  */
293118334Speter
293218334Speter      for (p = elt->first_same_value; p; p = p->next_same_value)
293318334Speter	p->flag = 0;
293418334Speter
293518334Speter      while (found_better)
293618334Speter	{
293790075Sobrien	  int best_addr_cost = address_cost (*loc, mode);
293818334Speter	  int best_rtx_cost = (elt->cost + 1) >> 1;
293990075Sobrien	  int exp_cost;
294090075Sobrien	  struct table_elt *best_elt = elt;
294118334Speter
294218334Speter	  found_better = 0;
294318334Speter	  for (p = elt->first_same_value; p; p = p->next_same_value)
294450397Sobrien	    if (! p->flag)
294518334Speter	      {
2946169689Skan		if ((REG_P (p->exp)
2947169689Skan		     || exp_equiv_p (p->exp, p->exp, 1, false))
294890075Sobrien		    && ((exp_cost = address_cost (p->exp, mode)) < best_addr_cost
294990075Sobrien			|| (exp_cost == best_addr_cost
295090075Sobrien			    && ((p->cost + 1) >> 1) > best_rtx_cost)))
295150397Sobrien		  {
295250397Sobrien		    found_better = 1;
295390075Sobrien		    best_addr_cost = exp_cost;
295450397Sobrien		    best_rtx_cost = (p->cost + 1) >> 1;
295550397Sobrien		    best_elt = p;
295650397Sobrien		  }
295718334Speter	      }
295818334Speter
295918334Speter	  if (found_better)
296018334Speter	    {
296118334Speter	      if (validate_change (insn, loc,
296218334Speter				   canon_reg (copy_rtx (best_elt->exp),
296318334Speter					      NULL_RTX), 0))
296418334Speter		return;
296518334Speter	      else
296618334Speter		best_elt->flag = 1;
296718334Speter	    }
296818334Speter	}
296918334Speter    }
297018334Speter
297118334Speter  /* If the address is a binary operation with the first operand a register
297218334Speter     and the second a constant, do the same as above, but looking for
297318334Speter     equivalences of the register.  Then try to simplify before checking for
297418334Speter     the best address to use.  This catches a few cases:  First is when we
297518334Speter     have REG+const and the register is another REG+const.  We can often merge
297618334Speter     the constants and eliminate one insn and one register.  It may also be
297718334Speter     that a machine has a cheap REG+REG+const.  Finally, this improves the
297818334Speter     code on the Alpha for unaligned byte stores.  */
297918334Speter
298018334Speter  if (flag_expensive_optimizations
2981169689Skan      && ARITHMETIC_P (*loc)
2982169689Skan      && REG_P (XEXP (*loc, 0)))
298318334Speter    {
2984132718Skan      rtx op1 = XEXP (*loc, 1);
298518334Speter
298618334Speter      do_not_record = 0;
298718334Speter      hash = HASH (XEXP (*loc, 0), Pmode);
298818334Speter      do_not_record = save_do_not_record;
298918334Speter      hash_arg_in_memory = save_hash_arg_in_memory;
299018334Speter
299118334Speter      elt = lookup (XEXP (*loc, 0), hash, Pmode);
299218334Speter      if (elt == 0)
299318334Speter	return;
299418334Speter
299518334Speter      /* We need to find the best (under the criteria documented above) entry
299618334Speter	 in the class that is valid.  We use the `flag' field to indicate
299718334Speter	 choices that were invalid and iterate until we can't find a better
299818334Speter	 one that hasn't already been tried.  */
299918334Speter
300018334Speter      for (p = elt->first_same_value; p; p = p->next_same_value)
300118334Speter	p->flag = 0;
300218334Speter
300318334Speter      while (found_better)
300418334Speter	{
300590075Sobrien	  int best_addr_cost = address_cost (*loc, mode);
300618334Speter	  int best_rtx_cost = (COST (*loc) + 1) >> 1;
300790075Sobrien	  struct table_elt *best_elt = elt;
300818334Speter	  rtx best_rtx = *loc;
300918334Speter	  int count;
301018334Speter
301118334Speter	  /* This is at worst case an O(n^2) algorithm, so limit our search
301218334Speter	     to the first 32 elements on the list.  This avoids trouble
301318334Speter	     compiling code with very long basic blocks that can easily
301490075Sobrien	     call simplify_gen_binary so many times that we run out of
301590075Sobrien	     memory.  */
301618334Speter
301718334Speter	  found_better = 0;
301818334Speter	  for (p = elt->first_same_value, count = 0;
301918334Speter	       p && count < 32;
302018334Speter	       p = p->next_same_value, count++)
302118334Speter	    if (! p->flag
3022169689Skan		&& (REG_P (p->exp)
3023169689Skan		    || (GET_CODE (p->exp) != EXPR_LIST
3024169689Skan			&& exp_equiv_p (p->exp, p->exp, 1, false))))
3025169689Skan
302618334Speter	      {
302790075Sobrien		rtx new = simplify_gen_binary (GET_CODE (*loc), Pmode,
3028132718Skan					       p->exp, op1);
302990075Sobrien		int new_cost;
3030169689Skan
3031169689Skan		/* Get the canonical version of the address so we can accept
3032169689Skan		   more.  */
3033169689Skan		new = canon_for_address (new);
3034169689Skan
303590075Sobrien		new_cost = address_cost (new, mode);
303618334Speter
303790075Sobrien		if (new_cost < best_addr_cost
303890075Sobrien		    || (new_cost == best_addr_cost
303990075Sobrien			&& (COST (new) + 1) >> 1 > best_rtx_cost))
304018334Speter		  {
304118334Speter		    found_better = 1;
304290075Sobrien		    best_addr_cost = new_cost;
304318334Speter		    best_rtx_cost = (COST (new) + 1) >> 1;
304418334Speter		    best_elt = p;
304518334Speter		    best_rtx = new;
304618334Speter		  }
304718334Speter	      }
304818334Speter
304918334Speter	  if (found_better)
305018334Speter	    {
305118334Speter	      if (validate_change (insn, loc,
305218334Speter				   canon_reg (copy_rtx (best_rtx),
305318334Speter					      NULL_RTX), 0))
305418334Speter		return;
305518334Speter	      else
305618334Speter		best_elt->flag = 1;
305718334Speter	    }
305818334Speter	}
305918334Speter    }
306018334Speter}
306118334Speter
306218334Speter/* Given an operation (CODE, *PARG1, *PARG2), where code is a comparison
306318334Speter   operation (EQ, NE, GT, etc.), follow it back through the hash table and
306418334Speter   what values are being compared.
306518334Speter
306618334Speter   *PARG1 and *PARG2 are updated to contain the rtx representing the values
306718334Speter   actually being compared.  For example, if *PARG1 was (cc0) and *PARG2
306818334Speter   was (const_int 0), *PARG1 and *PARG2 will be set to the objects that were
306918334Speter   compared to produce cc0.
307018334Speter
307118334Speter   The return value is the comparison operator and is either the code of
307218334Speter   A or the code corresponding to the inverse of the comparison.  */
307318334Speter
307418334Speterstatic enum rtx_code
3075132718Skanfind_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
3076132718Skan		      enum machine_mode *pmode1, enum machine_mode *pmode2)
307718334Speter{
307818334Speter  rtx arg1, arg2;
307918334Speter
308018334Speter  arg1 = *parg1, arg2 = *parg2;
308118334Speter
308218334Speter  /* If ARG2 is const0_rtx, see what ARG1 is equivalent to.  */
308318334Speter
308418334Speter  while (arg2 == CONST0_RTX (GET_MODE (arg1)))
308518334Speter    {
3086117395Skan      /* Set nonzero when we find something of interest.  */
308718334Speter      rtx x = 0;
308818334Speter      int reverse_code = 0;
308918334Speter      struct table_elt *p = 0;
309018334Speter
309118334Speter      /* If arg1 is a COMPARE, extract the comparison arguments from it.
309218334Speter	 On machines with CC0, this is the only case that can occur, since
309318334Speter	 fold_rtx will return the COMPARE or item being compared with zero
309418334Speter	 when given CC0.  */
309518334Speter
309618334Speter      if (GET_CODE (arg1) == COMPARE && arg2 == const0_rtx)
309718334Speter	x = arg1;
309818334Speter
309918334Speter      /* If ARG1 is a comparison operator and CODE is testing for
310018334Speter	 STORE_FLAG_VALUE, get the inner arguments.  */
310118334Speter
3102169689Skan      else if (COMPARISON_P (arg1))
310318334Speter	{
3104117395Skan#ifdef FLOAT_STORE_FLAG_VALUE
3105117395Skan	  REAL_VALUE_TYPE fsfv;
3106117395Skan#endif
3107117395Skan
310818334Speter	  if (code == NE
310918334Speter	      || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_INT
311018334Speter		  && code == LT && STORE_FLAG_VALUE == -1)
311118334Speter#ifdef FLOAT_STORE_FLAG_VALUE
3112169689Skan	      || (SCALAR_FLOAT_MODE_P (GET_MODE (arg1))
3113117395Skan		  && (fsfv = FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)),
3114117395Skan		      REAL_VALUE_NEGATIVE (fsfv)))
311518334Speter#endif
311618334Speter	      )
311718334Speter	    x = arg1;
311818334Speter	  else if (code == EQ
311918334Speter		   || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_INT
312018334Speter		       && code == GE && STORE_FLAG_VALUE == -1)
312118334Speter#ifdef FLOAT_STORE_FLAG_VALUE
3122169689Skan		   || (SCALAR_FLOAT_MODE_P (GET_MODE (arg1))
3123117395Skan		       && (fsfv = FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)),
3124117395Skan			   REAL_VALUE_NEGATIVE (fsfv)))
312518334Speter#endif
312618334Speter		   )
312718334Speter	    x = arg1, reverse_code = 1;
312818334Speter	}
312918334Speter
313018334Speter      /* ??? We could also check for
313118334Speter
313218334Speter	 (ne (and (eq (...) (const_int 1))) (const_int 0))
313318334Speter
313418334Speter	 and related forms, but let's wait until we see them occurring.  */
313518334Speter
313618334Speter      if (x == 0)
313718334Speter	/* Look up ARG1 in the hash table and see if it has an equivalence
313818334Speter	   that lets us see what is being compared.  */
3139169689Skan	p = lookup (arg1, SAFE_HASH (arg1, GET_MODE (arg1)), GET_MODE (arg1));
314090075Sobrien      if (p)
314190075Sobrien	{
314290075Sobrien	  p = p->first_same_value;
314318334Speter
314490075Sobrien	  /* If what we compare is already known to be constant, that is as
314590075Sobrien	     good as it gets.
314690075Sobrien	     We need to break the loop in this case, because otherwise we
314790075Sobrien	     can have an infinite loop when looking at a reg that is known
314890075Sobrien	     to be a constant which is the same as a comparison of a reg
314990075Sobrien	     against zero which appears later in the insn stream, which in
315090075Sobrien	     turn is constant and the same as the comparison of the first reg
315190075Sobrien	     against zero...  */
315290075Sobrien	  if (p->is_const)
315390075Sobrien	    break;
315490075Sobrien	}
315590075Sobrien
315618334Speter      for (; p; p = p->next_same_value)
315718334Speter	{
315818334Speter	  enum machine_mode inner_mode = GET_MODE (p->exp);
3159117395Skan#ifdef FLOAT_STORE_FLAG_VALUE
3160117395Skan	  REAL_VALUE_TYPE fsfv;
3161117395Skan#endif
316218334Speter
316318334Speter	  /* If the entry isn't valid, skip it.  */
3164169689Skan	  if (! exp_equiv_p (p->exp, p->exp, 1, false))
316518334Speter	    continue;
316618334Speter
316718334Speter	  if (GET_CODE (p->exp) == COMPARE
316818334Speter	      /* Another possibility is that this machine has a compare insn
316918334Speter		 that includes the comparison code.  In that case, ARG1 would
317018334Speter		 be equivalent to a comparison operation that would set ARG1 to
317118334Speter		 either STORE_FLAG_VALUE or zero.  If this is an NE operation,
317218334Speter		 ORIG_CODE is the actual comparison being done; if it is an EQ,
317318334Speter		 we must reverse ORIG_CODE.  On machine with a negative value
317418334Speter		 for STORE_FLAG_VALUE, also look at LT and GE operations.  */
317518334Speter	      || ((code == NE
317618334Speter		   || (code == LT
317718334Speter		       && GET_MODE_CLASS (inner_mode) == MODE_INT
317818334Speter		       && (GET_MODE_BITSIZE (inner_mode)
317918334Speter			   <= HOST_BITS_PER_WIDE_INT)
318018334Speter		       && (STORE_FLAG_VALUE
318118334Speter			   & ((HOST_WIDE_INT) 1
318218334Speter			      << (GET_MODE_BITSIZE (inner_mode) - 1))))
318318334Speter#ifdef FLOAT_STORE_FLAG_VALUE
318418334Speter		   || (code == LT
3185169689Skan		       && SCALAR_FLOAT_MODE_P (inner_mode)
3186117395Skan		       && (fsfv = FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)),
3187117395Skan			   REAL_VALUE_NEGATIVE (fsfv)))
318818334Speter#endif
318918334Speter		   )
3190169689Skan		  && COMPARISON_P (p->exp)))
319118334Speter	    {
319218334Speter	      x = p->exp;
319318334Speter	      break;
319418334Speter	    }
319518334Speter	  else if ((code == EQ
319618334Speter		    || (code == GE
319718334Speter			&& GET_MODE_CLASS (inner_mode) == MODE_INT
319818334Speter			&& (GET_MODE_BITSIZE (inner_mode)
319918334Speter			    <= HOST_BITS_PER_WIDE_INT)
320018334Speter			&& (STORE_FLAG_VALUE
320118334Speter			    & ((HOST_WIDE_INT) 1
320218334Speter			       << (GET_MODE_BITSIZE (inner_mode) - 1))))
320318334Speter#ifdef FLOAT_STORE_FLAG_VALUE
320418334Speter		    || (code == GE
3205169689Skan			&& SCALAR_FLOAT_MODE_P (inner_mode)
3206117395Skan			&& (fsfv = FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)),
3207117395Skan			    REAL_VALUE_NEGATIVE (fsfv)))
320818334Speter#endif
320918334Speter		    )
3210169689Skan		   && COMPARISON_P (p->exp))
321118334Speter	    {
321218334Speter	      reverse_code = 1;
321318334Speter	      x = p->exp;
321418334Speter	      break;
321518334Speter	    }
321618334Speter
3217132718Skan	  /* If this non-trapping address, e.g. fp + constant, the
3218132718Skan	     equivalent is a better operand since it may let us predict
3219132718Skan	     the value of the comparison.  */
3220132718Skan	  else if (!rtx_addr_can_trap_p (p->exp))
322118334Speter	    {
322218334Speter	      arg1 = p->exp;
322318334Speter	      continue;
322418334Speter	    }
322518334Speter	}
322618334Speter
322718334Speter      /* If we didn't find a useful equivalence for ARG1, we are done.
322818334Speter	 Otherwise, set up for the next iteration.  */
322918334Speter      if (x == 0)
323018334Speter	break;
323118334Speter
323290075Sobrien      /* If we need to reverse the comparison, make sure that that is
323390075Sobrien	 possible -- we can't necessarily infer the value of GE from LT
323490075Sobrien	 with floating-point operands.  */
323590075Sobrien      if (reverse_code)
323690075Sobrien	{
323790075Sobrien	  enum rtx_code reversed = reversed_comparison_code (x, NULL_RTX);
323890075Sobrien	  if (reversed == UNKNOWN)
323990075Sobrien	    break;
3240117395Skan	  else
3241117395Skan	    code = reversed;
324290075Sobrien	}
3243169689Skan      else if (COMPARISON_P (x))
324418334Speter	code = GET_CODE (x);
324590075Sobrien      arg1 = XEXP (x, 0), arg2 = XEXP (x, 1);
324618334Speter    }
324718334Speter
324818334Speter  /* Return our results.  Return the modes from before fold_rtx
324918334Speter     because fold_rtx might produce const_int, and then it's too late.  */
325018334Speter  *pmode1 = GET_MODE (arg1), *pmode2 = GET_MODE (arg2);
325118334Speter  *parg1 = fold_rtx (arg1, 0), *parg2 = fold_rtx (arg2, 0);
325218334Speter
325318334Speter  return code;
325418334Speter}
325518334Speter
3256169689Skan/* Fold SUBREG.  */
3257169689Skan
3258169689Skanstatic rtx
3259169689Skanfold_rtx_subreg (rtx x, rtx insn)
3260169689Skan{
3261169689Skan  enum machine_mode mode = GET_MODE (x);
3262169689Skan  rtx folded_arg0;
3263169689Skan  rtx const_arg0;
3264169689Skan  rtx new;
3265169689Skan
3266169689Skan  /* See if we previously assigned a constant value to this SUBREG.  */
3267169689Skan  if ((new = lookup_as_function (x, CONST_INT)) != 0
3268169689Skan      || (new = lookup_as_function (x, CONST_DOUBLE)) != 0)
3269169689Skan    return new;
3270169689Skan
3271169689Skan  /* If this is a paradoxical SUBREG, we have no idea what value the
3272169689Skan     extra bits would have.  However, if the operand is equivalent to
3273169689Skan     a SUBREG whose operand is the same as our mode, and all the modes
3274169689Skan     are within a word, we can just use the inner operand because
3275169689Skan     these SUBREGs just say how to treat the register.
3276169689Skan
3277169689Skan     Similarly if we find an integer constant.  */
3278169689Skan
3279169689Skan  if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
3280169689Skan    {
3281169689Skan      enum machine_mode imode = GET_MODE (SUBREG_REG (x));
3282169689Skan      struct table_elt *elt;
3283169689Skan
3284169689Skan      if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
3285169689Skan	  && GET_MODE_SIZE (imode) <= UNITS_PER_WORD
3286169689Skan	  && (elt = lookup (SUBREG_REG (x), HASH (SUBREG_REG (x), imode),
3287169689Skan			    imode)) != 0)
3288169689Skan	for (elt = elt->first_same_value; elt; elt = elt->next_same_value)
3289169689Skan	  {
3290169689Skan	    if (CONSTANT_P (elt->exp)
3291169689Skan		&& GET_MODE (elt->exp) == VOIDmode)
3292169689Skan	      return elt->exp;
3293169689Skan
3294169689Skan	    if (GET_CODE (elt->exp) == SUBREG
3295169689Skan		&& GET_MODE (SUBREG_REG (elt->exp)) == mode
3296169689Skan		&& exp_equiv_p (elt->exp, elt->exp, 1, false))
3297169689Skan	      return copy_rtx (SUBREG_REG (elt->exp));
3298169689Skan	  }
3299169689Skan
3300169689Skan      return x;
3301169689Skan    }
3302169689Skan
3303169689Skan  /* Fold SUBREG_REG.  If it changed, see if we can simplify the
3304169689Skan     SUBREG.  We might be able to if the SUBREG is extracting a single
3305169689Skan     word in an integral mode or extracting the low part.  */
3306169689Skan
3307169689Skan  folded_arg0 = fold_rtx (SUBREG_REG (x), insn);
3308169689Skan  const_arg0 = equiv_constant (folded_arg0);
3309169689Skan  if (const_arg0)
3310169689Skan    folded_arg0 = const_arg0;
3311169689Skan
3312169689Skan  if (folded_arg0 != SUBREG_REG (x))
3313169689Skan    {
3314169689Skan      new = simplify_subreg (mode, folded_arg0,
3315169689Skan			     GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
3316169689Skan      if (new)
3317169689Skan	return new;
3318169689Skan    }
3319169689Skan
3320169689Skan  if (REG_P (folded_arg0)
3321169689Skan      && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (folded_arg0)))
3322169689Skan    {
3323169689Skan      struct table_elt *elt;
3324169689Skan
3325169689Skan      elt = lookup (folded_arg0,
3326169689Skan		    HASH (folded_arg0, GET_MODE (folded_arg0)),
3327169689Skan		    GET_MODE (folded_arg0));
3328169689Skan
3329169689Skan      if (elt)
3330169689Skan	elt = elt->first_same_value;
3331169689Skan
3332169689Skan      if (subreg_lowpart_p (x))
3333169689Skan	/* If this is a narrowing SUBREG and our operand is a REG, see
3334169689Skan	   if we can find an equivalence for REG that is an arithmetic
3335169689Skan	   operation in a wider mode where both operands are
3336169689Skan	   paradoxical SUBREGs from objects of our result mode.  In
3337169689Skan	   that case, we couldn-t report an equivalent value for that
3338169689Skan	   operation, since we don't know what the extra bits will be.
3339169689Skan	   But we can find an equivalence for this SUBREG by folding
3340169689Skan	   that operation in the narrow mode.  This allows us to fold
3341169689Skan	   arithmetic in narrow modes when the machine only supports
3342169689Skan	   word-sized arithmetic.
3343169689Skan
3344169689Skan	   Also look for a case where we have a SUBREG whose operand
3345169689Skan	   is the same as our result.  If both modes are smaller than
3346169689Skan	   a word, we are simply interpreting a register in different
3347169689Skan	   modes and we can use the inner value.  */
3348169689Skan
3349169689Skan	for (; elt; elt = elt->next_same_value)
3350169689Skan	  {
3351169689Skan	    enum rtx_code eltcode = GET_CODE (elt->exp);
3352169689Skan
3353169689Skan	    /* Just check for unary and binary operations.  */
3354169689Skan	    if (UNARY_P (elt->exp)
3355169689Skan		&& eltcode != SIGN_EXTEND
3356169689Skan		&& eltcode != ZERO_EXTEND
3357169689Skan		&& GET_CODE (XEXP (elt->exp, 0)) == SUBREG
3358169689Skan		&& GET_MODE (SUBREG_REG (XEXP (elt->exp, 0))) == mode
3359169689Skan		&& (GET_MODE_CLASS (mode)
3360169689Skan		    == GET_MODE_CLASS (GET_MODE (XEXP (elt->exp, 0)))))
3361169689Skan	      {
3362169689Skan		rtx op0 = SUBREG_REG (XEXP (elt->exp, 0));
3363169689Skan
3364169689Skan		if (!REG_P (op0) && ! CONSTANT_P (op0))
3365169689Skan		  op0 = fold_rtx (op0, NULL_RTX);
3366169689Skan
3367169689Skan		op0 = equiv_constant (op0);
3368169689Skan		if (op0)
3369169689Skan		  new = simplify_unary_operation (GET_CODE (elt->exp), mode,
3370169689Skan						  op0, mode);
3371169689Skan	      }
3372169689Skan	    else if (ARITHMETIC_P (elt->exp)
3373169689Skan		     && eltcode != DIV && eltcode != MOD
3374169689Skan		     && eltcode != UDIV && eltcode != UMOD
3375169689Skan		     && eltcode != ASHIFTRT && eltcode != LSHIFTRT
3376169689Skan		     && eltcode != ROTATE && eltcode != ROTATERT
3377169689Skan		     && ((GET_CODE (XEXP (elt->exp, 0)) == SUBREG
3378169689Skan			  && (GET_MODE (SUBREG_REG (XEXP (elt->exp, 0)))
3379169689Skan			      == mode))
3380169689Skan			 || CONSTANT_P (XEXP (elt->exp, 0)))
3381169689Skan		     && ((GET_CODE (XEXP (elt->exp, 1)) == SUBREG
3382169689Skan			  && (GET_MODE (SUBREG_REG (XEXP (elt->exp, 1)))
3383169689Skan			      == mode))
3384169689Skan			 || CONSTANT_P (XEXP (elt->exp, 1))))
3385169689Skan	      {
3386169689Skan		rtx op0 = gen_lowpart_common (mode, XEXP (elt->exp, 0));
3387169689Skan		rtx op1 = gen_lowpart_common (mode, XEXP (elt->exp, 1));
3388169689Skan
3389169689Skan		if (op0 && !REG_P (op0) && ! CONSTANT_P (op0))
3390169689Skan		  op0 = fold_rtx (op0, NULL_RTX);
3391169689Skan
3392169689Skan		if (op0)
3393169689Skan		  op0 = equiv_constant (op0);
3394169689Skan
3395169689Skan		if (op1 && !REG_P (op1) && ! CONSTANT_P (op1))
3396169689Skan		  op1 = fold_rtx (op1, NULL_RTX);
3397169689Skan
3398169689Skan		if (op1)
3399169689Skan		  op1 = equiv_constant (op1);
3400169689Skan
3401169689Skan		/* If we are looking for the low SImode part of
3402169689Skan		   (ashift:DI c (const_int 32)), it doesn't work to
3403169689Skan		   compute that in SImode, because a 32-bit shift in
3404169689Skan		   SImode is unpredictable.  We know the value is
3405169689Skan		   0.  */
3406169689Skan		if (op0 && op1
3407169689Skan		    && GET_CODE (elt->exp) == ASHIFT
3408169689Skan		    && GET_CODE (op1) == CONST_INT
3409169689Skan		    && INTVAL (op1) >= GET_MODE_BITSIZE (mode))
3410169689Skan		  {
3411169689Skan		    if (INTVAL (op1)
3412169689Skan			< GET_MODE_BITSIZE (GET_MODE (elt->exp)))
3413169689Skan		      /* If the count fits in the inner mode's width,
3414169689Skan			 but exceeds the outer mode's width, the value
3415169689Skan			 will get truncated to 0 by the subreg.  */
3416169689Skan		      new = CONST0_RTX (mode);
3417169689Skan		    else
3418169689Skan		      /* If the count exceeds even the inner mode's width,
3419169689Skan			 don't fold this expression.  */
3420169689Skan		      new = 0;
3421169689Skan		  }
3422169689Skan		else if (op0 && op1)
3423169689Skan		  new = simplify_binary_operation (GET_CODE (elt->exp),
3424169689Skan						   mode, op0, op1);
3425169689Skan	      }
3426169689Skan
3427169689Skan	    else if (GET_CODE (elt->exp) == SUBREG
3428169689Skan		     && GET_MODE (SUBREG_REG (elt->exp)) == mode
3429169689Skan		     && (GET_MODE_SIZE (GET_MODE (folded_arg0))
3430169689Skan			 <= UNITS_PER_WORD)
3431169689Skan		     && exp_equiv_p (elt->exp, elt->exp, 1, false))
3432169689Skan	      new = copy_rtx (SUBREG_REG (elt->exp));
3433169689Skan
3434169689Skan	    if (new)
3435169689Skan	      return new;
3436169689Skan	  }
3437169689Skan      else
3438169689Skan	/* A SUBREG resulting from a zero extension may fold to zero
3439169689Skan	   if it extracts higher bits than the ZERO_EXTEND's source
3440169689Skan	   bits.  FIXME: if combine tried to, er, combine these
3441169689Skan	   instructions, this transformation may be moved to
3442169689Skan	   simplify_subreg.  */
3443169689Skan	for (; elt; elt = elt->next_same_value)
3444169689Skan	  {
3445169689Skan	    if (GET_CODE (elt->exp) == ZERO_EXTEND
3446169689Skan		&& subreg_lsb (x)
3447169689Skan		>= GET_MODE_BITSIZE (GET_MODE (XEXP (elt->exp, 0))))
3448169689Skan	      return CONST0_RTX (mode);
3449169689Skan	  }
3450169689Skan    }
3451169689Skan
3452169689Skan  return x;
3453169689Skan}
3454169689Skan
3455169689Skan/* Fold MEM.  Not to be called directly, see fold_rtx_mem instead.  */
3456169689Skan
3457169689Skanstatic rtx
3458169689Skanfold_rtx_mem_1 (rtx x, rtx insn)
3459169689Skan{
3460169689Skan  enum machine_mode mode = GET_MODE (x);
3461169689Skan  rtx new;
3462169689Skan
3463169689Skan  /* If we are not actually processing an insn, don't try to find the
3464169689Skan     best address.  Not only don't we care, but we could modify the
3465169689Skan     MEM in an invalid way since we have no insn to validate
3466169689Skan     against.  */
3467169689Skan  if (insn != 0)
3468169689Skan    find_best_addr (insn, &XEXP (x, 0), mode);
3469169689Skan
3470169689Skan  {
3471169689Skan    /* Even if we don't fold in the insn itself, we can safely do so
3472169689Skan       here, in hopes of getting a constant.  */
3473169689Skan    rtx addr = fold_rtx (XEXP (x, 0), NULL_RTX);
3474169689Skan    rtx base = 0;
3475169689Skan    HOST_WIDE_INT offset = 0;
3476169689Skan
3477169689Skan    if (REG_P (addr)
3478169689Skan	&& REGNO_QTY_VALID_P (REGNO (addr)))
3479169689Skan      {
3480169689Skan	int addr_q = REG_QTY (REGNO (addr));
3481169689Skan	struct qty_table_elem *addr_ent = &qty_table[addr_q];
3482169689Skan
3483169689Skan	if (GET_MODE (addr) == addr_ent->mode
3484169689Skan	    && addr_ent->const_rtx != NULL_RTX)
3485169689Skan	  addr = addr_ent->const_rtx;
3486169689Skan      }
3487169689Skan
3488169689Skan    /* Call target hook to avoid the effects of -fpic etc....  */
3489169689Skan    addr = targetm.delegitimize_address (addr);
3490169689Skan
3491169689Skan    /* If address is constant, split it into a base and integer
3492169689Skan       offset.  */
3493169689Skan    if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
3494169689Skan      base = addr;
3495169689Skan    else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
3496169689Skan	     && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
3497169689Skan      {
3498169689Skan	base = XEXP (XEXP (addr, 0), 0);
3499169689Skan	offset = INTVAL (XEXP (XEXP (addr, 0), 1));
3500169689Skan      }
3501169689Skan    else if (GET_CODE (addr) == LO_SUM
3502169689Skan	     && GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
3503169689Skan      base = XEXP (addr, 1);
3504169689Skan
3505169689Skan    /* If this is a constant pool reference, we can fold it into its
3506169689Skan       constant to allow better value tracking.  */
3507169689Skan    if (base && GET_CODE (base) == SYMBOL_REF
3508169689Skan	&& CONSTANT_POOL_ADDRESS_P (base))
3509169689Skan      {
3510169689Skan	rtx constant = get_pool_constant (base);
3511169689Skan	enum machine_mode const_mode = get_pool_mode (base);
3512169689Skan	rtx new;
3513169689Skan
3514169689Skan	if (CONSTANT_P (constant) && GET_CODE (constant) != CONST_INT)
3515169689Skan	  {
3516169689Skan	    constant_pool_entries_cost = COST (constant);
3517169689Skan	    constant_pool_entries_regcost = approx_reg_cost (constant);
3518169689Skan	  }
3519169689Skan
3520169689Skan	/* If we are loading the full constant, we have an
3521169689Skan	   equivalence.  */
3522169689Skan	if (offset == 0 && mode == const_mode)
3523169689Skan	  return constant;
3524169689Skan
3525169689Skan	/* If this actually isn't a constant (weird!), we can't do
3526169689Skan	   anything.  Otherwise, handle the two most common cases:
3527169689Skan	   extracting a word from a multi-word constant, and
3528169689Skan	   extracting the low-order bits.  Other cases don't seem
3529169689Skan	   common enough to worry about.  */
3530169689Skan	if (! CONSTANT_P (constant))
3531169689Skan	  return x;
3532169689Skan
3533169689Skan	if (GET_MODE_CLASS (mode) == MODE_INT
3534169689Skan	    && GET_MODE_SIZE (mode) == UNITS_PER_WORD
3535169689Skan	    && offset % UNITS_PER_WORD == 0
3536169689Skan	    && (new = operand_subword (constant,
3537169689Skan				       offset / UNITS_PER_WORD,
3538169689Skan				       0, const_mode)) != 0)
3539169689Skan	  return new;
3540169689Skan
3541169689Skan	if (((BYTES_BIG_ENDIAN
3542169689Skan	      && offset == GET_MODE_SIZE (GET_MODE (constant)) - 1)
3543169689Skan	     || (! BYTES_BIG_ENDIAN && offset == 0))
3544169689Skan	    && (new = gen_lowpart (mode, constant)) != 0)
3545169689Skan	  return new;
3546169689Skan      }
3547169689Skan
3548169689Skan    /* If this is a reference to a label at a known position in a jump
3549169689Skan       table, we also know its value.  */
3550169689Skan    if (base && GET_CODE (base) == LABEL_REF)
3551169689Skan      {
3552169689Skan	rtx label = XEXP (base, 0);
3553169689Skan	rtx table_insn = NEXT_INSN (label);
3554169689Skan
3555169689Skan	if (table_insn && JUMP_P (table_insn)
3556169689Skan	    && GET_CODE (PATTERN (table_insn)) == ADDR_VEC)
3557169689Skan	  {
3558169689Skan	    rtx table = PATTERN (table_insn);
3559169689Skan
3560169689Skan	    if (offset >= 0
3561169689Skan		&& (offset / GET_MODE_SIZE (GET_MODE (table))
3562169689Skan		    < XVECLEN (table, 0)))
3563169689Skan	      {
3564169689Skan		rtx label = XVECEXP
3565169689Skan		  (table, 0, offset / GET_MODE_SIZE (GET_MODE (table)));
3566169689Skan		rtx set;
3567169689Skan
3568169689Skan		/* If we have an insn that loads the label from the
3569169689Skan		   jumptable into a reg, we don't want to set the reg
3570169689Skan		   to the label, because this may cause a reference to
3571169689Skan		   the label to remain after the label is removed in
3572169689Skan		   some very obscure cases (PR middle-end/18628).  */
3573169689Skan		if (!insn)
3574169689Skan		  return label;
3575169689Skan
3576169689Skan		set = single_set (insn);
3577169689Skan
3578169689Skan		if (! set || SET_SRC (set) != x)
3579169689Skan		  return x;
3580169689Skan
3581169689Skan		/* If it's a jump, it's safe to reference the label.  */
3582169689Skan		if (SET_DEST (set) == pc_rtx)
3583169689Skan		  return label;
3584169689Skan
3585169689Skan		return x;
3586169689Skan	      }
3587169689Skan	  }
3588169689Skan	if (table_insn && JUMP_P (table_insn)
3589169689Skan	    && GET_CODE (PATTERN (table_insn)) == ADDR_DIFF_VEC)
3590169689Skan	  {
3591169689Skan	    rtx table = PATTERN (table_insn);
3592169689Skan
3593169689Skan	    if (offset >= 0
3594169689Skan		&& (offset / GET_MODE_SIZE (GET_MODE (table))
3595169689Skan		    < XVECLEN (table, 1)))
3596169689Skan	      {
3597169689Skan		offset /= GET_MODE_SIZE (GET_MODE (table));
3598169689Skan		new = gen_rtx_MINUS (Pmode, XVECEXP (table, 1, offset),
3599169689Skan				     XEXP (table, 0));
3600169689Skan
3601169689Skan		if (GET_MODE (table) != Pmode)
3602169689Skan		  new = gen_rtx_TRUNCATE (GET_MODE (table), new);
3603169689Skan
3604169689Skan		/* Indicate this is a constant.  This isn't a valid
3605169689Skan		   form of CONST, but it will only be used to fold the
3606169689Skan		   next insns and then discarded, so it should be
3607169689Skan		   safe.
3608169689Skan
3609169689Skan		   Note this expression must be explicitly discarded,
3610169689Skan		   by cse_insn, else it may end up in a REG_EQUAL note
3611169689Skan		   and "escape" to cause problems elsewhere.  */
3612169689Skan		return gen_rtx_CONST (GET_MODE (new), new);
3613169689Skan	      }
3614169689Skan	  }
3615169689Skan      }
3616169689Skan
3617169689Skan    return x;
3618169689Skan  }
3619169689Skan}
3620169689Skan
3621169689Skan/* Fold MEM.  */
3622169689Skan
3623169689Skanstatic rtx
3624169689Skanfold_rtx_mem (rtx x, rtx insn)
3625169689Skan{
3626169689Skan  /* To avoid infinite oscillations between fold_rtx and fold_rtx_mem,
3627169689Skan     refuse to allow recursion of the latter past n levels.  This can
3628169689Skan     happen because fold_rtx_mem will try to fold the address of the
3629169689Skan     memory reference it is passed, i.e. conceptually throwing away
3630169689Skan     the MEM and reinjecting the bare address into fold_rtx.  As a
3631169689Skan     result, patterns like
3632169689Skan
3633169689Skan       set (reg1)
3634169689Skan	   (plus (reg)
3635169689Skan		 (mem (plus (reg2) (const_int))))
3636169689Skan
3637169689Skan       set (reg2)
3638169689Skan	   (plus (reg)
3639169689Skan		 (mem (plus (reg1) (const_int))))
3640169689Skan
3641169689Skan     will defeat any "first-order" short-circuit put in either
3642169689Skan     function to prevent these infinite oscillations.
3643169689Skan
3644169689Skan     The heuristics for determining n is as follows: since each time
3645169689Skan     it is invoked fold_rtx_mem throws away a MEM, and since MEMs
3646169689Skan     are generically not nested, we assume that each invocation of
3647169689Skan     fold_rtx_mem corresponds to a new "top-level" operand, i.e.
3648169689Skan     the source or the destination of a SET.  So fold_rtx_mem is
3649169689Skan     bound to stop or cycle before n recursions, n being the number
3650169689Skan     of expressions recorded in the hash table.  We also leave some
3651169689Skan     play to account for the initial steps.  */
3652169689Skan
3653169689Skan  static unsigned int depth;
3654169689Skan  rtx ret;
3655169689Skan
3656169689Skan  if (depth > 3 + table_size)
3657169689Skan    return x;
3658169689Skan
3659169689Skan  depth++;
3660169689Skan  ret = fold_rtx_mem_1 (x, insn);
3661169689Skan  depth--;
3662169689Skan
3663169689Skan  return ret;
3664169689Skan}
3665169689Skan
366618334Speter/* If X is a nontrivial arithmetic operation on an argument
366718334Speter   for which a constant value can be determined, return
366818334Speter   the result of operating on that value, as a constant.
366918334Speter   Otherwise, return X, possibly with one or more operands
367018334Speter   modified by recursive calls to this function.
367118334Speter
367218334Speter   If X is a register whose contents are known, we do NOT
367318334Speter   return those contents here.  equiv_constant is called to
367418334Speter   perform that task.
367518334Speter
367618334Speter   INSN is the insn that we may be modifying.  If it is 0, make a copy
367718334Speter   of X before modifying it.  */
367818334Speter
367918334Speterstatic rtx
3680132718Skanfold_rtx (rtx x, rtx insn)
368118334Speter{
368290075Sobrien  enum rtx_code code;
368390075Sobrien  enum machine_mode mode;
368490075Sobrien  const char *fmt;
368590075Sobrien  int i;
368618334Speter  rtx new = 0;
368718334Speter  int copied = 0;
368818334Speter  int must_swap = 0;
368918334Speter
369018334Speter  /* Folded equivalents of first two operands of X.  */
369118334Speter  rtx folded_arg0;
369218334Speter  rtx folded_arg1;
369318334Speter
369418334Speter  /* Constant equivalents of first three operands of X;
369518334Speter     0 when no such equivalent is known.  */
369618334Speter  rtx const_arg0;
369718334Speter  rtx const_arg1;
369818334Speter  rtx const_arg2;
369918334Speter
370018334Speter  /* The mode of the first operand of X.  We need this for sign and zero
370118334Speter     extends.  */
370218334Speter  enum machine_mode mode_arg0;
370318334Speter
370418334Speter  if (x == 0)
370518334Speter    return x;
370618334Speter
370718334Speter  mode = GET_MODE (x);
370818334Speter  code = GET_CODE (x);
370918334Speter  switch (code)
371018334Speter    {
371118334Speter    case CONST:
371218334Speter    case CONST_INT:
371318334Speter    case CONST_DOUBLE:
371496263Sobrien    case CONST_VECTOR:
371518334Speter    case SYMBOL_REF:
371618334Speter    case LABEL_REF:
371718334Speter    case REG:
3718169689Skan    case PC:
371918334Speter      /* No use simplifying an EXPR_LIST
372018334Speter	 since they are used only for lists of args
372118334Speter	 in a function call's REG_EQUAL note.  */
372218334Speter    case EXPR_LIST:
372318334Speter      return x;
372418334Speter
372518334Speter#ifdef HAVE_cc0
372618334Speter    case CC0:
372718334Speter      return prev_insn_cc0;
372818334Speter#endif
372918334Speter
373018334Speter    case SUBREG:
3731169689Skan      return fold_rtx_subreg (x, insn);
373218334Speter
373318334Speter    case NOT:
373418334Speter    case NEG:
373518334Speter      /* If we have (NOT Y), see if Y is known to be (NOT Z).
373618334Speter	 If so, (NOT Y) simplifies to Z.  Similarly for NEG.  */
373718334Speter      new = lookup_as_function (XEXP (x, 0), code);
373818334Speter      if (new)
373918334Speter	return fold_rtx (copy_rtx (XEXP (new, 0)), insn);
374018334Speter      break;
374118334Speter
374218334Speter    case MEM:
3743169689Skan      return fold_rtx_mem (x, insn);
374418334Speter
374590075Sobrien#ifdef NO_FUNCTION_CSE
374690075Sobrien    case CALL:
374790075Sobrien      if (CONSTANT_P (XEXP (XEXP (x, 0), 0)))
374890075Sobrien	return x;
374990075Sobrien      break;
375090075Sobrien#endif
375190075Sobrien
375250397Sobrien    case ASM_OPERANDS:
3753169689Skan      if (insn)
3754169689Skan	{
3755169689Skan	  for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
3756169689Skan	    validate_change (insn, &ASM_OPERANDS_INPUT (x, i),
3757169689Skan			     fold_rtx (ASM_OPERANDS_INPUT (x, i), insn), 0);
3758169689Skan	}
375950397Sobrien      break;
376090075Sobrien
376150397Sobrien    default:
376250397Sobrien      break;
376318334Speter    }
376418334Speter
376518334Speter  const_arg0 = 0;
376618334Speter  const_arg1 = 0;
376718334Speter  const_arg2 = 0;
376818334Speter  mode_arg0 = VOIDmode;
376918334Speter
377018334Speter  /* Try folding our operands.
377118334Speter     Then see which ones have constant values known.  */
377218334Speter
377318334Speter  fmt = GET_RTX_FORMAT (code);
377418334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
377518334Speter    if (fmt[i] == 'e')
377618334Speter      {
377718334Speter	rtx arg = XEXP (x, i);
377818334Speter	rtx folded_arg = arg, const_arg = 0;
377918334Speter	enum machine_mode mode_arg = GET_MODE (arg);
378018334Speter	rtx cheap_arg, expensive_arg;
378118334Speter	rtx replacements[2];
378218334Speter	int j;
3783117395Skan	int old_cost = COST_IN (XEXP (x, i), code);
378418334Speter
378518334Speter	/* Most arguments are cheap, so handle them specially.  */
378618334Speter	switch (GET_CODE (arg))
378718334Speter	  {
378818334Speter	  case REG:
378918334Speter	    /* This is the same as calling equiv_constant; it is duplicated
379018334Speter	       here for speed.  */
379190075Sobrien	    if (REGNO_QTY_VALID_P (REGNO (arg)))
379290075Sobrien	      {
379390075Sobrien		int arg_q = REG_QTY (REGNO (arg));
379490075Sobrien		struct qty_table_elem *arg_ent = &qty_table[arg_q];
379590075Sobrien
379690075Sobrien		if (arg_ent->const_rtx != NULL_RTX
3797169689Skan		    && !REG_P (arg_ent->const_rtx)
379890075Sobrien		    && GET_CODE (arg_ent->const_rtx) != PLUS)
379990075Sobrien		  const_arg
3800169689Skan		    = gen_lowpart (GET_MODE (arg),
380190075Sobrien					       arg_ent->const_rtx);
380290075Sobrien	      }
380318334Speter	    break;
380418334Speter
380518334Speter	  case CONST:
380618334Speter	  case CONST_INT:
380718334Speter	  case SYMBOL_REF:
380818334Speter	  case LABEL_REF:
380918334Speter	  case CONST_DOUBLE:
381096263Sobrien	  case CONST_VECTOR:
381118334Speter	    const_arg = arg;
381218334Speter	    break;
381318334Speter
381418334Speter#ifdef HAVE_cc0
381518334Speter	  case CC0:
381618334Speter	    folded_arg = prev_insn_cc0;
381718334Speter	    mode_arg = prev_insn_cc0_mode;
381818334Speter	    const_arg = equiv_constant (folded_arg);
381918334Speter	    break;
382018334Speter#endif
382118334Speter
382218334Speter	  default:
382318334Speter	    folded_arg = fold_rtx (arg, insn);
382418334Speter	    const_arg = equiv_constant (folded_arg);
382518334Speter	  }
382618334Speter
382718334Speter	/* For the first three operands, see if the operand
382818334Speter	   is constant or equivalent to a constant.  */
382918334Speter	switch (i)
383018334Speter	  {
383118334Speter	  case 0:
383218334Speter	    folded_arg0 = folded_arg;
383318334Speter	    const_arg0 = const_arg;
383418334Speter	    mode_arg0 = mode_arg;
383518334Speter	    break;
383618334Speter	  case 1:
383718334Speter	    folded_arg1 = folded_arg;
383818334Speter	    const_arg1 = const_arg;
383918334Speter	    break;
384018334Speter	  case 2:
384118334Speter	    const_arg2 = const_arg;
384218334Speter	    break;
384318334Speter	  }
384418334Speter
384518334Speter	/* Pick the least expensive of the folded argument and an
384618334Speter	   equivalent constant argument.  */
384718334Speter	if (const_arg == 0 || const_arg == folded_arg
384890075Sobrien	    || COST_IN (const_arg, code) > COST_IN (folded_arg, code))
384918334Speter	  cheap_arg = folded_arg, expensive_arg = const_arg;
385018334Speter	else
385118334Speter	  cheap_arg = const_arg, expensive_arg = folded_arg;
385218334Speter
385318334Speter	/* Try to replace the operand with the cheapest of the two
385418334Speter	   possibilities.  If it doesn't work and this is either of the first
385518334Speter	   two operands of a commutative operation, try swapping them.
385618334Speter	   If THAT fails, try the more expensive, provided it is cheaper
385718334Speter	   than what is already there.  */
385818334Speter
385918334Speter	if (cheap_arg == XEXP (x, i))
386018334Speter	  continue;
386118334Speter
386218334Speter	if (insn == 0 && ! copied)
386318334Speter	  {
386418334Speter	    x = copy_rtx (x);
386518334Speter	    copied = 1;
386618334Speter	  }
386718334Speter
386890075Sobrien	/* Order the replacements from cheapest to most expensive.  */
386990075Sobrien	replacements[0] = cheap_arg;
387090075Sobrien	replacements[1] = expensive_arg;
387190075Sobrien
3872117395Skan	for (j = 0; j < 2 && replacements[j]; j++)
387318334Speter	  {
387490075Sobrien	    int new_cost = COST_IN (replacements[j], code);
387590075Sobrien
387690075Sobrien	    /* Stop if what existed before was cheaper.  Prefer constants
387790075Sobrien	       in the case of a tie.  */
387890075Sobrien	    if (new_cost > old_cost
387990075Sobrien		|| (new_cost == old_cost && CONSTANT_P (XEXP (x, i))))
388090075Sobrien	      break;
388190075Sobrien
3882132718Skan	    /* It's not safe to substitute the operand of a conversion
3883132718Skan	       operator with a constant, as the conversion's identity
3884169689Skan	       depends upon the mode of its operand.  This optimization
3885132718Skan	       is handled by the call to simplify_unary_operation.  */
3886169689Skan	    if (GET_RTX_CLASS (code) == RTX_UNARY
3887132718Skan		&& GET_MODE (replacements[j]) != mode_arg0
3888132718Skan		&& (code == ZERO_EXTEND
3889132718Skan		    || code == SIGN_EXTEND
3890132718Skan		    || code == TRUNCATE
3891132718Skan		    || code == FLOAT_TRUNCATE
3892132718Skan		    || code == FLOAT_EXTEND
3893132718Skan		    || code == FLOAT
3894132718Skan		    || code == FIX
3895132718Skan		    || code == UNSIGNED_FLOAT
3896132718Skan		    || code == UNSIGNED_FIX))
3897132718Skan	      continue;
3898132718Skan
389918334Speter	    if (validate_change (insn, &XEXP (x, i), replacements[j], 0))
390018334Speter	      break;
390118334Speter
3902169689Skan	    if (GET_RTX_CLASS (code) == RTX_COMM_COMPARE
3903169689Skan		|| GET_RTX_CLASS (code) == RTX_COMM_ARITH)
390418334Speter	      {
390518334Speter		validate_change (insn, &XEXP (x, i), XEXP (x, 1 - i), 1);
390618334Speter		validate_change (insn, &XEXP (x, 1 - i), replacements[j], 1);
390718334Speter
390818334Speter		if (apply_change_group ())
390918334Speter		  {
391018334Speter		    /* Swap them back to be invalid so that this loop can
391118334Speter		       continue and flag them to be swapped back later.  */
391218334Speter		    rtx tem;
391318334Speter
391418334Speter		    tem = XEXP (x, 0); XEXP (x, 0) = XEXP (x, 1);
391518334Speter				       XEXP (x, 1) = tem;
391618334Speter		    must_swap = 1;
391718334Speter		    break;
391818334Speter		  }
391918334Speter	      }
392018334Speter	  }
392118334Speter      }
392218334Speter
392350397Sobrien    else
392450397Sobrien      {
392550397Sobrien	if (fmt[i] == 'E')
392650397Sobrien	  /* Don't try to fold inside of a vector of expressions.
392750397Sobrien	     Doing nothing is harmless.  */
392890075Sobrien	  {;}
392950397Sobrien      }
393018334Speter
393118334Speter  /* If a commutative operation, place a constant integer as the second
393218334Speter     operand unless the first operand is also a constant integer.  Otherwise,
393318334Speter     place any constant second unless the first operand is also a constant.  */
393418334Speter
3935169689Skan  if (COMMUTATIVE_P (x))
393618334Speter    {
3937132718Skan      if (must_swap
3938132718Skan	  || swap_commutative_operands_p (const_arg0 ? const_arg0
3939132718Skan						     : XEXP (x, 0),
3940132718Skan					  const_arg1 ? const_arg1
3941132718Skan						     : XEXP (x, 1)))
394218334Speter	{
394390075Sobrien	  rtx tem = XEXP (x, 0);
394418334Speter
394518334Speter	  if (insn == 0 && ! copied)
394618334Speter	    {
394718334Speter	      x = copy_rtx (x);
394818334Speter	      copied = 1;
394918334Speter	    }
395018334Speter
395118334Speter	  validate_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
395218334Speter	  validate_change (insn, &XEXP (x, 1), tem, 1);
395318334Speter	  if (apply_change_group ())
395418334Speter	    {
395518334Speter	      tem = const_arg0, const_arg0 = const_arg1, const_arg1 = tem;
395618334Speter	      tem = folded_arg0, folded_arg0 = folded_arg1, folded_arg1 = tem;
395718334Speter	    }
395818334Speter	}
395918334Speter    }
396018334Speter
396118334Speter  /* If X is an arithmetic operation, see if we can simplify it.  */
396218334Speter
396318334Speter  switch (GET_RTX_CLASS (code))
396418334Speter    {
3965169689Skan    case RTX_UNARY:
396618334Speter      {
396718334Speter	int is_const = 0;
396818334Speter
396918334Speter	/* We can't simplify extension ops unless we know the
397018334Speter	   original mode.  */
397118334Speter	if ((code == ZERO_EXTEND || code == SIGN_EXTEND)
397218334Speter	    && mode_arg0 == VOIDmode)
397318334Speter	  break;
397418334Speter
397518334Speter	/* If we had a CONST, strip it off and put it back later if we
397618334Speter	   fold.  */
397718334Speter	if (const_arg0 != 0 && GET_CODE (const_arg0) == CONST)
397818334Speter	  is_const = 1, const_arg0 = XEXP (const_arg0, 0);
397918334Speter
398018334Speter	new = simplify_unary_operation (code, mode,
398118334Speter					const_arg0 ? const_arg0 : folded_arg0,
398218334Speter					mode_arg0);
3983169689Skan	/* NEG of PLUS could be converted into MINUS, but that causes
3984169689Skan	   expressions of the form
3985169689Skan	   (CONST (MINUS (CONST_INT) (SYMBOL_REF)))
3986169689Skan	   which many ports mistakenly treat as LEGITIMATE_CONSTANT_P.
3987169689Skan	   FIXME: those ports should be fixed.  */
3988169689Skan	if (new != 0 && is_const
3989169689Skan	    && GET_CODE (new) == PLUS
3990169689Skan	    && (GET_CODE (XEXP (new, 0)) == SYMBOL_REF
3991169689Skan		|| GET_CODE (XEXP (new, 0)) == LABEL_REF)
3992169689Skan	    && GET_CODE (XEXP (new, 1)) == CONST_INT)
399350397Sobrien	  new = gen_rtx_CONST (mode, new);
399418334Speter      }
399518334Speter      break;
399690075Sobrien
3997169689Skan    case RTX_COMPARE:
3998169689Skan    case RTX_COMM_COMPARE:
399918334Speter      /* See what items are actually being compared and set FOLDED_ARG[01]
400018334Speter	 to those values and CODE to the actual comparison code.  If any are
400118334Speter	 constant, set CONST_ARG0 and CONST_ARG1 appropriately.  We needn't
400218334Speter	 do anything if both operands are already known to be constant.  */
400318334Speter
4004169689Skan      /* ??? Vector mode comparisons are not supported yet.  */
4005169689Skan      if (VECTOR_MODE_P (mode))
4006169689Skan	break;
4007169689Skan
400818334Speter      if (const_arg0 == 0 || const_arg1 == 0)
400918334Speter	{
401018334Speter	  struct table_elt *p0, *p1;
401190075Sobrien	  rtx true_rtx = const_true_rtx, false_rtx = const0_rtx;
401218334Speter	  enum machine_mode mode_arg1;
401318334Speter
401418334Speter#ifdef FLOAT_STORE_FLAG_VALUE
4015169689Skan	  if (SCALAR_FLOAT_MODE_P (mode))
401618334Speter	    {
401790075Sobrien	      true_rtx = (CONST_DOUBLE_FROM_REAL_VALUE
4018117395Skan			  (FLOAT_STORE_FLAG_VALUE (mode), mode));
401990075Sobrien	      false_rtx = CONST0_RTX (mode);
402018334Speter	    }
402118334Speter#endif
402218334Speter
402318334Speter	  code = find_comparison_args (code, &folded_arg0, &folded_arg1,
402418334Speter				       &mode_arg0, &mode_arg1);
402518334Speter
402618334Speter	  /* If the mode is VOIDmode or a MODE_CC mode, we don't know
402718334Speter	     what kinds of things are being compared, so we can't do
402818334Speter	     anything with this comparison.  */
402918334Speter
403018334Speter	  if (mode_arg0 == VOIDmode || GET_MODE_CLASS (mode_arg0) == MODE_CC)
403118334Speter	    break;
403218334Speter
4033169689Skan	  const_arg0 = equiv_constant (folded_arg0);
4034169689Skan	  const_arg1 = equiv_constant (folded_arg1);
4035169689Skan
403650397Sobrien	  /* If we do not now have two constants being compared, see
403750397Sobrien	     if we can nevertheless deduce some things about the
403850397Sobrien	     comparison.  */
403918334Speter	  if (const_arg0 == 0 || const_arg1 == 0)
404018334Speter	    {
4041169689Skan	      if (const_arg1 != NULL)
4042169689Skan		{
4043169689Skan		  rtx cheapest_simplification;
4044169689Skan		  int cheapest_cost;
4045169689Skan		  rtx simp_result;
4046169689Skan		  struct table_elt *p;
4047169689Skan
4048169689Skan		  /* See if we can find an equivalent of folded_arg0
4049169689Skan		     that gets us a cheaper expression, possibly a
4050169689Skan		     constant through simplifications.  */
4051169689Skan		  p = lookup (folded_arg0, SAFE_HASH (folded_arg0, mode_arg0),
4052169689Skan			      mode_arg0);
4053169689Skan
4054169689Skan		  if (p != NULL)
4055169689Skan		    {
4056169689Skan		      cheapest_simplification = x;
4057169689Skan		      cheapest_cost = COST (x);
4058169689Skan
4059169689Skan		      for (p = p->first_same_value; p != NULL; p = p->next_same_value)
4060169689Skan			{
4061169689Skan			  int cost;
4062169689Skan
4063169689Skan			  /* If the entry isn't valid, skip it.  */
4064169689Skan			  if (! exp_equiv_p (p->exp, p->exp, 1, false))
4065169689Skan			    continue;
4066169689Skan
4067169689Skan			  /* Try to simplify using this equivalence.  */
4068169689Skan			  simp_result
4069169689Skan			    = simplify_relational_operation (code, mode,
4070169689Skan							     mode_arg0,
4071169689Skan							     p->exp,
4072169689Skan							     const_arg1);
4073169689Skan
4074169689Skan			  if (simp_result == NULL)
4075169689Skan			    continue;
4076169689Skan
4077169689Skan			  cost = COST (simp_result);
4078169689Skan			  if (cost < cheapest_cost)
4079169689Skan			    {
4080169689Skan			      cheapest_cost = cost;
4081169689Skan			      cheapest_simplification = simp_result;
4082169689Skan			    }
4083169689Skan			}
4084169689Skan
4085169689Skan		      /* If we have a cheaper expression now, use that
4086169689Skan			 and try folding it further, from the top.  */
4087169689Skan		      if (cheapest_simplification != x)
4088169689Skan			return fold_rtx (cheapest_simplification, insn);
4089169689Skan		    }
4090169689Skan		}
4091169689Skan
4092132718Skan	      /* Some addresses are known to be nonzero.  We don't know
4093132718Skan		 their sign, but equality comparisons are known.  */
409418334Speter	      if (const_arg1 == const0_rtx
4095132718Skan		  && nonzero_address_p (folded_arg0))
409618334Speter		{
409718334Speter		  if (code == EQ)
409890075Sobrien		    return false_rtx;
409918334Speter		  else if (code == NE)
410090075Sobrien		    return true_rtx;
410118334Speter		}
410218334Speter
410390075Sobrien	      /* See if the two operands are the same.  */
410418334Speter
410590075Sobrien	      if (folded_arg0 == folded_arg1
4106169689Skan		  || (REG_P (folded_arg0)
4107169689Skan		      && REG_P (folded_arg1)
410890075Sobrien		      && (REG_QTY (REGNO (folded_arg0))
410990075Sobrien			  == REG_QTY (REGNO (folded_arg1))))
411090075Sobrien		  || ((p0 = lookup (folded_arg0,
4111169689Skan				    SAFE_HASH (folded_arg0, mode_arg0),
4112169689Skan				    mode_arg0))
411390075Sobrien		      && (p1 = lookup (folded_arg1,
4114169689Skan				       SAFE_HASH (folded_arg1, mode_arg0),
4115169689Skan				       mode_arg0))
411690075Sobrien		      && p0->first_same_value == p1->first_same_value))
411790075Sobrien		{
4118117395Skan		  /* Sadly two equal NaNs are not equivalent.  */
4119117395Skan		  if (!HONOR_NANS (mode_arg0))
4120117395Skan		    return ((code == EQ || code == LE || code == GE
4121117395Skan			     || code == LEU || code == GEU || code == UNEQ
4122117395Skan			     || code == UNLE || code == UNGE
4123117395Skan			     || code == ORDERED)
4124117395Skan			    ? true_rtx : false_rtx);
4125117395Skan		  /* Take care for the FP compares we can resolve.  */
4126117395Skan		  if (code == UNEQ || code == UNLE || code == UNGE)
4127117395Skan		    return true_rtx;
4128117395Skan		  if (code == LTGT || code == LT || code == GT)
4129117395Skan		    return false_rtx;
413090075Sobrien		}
413118334Speter
413218334Speter	      /* If FOLDED_ARG0 is a register, see if the comparison we are
413318334Speter		 doing now is either the same as we did before or the reverse
413418334Speter		 (we only check the reverse if not floating-point).  */
4135169689Skan	      else if (REG_P (folded_arg0))
413618334Speter		{
413752284Sobrien		  int qty = REG_QTY (REGNO (folded_arg0));
413818334Speter
413990075Sobrien		  if (REGNO_QTY_VALID_P (REGNO (folded_arg0)))
414090075Sobrien		    {
414190075Sobrien		      struct qty_table_elem *ent = &qty_table[qty];
414290075Sobrien
414390075Sobrien		      if ((comparison_dominates_p (ent->comparison_code, code)
414490075Sobrien			   || (! FLOAT_MODE_P (mode_arg0)
414590075Sobrien			       && comparison_dominates_p (ent->comparison_code,
414690075Sobrien						          reverse_condition (code))))
414790075Sobrien			  && (rtx_equal_p (ent->comparison_const, folded_arg1)
414890075Sobrien			      || (const_arg1
414990075Sobrien				  && rtx_equal_p (ent->comparison_const,
415090075Sobrien						  const_arg1))
4151169689Skan			      || (REG_P (folded_arg1)
415290075Sobrien				  && (REG_QTY (REGNO (folded_arg1)) == ent->comparison_qty))))
415390075Sobrien			return (comparison_dominates_p (ent->comparison_code, code)
415490075Sobrien				? true_rtx : false_rtx);
415590075Sobrien		    }
415618334Speter		}
415718334Speter	    }
415818334Speter	}
415918334Speter
416018334Speter      /* If we are comparing against zero, see if the first operand is
416118334Speter	 equivalent to an IOR with a constant.  If so, we may be able to
416218334Speter	 determine the result of this comparison.  */
416318334Speter
416418334Speter      if (const_arg1 == const0_rtx)
416518334Speter	{
416618334Speter	  rtx y = lookup_as_function (folded_arg0, IOR);
416718334Speter	  rtx inner_const;
416818334Speter
416918334Speter	  if (y != 0
417018334Speter	      && (inner_const = equiv_constant (XEXP (y, 1))) != 0
417118334Speter	      && GET_CODE (inner_const) == CONST_INT
417218334Speter	      && INTVAL (inner_const) != 0)
417318334Speter	    {
417418334Speter	      int sign_bitnum = GET_MODE_BITSIZE (mode_arg0) - 1;
417518334Speter	      int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
417618334Speter			      && (INTVAL (inner_const)
417718334Speter				  & ((HOST_WIDE_INT) 1 << sign_bitnum)));
417890075Sobrien	      rtx true_rtx = const_true_rtx, false_rtx = const0_rtx;
417918334Speter
418018334Speter#ifdef FLOAT_STORE_FLAG_VALUE
4181169689Skan	      if (SCALAR_FLOAT_MODE_P (mode))
418218334Speter		{
418390075Sobrien		  true_rtx = (CONST_DOUBLE_FROM_REAL_VALUE
418490075Sobrien			  (FLOAT_STORE_FLAG_VALUE (mode), mode));
418590075Sobrien		  false_rtx = CONST0_RTX (mode);
418618334Speter		}
418718334Speter#endif
418818334Speter
418918334Speter	      switch (code)
419018334Speter		{
419118334Speter		case EQ:
419290075Sobrien		  return false_rtx;
419318334Speter		case NE:
419490075Sobrien		  return true_rtx;
419518334Speter		case LT:  case LE:
419618334Speter		  if (has_sign)
419790075Sobrien		    return true_rtx;
419818334Speter		  break;
419918334Speter		case GT:  case GE:
420018334Speter		  if (has_sign)
420190075Sobrien		    return false_rtx;
420218334Speter		  break;
420350397Sobrien		default:
420450397Sobrien		  break;
420518334Speter		}
420618334Speter	    }
420718334Speter	}
420818334Speter
4209169689Skan      {
4210169689Skan	rtx op0 = const_arg0 ? const_arg0 : folded_arg0;
4211169689Skan	rtx op1 = const_arg1 ? const_arg1 : folded_arg1;
4212169689Skan        new = simplify_relational_operation (code, mode, mode_arg0, op0, op1);
4213169689Skan      }
421418334Speter      break;
421518334Speter
4216169689Skan    case RTX_BIN_ARITH:
4217169689Skan    case RTX_COMM_ARITH:
421818334Speter      switch (code)
421918334Speter	{
422018334Speter	case PLUS:
422118334Speter	  /* If the second operand is a LABEL_REF, see if the first is a MINUS
422218334Speter	     with that LABEL_REF as its second operand.  If so, the result is
422318334Speter	     the first operand of that MINUS.  This handles switches with an
422418334Speter	     ADDR_DIFF_VEC table.  */
422518334Speter	  if (const_arg1 && GET_CODE (const_arg1) == LABEL_REF)
422618334Speter	    {
422718334Speter	      rtx y
422818334Speter		= GET_CODE (folded_arg0) == MINUS ? folded_arg0
422990075Sobrien		: lookup_as_function (folded_arg0, MINUS);
423018334Speter
423118334Speter	      if (y != 0 && GET_CODE (XEXP (y, 1)) == LABEL_REF
423218334Speter		  && XEXP (XEXP (y, 1), 0) == XEXP (const_arg1, 0))
423318334Speter		return XEXP (y, 0);
423418334Speter
423518334Speter	      /* Now try for a CONST of a MINUS like the above.  */
423618334Speter	      if ((y = (GET_CODE (folded_arg0) == CONST ? folded_arg0
423718334Speter			: lookup_as_function (folded_arg0, CONST))) != 0
423818334Speter		  && GET_CODE (XEXP (y, 0)) == MINUS
423918334Speter		  && GET_CODE (XEXP (XEXP (y, 0), 1)) == LABEL_REF
424090075Sobrien		  && XEXP (XEXP (XEXP (y, 0), 1), 0) == XEXP (const_arg1, 0))
424118334Speter		return XEXP (XEXP (y, 0), 0);
424218334Speter	    }
424318334Speter
424418334Speter	  /* Likewise if the operands are in the other order.  */
424518334Speter	  if (const_arg0 && GET_CODE (const_arg0) == LABEL_REF)
424618334Speter	    {
424718334Speter	      rtx y
424818334Speter		= GET_CODE (folded_arg1) == MINUS ? folded_arg1
424990075Sobrien		: lookup_as_function (folded_arg1, MINUS);
425018334Speter
425118334Speter	      if (y != 0 && GET_CODE (XEXP (y, 1)) == LABEL_REF
425218334Speter		  && XEXP (XEXP (y, 1), 0) == XEXP (const_arg0, 0))
425318334Speter		return XEXP (y, 0);
425418334Speter
425518334Speter	      /* Now try for a CONST of a MINUS like the above.  */
425618334Speter	      if ((y = (GET_CODE (folded_arg1) == CONST ? folded_arg1
425718334Speter			: lookup_as_function (folded_arg1, CONST))) != 0
425818334Speter		  && GET_CODE (XEXP (y, 0)) == MINUS
425918334Speter		  && GET_CODE (XEXP (XEXP (y, 0), 1)) == LABEL_REF
426090075Sobrien		  && XEXP (XEXP (XEXP (y, 0), 1), 0) == XEXP (const_arg0, 0))
426118334Speter		return XEXP (XEXP (y, 0), 0);
426218334Speter	    }
426318334Speter
426418334Speter	  /* If second operand is a register equivalent to a negative
426518334Speter	     CONST_INT, see if we can find a register equivalent to the
426618334Speter	     positive constant.  Make a MINUS if so.  Don't do this for
426750397Sobrien	     a non-negative constant since we might then alternate between
426890075Sobrien	     choosing positive and negative constants.  Having the positive
426950397Sobrien	     constant previously-used is the more common case.  Be sure
427050397Sobrien	     the resulting constant is non-negative; if const_arg1 were
427150397Sobrien	     the smallest negative number this would overflow: depending
427250397Sobrien	     on the mode, this would either just be the same value (and
427350397Sobrien	     hence not save anything) or be incorrect.  */
427450397Sobrien	  if (const_arg1 != 0 && GET_CODE (const_arg1) == CONST_INT
427550397Sobrien	      && INTVAL (const_arg1) < 0
427652750Sobrien	      /* This used to test
427752750Sobrien
427890075Sobrien	         -INTVAL (const_arg1) >= 0
427952750Sobrien
428052750Sobrien		 But The Sun V5.0 compilers mis-compiled that test.  So
428152750Sobrien		 instead we test for the problematic value in a more direct
428252750Sobrien		 manner and hope the Sun compilers get it correct.  */
428352750Sobrien	      && INTVAL (const_arg1) !=
428452750Sobrien	        ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1))
4285169689Skan	      && REG_P (folded_arg1))
428618334Speter	    {
428790075Sobrien	      rtx new_const = GEN_INT (-INTVAL (const_arg1));
428818334Speter	      struct table_elt *p
4289169689Skan		= lookup (new_const, SAFE_HASH (new_const, mode), mode);
429018334Speter
429118334Speter	      if (p)
429218334Speter		for (p = p->first_same_value; p; p = p->next_same_value)
4293169689Skan		  if (REG_P (p->exp))
429490075Sobrien		    return simplify_gen_binary (MINUS, mode, folded_arg0,
429590075Sobrien						canon_reg (p->exp, NULL_RTX));
429618334Speter	    }
429718334Speter	  goto from_plus;
429818334Speter
429918334Speter	case MINUS:
430018334Speter	  /* If we have (MINUS Y C), see if Y is known to be (PLUS Z C2).
430118334Speter	     If so, produce (PLUS Z C2-C).  */
430218334Speter	  if (const_arg1 != 0 && GET_CODE (const_arg1) == CONST_INT)
430318334Speter	    {
430418334Speter	      rtx y = lookup_as_function (XEXP (x, 0), PLUS);
430518334Speter	      if (y && GET_CODE (XEXP (y, 1)) == CONST_INT)
430618334Speter		return fold_rtx (plus_constant (copy_rtx (y),
430718334Speter						-INTVAL (const_arg1)),
430818334Speter				 NULL_RTX);
430918334Speter	    }
431018334Speter
431190075Sobrien	  /* Fall through.  */
431218334Speter
431318334Speter	from_plus:
431418334Speter	case SMIN:    case SMAX:      case UMIN:    case UMAX:
431518334Speter	case IOR:     case AND:       case XOR:
4316117395Skan	case MULT:
431718334Speter	case ASHIFT:  case LSHIFTRT:  case ASHIFTRT:
431818334Speter	  /* If we have (<op> <reg> <const_int>) for an associative OP and REG
431918334Speter	     is known to be of similar form, we may be able to replace the
432018334Speter	     operation with a combined operation.  This may eliminate the
432118334Speter	     intermediate operation if every use is simplified in this way.
432218334Speter	     Note that the similar optimization done by combine.c only works
432318334Speter	     if the intermediate operation's result has only one reference.  */
432418334Speter
4325169689Skan	  if (REG_P (folded_arg0)
432618334Speter	      && const_arg1 && GET_CODE (const_arg1) == CONST_INT)
432718334Speter	    {
432818334Speter	      int is_shift
432918334Speter		= (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT);
4330169689Skan	      rtx y, inner_const, new_const;
433118334Speter	      enum rtx_code associate_code;
433218334Speter
4333169689Skan	      if (is_shift
4334169689Skan		  && (INTVAL (const_arg1) >= GET_MODE_BITSIZE (mode)
4335169689Skan		      || INTVAL (const_arg1) < 0))
4336169689Skan		{
4337169689Skan		  if (SHIFT_COUNT_TRUNCATED)
4338169689Skan		    const_arg1 = GEN_INT (INTVAL (const_arg1)
4339169689Skan					  & (GET_MODE_BITSIZE (mode) - 1));
4340169689Skan		  else
4341169689Skan		    break;
4342169689Skan		}
4343169689Skan
4344169689Skan	      y = lookup_as_function (folded_arg0, code);
4345169689Skan	      if (y == 0)
434618334Speter		break;
434718334Speter
4348169689Skan	      /* If we have compiled a statement like
4349169689Skan		 "if (x == (x & mask1))", and now are looking at
4350169689Skan		 "x & mask2", we will have a case where the first operand
4351169689Skan		 of Y is the same as our first operand.  Unless we detect
4352169689Skan		 this case, an infinite loop will result.  */
4353169689Skan	      if (XEXP (y, 0) == folded_arg0)
4354169689Skan		break;
4355169689Skan
4356169689Skan	      inner_const = equiv_constant (fold_rtx (XEXP (y, 1), 0));
4357169689Skan	      if (!inner_const || GET_CODE (inner_const) != CONST_INT)
4358169689Skan		break;
4359169689Skan
436018334Speter	      /* Don't associate these operations if they are a PLUS with the
436118334Speter		 same constant and it is a power of two.  These might be doable
436218334Speter		 with a pre- or post-increment.  Similarly for two subtracts of
436318334Speter		 identical powers of two with post decrement.  */
436418334Speter
4365132718Skan	      if (code == PLUS && const_arg1 == inner_const
436652284Sobrien		  && ((HAVE_PRE_INCREMENT
436752284Sobrien			  && exact_log2 (INTVAL (const_arg1)) >= 0)
436852284Sobrien		      || (HAVE_POST_INCREMENT
436952284Sobrien			  && exact_log2 (INTVAL (const_arg1)) >= 0)
437052284Sobrien		      || (HAVE_PRE_DECREMENT
437152284Sobrien			  && exact_log2 (- INTVAL (const_arg1)) >= 0)
437252284Sobrien		      || (HAVE_POST_DECREMENT
437352284Sobrien			  && exact_log2 (- INTVAL (const_arg1)) >= 0)))
437418334Speter		break;
437518334Speter
4376169689Skan	      if (is_shift
4377169689Skan		  && (INTVAL (inner_const) >= GET_MODE_BITSIZE (mode)
4378169689Skan		      || INTVAL (inner_const) < 0))
4379169689Skan		{
4380169689Skan		  if (SHIFT_COUNT_TRUNCATED)
4381169689Skan		    inner_const = GEN_INT (INTVAL (inner_const)
4382169689Skan					   & (GET_MODE_BITSIZE (mode) - 1));
4383169689Skan		  else
4384169689Skan		    break;
4385169689Skan		}
4386169689Skan
438718334Speter	      /* Compute the code used to compose the constants.  For example,
4388117395Skan		 A-C1-C2 is A-(C1 + C2), so if CODE == MINUS, we want PLUS.  */
438918334Speter
4390117395Skan	      associate_code = (is_shift || code == MINUS ? PLUS : code);
439118334Speter
439218334Speter	      new_const = simplify_binary_operation (associate_code, mode,
439318334Speter						     const_arg1, inner_const);
439418334Speter
439518334Speter	      if (new_const == 0)
439618334Speter		break;
439718334Speter
439818334Speter	      /* If we are associating shift operations, don't let this
439918334Speter		 produce a shift of the size of the object or larger.
440018334Speter		 This could occur when we follow a sign-extend by a right
440118334Speter		 shift on a machine that does a sign-extend as a pair
440218334Speter		 of shifts.  */
440318334Speter
4404169689Skan	      if (is_shift
4405169689Skan		  && GET_CODE (new_const) == CONST_INT
440618334Speter		  && INTVAL (new_const) >= GET_MODE_BITSIZE (mode))
440718334Speter		{
440818334Speter		  /* As an exception, we can turn an ASHIFTRT of this
440918334Speter		     form into a shift of the number of bits - 1.  */
441018334Speter		  if (code == ASHIFTRT)
441118334Speter		    new_const = GEN_INT (GET_MODE_BITSIZE (mode) - 1);
4412169689Skan		  else if (!side_effects_p (XEXP (y, 0)))
4413169689Skan		    return CONST0_RTX (mode);
441418334Speter		  else
441518334Speter		    break;
441618334Speter		}
441718334Speter
441818334Speter	      y = copy_rtx (XEXP (y, 0));
441918334Speter
442018334Speter	      /* If Y contains our first operand (the most common way this
442118334Speter		 can happen is if Y is a MEM), we would do into an infinite
442218334Speter		 loop if we tried to fold it.  So don't in that case.  */
442318334Speter
442418334Speter	      if (! reg_mentioned_p (folded_arg0, y))
442518334Speter		y = fold_rtx (y, insn);
442618334Speter
442790075Sobrien	      return simplify_gen_binary (code, mode, y, new_const);
442818334Speter	    }
442950397Sobrien	  break;
443050397Sobrien
4431117395Skan	case DIV:       case UDIV:
4432117395Skan	  /* ??? The associative optimization performed immediately above is
4433117395Skan	     also possible for DIV and UDIV using associate_code of MULT.
4434117395Skan	     However, we would need extra code to verify that the
4435117395Skan	     multiplication does not overflow, that is, there is no overflow
4436117395Skan	     in the calculation of new_const.  */
4437117395Skan	  break;
4438117395Skan
443950397Sobrien	default:
444050397Sobrien	  break;
444118334Speter	}
444218334Speter
444318334Speter      new = simplify_binary_operation (code, mode,
444418334Speter				       const_arg0 ? const_arg0 : folded_arg0,
444518334Speter				       const_arg1 ? const_arg1 : folded_arg1);
444618334Speter      break;
444718334Speter
4448169689Skan    case RTX_OBJ:
444918334Speter      /* (lo_sum (high X) X) is simply X.  */
445018334Speter      if (code == LO_SUM && const_arg0 != 0
445118334Speter	  && GET_CODE (const_arg0) == HIGH
445218334Speter	  && rtx_equal_p (XEXP (const_arg0, 0), const_arg1))
445318334Speter	return const_arg1;
445418334Speter      break;
445518334Speter
4456169689Skan    case RTX_TERNARY:
4457169689Skan    case RTX_BITFIELD_OPS:
445818334Speter      new = simplify_ternary_operation (code, mode, mode_arg0,
445918334Speter					const_arg0 ? const_arg0 : folded_arg0,
446018334Speter					const_arg1 ? const_arg1 : folded_arg1,
446118334Speter					const_arg2 ? const_arg2 : XEXP (x, 2));
446218334Speter      break;
446350397Sobrien
4464169689Skan    default:
446550397Sobrien      break;
446618334Speter    }
446718334Speter
446818334Speter  return new ? new : x;
446918334Speter}
447018334Speter
447118334Speter/* Return a constant value currently equivalent to X.
447218334Speter   Return 0 if we don't know one.  */
447318334Speter
447418334Speterstatic rtx
4475132718Skanequiv_constant (rtx x)
447618334Speter{
4477169689Skan  if (REG_P (x)
447890075Sobrien      && REGNO_QTY_VALID_P (REGNO (x)))
447990075Sobrien    {
448090075Sobrien      int x_q = REG_QTY (REGNO (x));
448190075Sobrien      struct qty_table_elem *x_ent = &qty_table[x_q];
448218334Speter
448390075Sobrien      if (x_ent->const_rtx)
4484169689Skan	x = gen_lowpart (GET_MODE (x), x_ent->const_rtx);
448590075Sobrien    }
448690075Sobrien
448752284Sobrien  if (x == 0 || CONSTANT_P (x))
448818334Speter    return x;
448918334Speter
449018334Speter  /* If X is a MEM, try to fold it outside the context of any insn to see if
449118334Speter     it might be equivalent to a constant.  That handles the case where it
449218334Speter     is a constant-pool reference.  Then try to look it up in the hash table
449318334Speter     in case it is something whose value we have seen before.  */
449418334Speter
4495169689Skan  if (MEM_P (x))
449618334Speter    {
449718334Speter      struct table_elt *elt;
449818334Speter
449918334Speter      x = fold_rtx (x, NULL_RTX);
450018334Speter      if (CONSTANT_P (x))
450118334Speter	return x;
450218334Speter
4503169689Skan      elt = lookup (x, SAFE_HASH (x, GET_MODE (x)), GET_MODE (x));
450418334Speter      if (elt == 0)
450518334Speter	return 0;
450618334Speter
450718334Speter      for (elt = elt->first_same_value; elt; elt = elt->next_same_value)
450818334Speter	if (elt->is_const && CONSTANT_P (elt->exp))
450918334Speter	  return elt->exp;
451018334Speter    }
451118334Speter
451218334Speter  return 0;
451318334Speter}
451418334Speter
4515169689Skan/* Given INSN, a jump insn, PATH_TAKEN indicates if we are following the "taken"
451618334Speter   branch.  It will be zero if not.
451718334Speter
451818334Speter   In certain cases, this can cause us to add an equivalence.  For example,
451990075Sobrien   if we are following the taken case of
4520132718Skan	if (i == 2)
452118334Speter   we can add the fact that `i' and '2' are now equivalent.
452218334Speter
452318334Speter   In any case, we can record that this comparison was passed.  If the same
452418334Speter   comparison is seen later, we will know its value.  */
452518334Speter
452618334Speterstatic void
4527132718Skanrecord_jump_equiv (rtx insn, int taken)
452818334Speter{
452918334Speter  int cond_known_true;
453018334Speter  rtx op0, op1;
453190075Sobrien  rtx set;
453218334Speter  enum machine_mode mode, mode0, mode1;
453318334Speter  int reversed_nonequality = 0;
453418334Speter  enum rtx_code code;
453518334Speter
453618334Speter  /* Ensure this is the right kind of insn.  */
453790075Sobrien  if (! any_condjump_p (insn))
453818334Speter    return;
453990075Sobrien  set = pc_set (insn);
454018334Speter
454118334Speter  /* See if this jump condition is known true or false.  */
454218334Speter  if (taken)
454390075Sobrien    cond_known_true = (XEXP (SET_SRC (set), 2) == pc_rtx);
454418334Speter  else
454590075Sobrien    cond_known_true = (XEXP (SET_SRC (set), 1) == pc_rtx);
454618334Speter
454718334Speter  /* Get the type of comparison being done and the operands being compared.
454818334Speter     If we had to reverse a non-equality condition, record that fact so we
454918334Speter     know that it isn't valid for floating-point.  */
455090075Sobrien  code = GET_CODE (XEXP (SET_SRC (set), 0));
455190075Sobrien  op0 = fold_rtx (XEXP (XEXP (SET_SRC (set), 0), 0), insn);
455290075Sobrien  op1 = fold_rtx (XEXP (XEXP (SET_SRC (set), 0), 1), insn);
455318334Speter
455418334Speter  code = find_comparison_args (code, &op0, &op1, &mode0, &mode1);
4555169689Skan
4556169689Skan  /* If the mode is a MODE_CC mode, we don't know what kinds of things
4557169689Skan     are being compared, so we can't do anything with this
4558169689Skan     comparison.  */
4559169689Skan
4560169689Skan  if (GET_MODE_CLASS (mode0) == MODE_CC)
4561169689Skan    return;
4562169689Skan
456318334Speter  if (! cond_known_true)
456418334Speter    {
456590075Sobrien      code = reversed_comparison_code_parts (code, op0, op1, insn);
456690075Sobrien
456790075Sobrien      /* Don't remember if we can't find the inverse.  */
456890075Sobrien      if (code == UNKNOWN)
456990075Sobrien	return;
457018334Speter    }
457118334Speter
457218334Speter  /* The mode is the mode of the non-constant.  */
457318334Speter  mode = mode0;
457418334Speter  if (mode1 != VOIDmode)
457518334Speter    mode = mode1;
457618334Speter
457718334Speter  record_jump_cond (code, mode, op0, op1, reversed_nonequality);
457818334Speter}
457918334Speter
4580169689Skan/* Yet another form of subreg creation.  In this case, we want something in
4581169689Skan   MODE, and we should assume OP has MODE iff it is naturally modeless.  */
4582169689Skan
4583169689Skanstatic rtx
4584169689Skanrecord_jump_cond_subreg (enum machine_mode mode, rtx op)
4585169689Skan{
4586169689Skan  enum machine_mode op_mode = GET_MODE (op);
4587169689Skan  if (op_mode == mode || op_mode == VOIDmode)
4588169689Skan    return op;
4589169689Skan  return lowpart_subreg (mode, op, op_mode);
4590169689Skan}
4591169689Skan
459218334Speter/* We know that comparison CODE applied to OP0 and OP1 in MODE is true.
459318334Speter   REVERSED_NONEQUALITY is nonzero if CODE had to be swapped.
459418334Speter   Make any useful entries we can with that information.  Called from
459518334Speter   above function and called recursively.  */
459618334Speter
459718334Speterstatic void
4598132718Skanrecord_jump_cond (enum rtx_code code, enum machine_mode mode, rtx op0,
4599132718Skan		  rtx op1, int reversed_nonequality)
460018334Speter{
460118334Speter  unsigned op0_hash, op1_hash;
460290075Sobrien  int op0_in_memory, op1_in_memory;
460318334Speter  struct table_elt *op0_elt, *op1_elt;
460418334Speter
460518334Speter  /* If OP0 and OP1 are known equal, and either is a paradoxical SUBREG,
460618334Speter     we know that they are also equal in the smaller mode (this is also
460718334Speter     true for all smaller modes whether or not there is a SUBREG, but
460850397Sobrien     is not worth testing for with no SUBREG).  */
460918334Speter
461018334Speter  /* Note that GET_MODE (op0) may not equal MODE.  */
461118334Speter  if (code == EQ && GET_CODE (op0) == SUBREG
461218334Speter      && (GET_MODE_SIZE (GET_MODE (op0))
461318334Speter	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))
461418334Speter    {
461518334Speter      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
4616169689Skan      rtx tem = record_jump_cond_subreg (inner_mode, op1);
4617169689Skan      if (tem)
4618169689Skan	record_jump_cond (code, mode, SUBREG_REG (op0), tem,
4619169689Skan			  reversed_nonequality);
462018334Speter    }
462118334Speter
462218334Speter  if (code == EQ && GET_CODE (op1) == SUBREG
462318334Speter      && (GET_MODE_SIZE (GET_MODE (op1))
462418334Speter	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1)))))
462518334Speter    {
462618334Speter      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op1));
4627169689Skan      rtx tem = record_jump_cond_subreg (inner_mode, op0);
4628169689Skan      if (tem)
4629169689Skan	record_jump_cond (code, mode, SUBREG_REG (op1), tem,
4630169689Skan			  reversed_nonequality);
463118334Speter    }
463218334Speter
463390075Sobrien  /* Similarly, if this is an NE comparison, and either is a SUBREG
463418334Speter     making a smaller mode, we know the whole thing is also NE.  */
463518334Speter
463618334Speter  /* Note that GET_MODE (op0) may not equal MODE;
463718334Speter     if we test MODE instead, we can get an infinite recursion
463818334Speter     alternating between two modes each wider than MODE.  */
463918334Speter
464018334Speter  if (code == NE && GET_CODE (op0) == SUBREG
464118334Speter      && subreg_lowpart_p (op0)
464218334Speter      && (GET_MODE_SIZE (GET_MODE (op0))
464318334Speter	  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))
464418334Speter    {
464518334Speter      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
4646169689Skan      rtx tem = record_jump_cond_subreg (inner_mode, op1);
4647169689Skan      if (tem)
4648169689Skan	record_jump_cond (code, mode, SUBREG_REG (op0), tem,
4649169689Skan			  reversed_nonequality);
465018334Speter    }
465118334Speter
465218334Speter  if (code == NE && GET_CODE (op1) == SUBREG
465318334Speter      && subreg_lowpart_p (op1)
465418334Speter      && (GET_MODE_SIZE (GET_MODE (op1))
465518334Speter	  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1)))))
465618334Speter    {
465718334Speter      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op1));
4658169689Skan      rtx tem = record_jump_cond_subreg (inner_mode, op0);
4659169689Skan      if (tem)
4660169689Skan	record_jump_cond (code, mode, SUBREG_REG (op1), tem,
4661169689Skan			  reversed_nonequality);
466218334Speter    }
466318334Speter
466418334Speter  /* Hash both operands.  */
466518334Speter
466618334Speter  do_not_record = 0;
466718334Speter  hash_arg_in_memory = 0;
466818334Speter  op0_hash = HASH (op0, mode);
466918334Speter  op0_in_memory = hash_arg_in_memory;
467018334Speter
467118334Speter  if (do_not_record)
467218334Speter    return;
467318334Speter
467418334Speter  do_not_record = 0;
467518334Speter  hash_arg_in_memory = 0;
467618334Speter  op1_hash = HASH (op1, mode);
467718334Speter  op1_in_memory = hash_arg_in_memory;
467890075Sobrien
467918334Speter  if (do_not_record)
468018334Speter    return;
468118334Speter
468218334Speter  /* Look up both operands.  */
468318334Speter  op0_elt = lookup (op0, op0_hash, mode);
468418334Speter  op1_elt = lookup (op1, op1_hash, mode);
468518334Speter
468618334Speter  /* If both operands are already equivalent or if they are not in the
468718334Speter     table but are identical, do nothing.  */
468818334Speter  if ((op0_elt != 0 && op1_elt != 0
468918334Speter       && op0_elt->first_same_value == op1_elt->first_same_value)
469018334Speter      || op0 == op1 || rtx_equal_p (op0, op1))
469118334Speter    return;
469218334Speter
469318334Speter  /* If we aren't setting two things equal all we can do is save this
469418334Speter     comparison.   Similarly if this is floating-point.  In the latter
469518334Speter     case, OP1 might be zero and both -0.0 and 0.0 are equal to it.
469618334Speter     If we record the equality, we might inadvertently delete code
469718334Speter     whose intent was to change -0 to +0.  */
469818334Speter
469918334Speter  if (code != EQ || FLOAT_MODE_P (GET_MODE (op0)))
470018334Speter    {
470190075Sobrien      struct qty_table_elem *ent;
470290075Sobrien      int qty;
470390075Sobrien
470418334Speter      /* If we reversed a floating-point comparison, if OP0 is not a
470518334Speter	 register, or if OP1 is neither a register or constant, we can't
470618334Speter	 do anything.  */
470718334Speter
4708169689Skan      if (!REG_P (op1))
470918334Speter	op1 = equiv_constant (op1);
471018334Speter
471118334Speter      if ((reversed_nonequality && FLOAT_MODE_P (mode))
4712169689Skan	  || !REG_P (op0) || op1 == 0)
471318334Speter	return;
471418334Speter
471518334Speter      /* Put OP0 in the hash table if it isn't already.  This gives it a
471618334Speter	 new quantity number.  */
471718334Speter      if (op0_elt == 0)
471818334Speter	{
471990075Sobrien	  if (insert_regs (op0, NULL, 0))
472018334Speter	    {
472118334Speter	      rehash_using_reg (op0);
472218334Speter	      op0_hash = HASH (op0, mode);
472318334Speter
472418334Speter	      /* If OP0 is contained in OP1, this changes its hash code
472518334Speter		 as well.  Faster to rehash than to check, except
472618334Speter		 for the simple case of a constant.  */
472718334Speter	      if (! CONSTANT_P (op1))
472818334Speter		op1_hash = HASH (op1,mode);
472918334Speter	    }
473018334Speter
473190075Sobrien	  op0_elt = insert (op0, NULL, op0_hash, mode);
473218334Speter	  op0_elt->in_memory = op0_in_memory;
473318334Speter	}
473418334Speter
473590075Sobrien      qty = REG_QTY (REGNO (op0));
473690075Sobrien      ent = &qty_table[qty];
473790075Sobrien
473890075Sobrien      ent->comparison_code = code;
4739169689Skan      if (REG_P (op1))
474018334Speter	{
474118334Speter	  /* Look it up again--in case op0 and op1 are the same.  */
474218334Speter	  op1_elt = lookup (op1, op1_hash, mode);
474318334Speter
474418334Speter	  /* Put OP1 in the hash table so it gets a new quantity number.  */
474518334Speter	  if (op1_elt == 0)
474618334Speter	    {
474790075Sobrien	      if (insert_regs (op1, NULL, 0))
474818334Speter		{
474918334Speter		  rehash_using_reg (op1);
475018334Speter		  op1_hash = HASH (op1, mode);
475118334Speter		}
475218334Speter
475390075Sobrien	      op1_elt = insert (op1, NULL, op1_hash, mode);
475418334Speter	      op1_elt->in_memory = op1_in_memory;
475518334Speter	    }
475618334Speter
475790075Sobrien	  ent->comparison_const = NULL_RTX;
475890075Sobrien	  ent->comparison_qty = REG_QTY (REGNO (op1));
475918334Speter	}
476018334Speter      else
476118334Speter	{
476290075Sobrien	  ent->comparison_const = op1;
476390075Sobrien	  ent->comparison_qty = -1;
476418334Speter	}
476518334Speter
476618334Speter      return;
476718334Speter    }
476818334Speter
476918334Speter  /* If either side is still missing an equivalence, make it now,
477018334Speter     then merge the equivalences.  */
477118334Speter
477218334Speter  if (op0_elt == 0)
477318334Speter    {
477490075Sobrien      if (insert_regs (op0, NULL, 0))
477518334Speter	{
477618334Speter	  rehash_using_reg (op0);
477718334Speter	  op0_hash = HASH (op0, mode);
477818334Speter	}
477918334Speter
478090075Sobrien      op0_elt = insert (op0, NULL, op0_hash, mode);
478118334Speter      op0_elt->in_memory = op0_in_memory;
478218334Speter    }
478318334Speter
478418334Speter  if (op1_elt == 0)
478518334Speter    {
478690075Sobrien      if (insert_regs (op1, NULL, 0))
478718334Speter	{
478818334Speter	  rehash_using_reg (op1);
478918334Speter	  op1_hash = HASH (op1, mode);
479018334Speter	}
479118334Speter
479290075Sobrien      op1_elt = insert (op1, NULL, op1_hash, mode);
479318334Speter      op1_elt->in_memory = op1_in_memory;
479418334Speter    }
479518334Speter
479618334Speter  merge_equiv_classes (op0_elt, op1_elt);
479718334Speter}
479818334Speter
479918334Speter/* CSE processing for one instruction.
480018334Speter   First simplify sources and addresses of all assignments
480118334Speter   in the instruction, using previously-computed equivalents values.
480218334Speter   Then install the new sources and destinations in the table
480390075Sobrien   of available values.
480418334Speter
480550397Sobrien   If LIBCALL_INSN is nonzero, don't record any equivalence made in
480650397Sobrien   the insn.  It means that INSN is inside libcall block.  In this
480790075Sobrien   case LIBCALL_INSN is the corresponding insn with REG_LIBCALL.  */
480818334Speter
480918334Speter/* Data on one SET contained in the instruction.  */
481018334Speter
481118334Speterstruct set
481218334Speter{
481318334Speter  /* The SET rtx itself.  */
481418334Speter  rtx rtl;
481518334Speter  /* The SET_SRC of the rtx (the original value, if it is changing).  */
481618334Speter  rtx src;
481718334Speter  /* The hash-table element for the SET_SRC of the SET.  */
481818334Speter  struct table_elt *src_elt;
481918334Speter  /* Hash value for the SET_SRC.  */
482018334Speter  unsigned src_hash;
482118334Speter  /* Hash value for the SET_DEST.  */
482218334Speter  unsigned dest_hash;
482318334Speter  /* The SET_DEST, with SUBREG, etc., stripped.  */
482418334Speter  rtx inner_dest;
482590075Sobrien  /* Nonzero if the SET_SRC is in memory.  */
482618334Speter  char src_in_memory;
482718334Speter  /* Nonzero if the SET_SRC contains something
482818334Speter     whose value cannot be predicted and understood.  */
482918334Speter  char src_volatile;
4830132718Skan  /* Original machine mode, in case it becomes a CONST_INT.
4831132718Skan     The size of this field should match the size of the mode
4832132718Skan     field of struct rtx_def (see rtl.h).  */
4833132718Skan  ENUM_BITFIELD(machine_mode) mode : 8;
483418334Speter  /* A constant equivalent for SET_SRC, if any.  */
483518334Speter  rtx src_const;
483690075Sobrien  /* Original SET_SRC value used for libcall notes.  */
483790075Sobrien  rtx orig_src;
483818334Speter  /* Hash value of constant equivalent for SET_SRC.  */
483918334Speter  unsigned src_const_hash;
484018334Speter  /* Table entry for constant equivalent for SET_SRC, if any.  */
484118334Speter  struct table_elt *src_const_elt;
4842169689Skan  /* Table entry for the destination address.  */
4843169689Skan  struct table_elt *dest_addr_elt;
484418334Speter};
484518334Speter
484618334Speterstatic void
4847132718Skancse_insn (rtx insn, rtx libcall_insn)
484818334Speter{
484990075Sobrien  rtx x = PATTERN (insn);
485090075Sobrien  int i;
485118334Speter  rtx tem;
485290075Sobrien  int n_sets = 0;
485318334Speter
485450397Sobrien#ifdef HAVE_cc0
485518334Speter  /* Records what this insn does to set CC0.  */
485618334Speter  rtx this_insn_cc0 = 0;
485750397Sobrien  enum machine_mode this_insn_cc0_mode = VOIDmode;
485850397Sobrien#endif
485918334Speter
486018334Speter  rtx src_eqv = 0;
486118334Speter  struct table_elt *src_eqv_elt = 0;
486290075Sobrien  int src_eqv_volatile = 0;
486390075Sobrien  int src_eqv_in_memory = 0;
486490075Sobrien  unsigned src_eqv_hash = 0;
486518334Speter
486690075Sobrien  struct set *sets = (struct set *) 0;
486718334Speter
486818334Speter  this_insn = insn;
486918334Speter
487018334Speter  /* Find all the SETs and CLOBBERs in this instruction.
487118334Speter     Record all the SETs in the array `set' and count them.
487218334Speter     Also determine whether there is a CLOBBER that invalidates
487318334Speter     all memory references, or all references at varying addresses.  */
487418334Speter
4875169689Skan  if (CALL_P (insn))
487618334Speter    {
487718334Speter      for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
487890075Sobrien	{
487990075Sobrien	  if (GET_CODE (XEXP (tem, 0)) == CLOBBER)
488090075Sobrien	    invalidate (SET_DEST (XEXP (tem, 0)), VOIDmode);
488190075Sobrien	  XEXP (tem, 0) = canon_reg (XEXP (tem, 0), insn);
488290075Sobrien	}
488318334Speter    }
488418334Speter
488518334Speter  if (GET_CODE (x) == SET)
488618334Speter    {
4887132718Skan      sets = alloca (sizeof (struct set));
488818334Speter      sets[0].rtl = x;
488918334Speter
489018334Speter      /* Ignore SETs that are unconditional jumps.
489118334Speter	 They never need cse processing, so this does not hurt.
489218334Speter	 The reason is not efficiency but rather
489318334Speter	 so that we can test at the end for instructions
489418334Speter	 that have been simplified to unconditional jumps
489518334Speter	 and not be misled by unchanged instructions
489618334Speter	 that were unconditional jumps to begin with.  */
489718334Speter      if (SET_DEST (x) == pc_rtx
489818334Speter	  && GET_CODE (SET_SRC (x)) == LABEL_REF)
489918334Speter	;
490018334Speter
490118334Speter      /* Don't count call-insns, (set (reg 0) (call ...)), as a set.
490218334Speter	 The hard function value register is used only once, to copy to
490318334Speter	 someplace else, so it isn't worth cse'ing (and on 80386 is unsafe)!
490418334Speter	 Ensure we invalidate the destination register.  On the 80386 no
490518334Speter	 other code would invalidate it since it is a fixed_reg.
490650397Sobrien	 We need not check the return of apply_change_group; see canon_reg.  */
490718334Speter
490818334Speter      else if (GET_CODE (SET_SRC (x)) == CALL)
490918334Speter	{
491018334Speter	  canon_reg (SET_SRC (x), insn);
491118334Speter	  apply_change_group ();
491218334Speter	  fold_rtx (SET_SRC (x), insn);
491318334Speter	  invalidate (SET_DEST (x), VOIDmode);
491418334Speter	}
491518334Speter      else
491618334Speter	n_sets = 1;
491718334Speter    }
491818334Speter  else if (GET_CODE (x) == PARALLEL)
491918334Speter    {
492090075Sobrien      int lim = XVECLEN (x, 0);
492118334Speter
4922132718Skan      sets = alloca (lim * sizeof (struct set));
492318334Speter
492418334Speter      /* Find all regs explicitly clobbered in this insn,
492518334Speter	 and ensure they are not replaced with any other regs
492618334Speter	 elsewhere in this insn.
492718334Speter	 When a reg that is clobbered is also used for input,
492818334Speter	 we should presume that that is for a reason,
492918334Speter	 and we should not substitute some other register
493018334Speter	 which is not supposed to be clobbered.
493118334Speter	 Therefore, this loop cannot be merged into the one below
493218334Speter	 because a CALL may precede a CLOBBER and refer to the
493318334Speter	 value clobbered.  We must not let a canonicalization do
493418334Speter	 anything in that case.  */
493518334Speter      for (i = 0; i < lim; i++)
493618334Speter	{
493790075Sobrien	  rtx y = XVECEXP (x, 0, i);
493818334Speter	  if (GET_CODE (y) == CLOBBER)
493918334Speter	    {
494018334Speter	      rtx clobbered = XEXP (y, 0);
494118334Speter
4942169689Skan	      if (REG_P (clobbered)
494318334Speter		  || GET_CODE (clobbered) == SUBREG)
494418334Speter		invalidate (clobbered, VOIDmode);
494518334Speter	      else if (GET_CODE (clobbered) == STRICT_LOW_PART
494618334Speter		       || GET_CODE (clobbered) == ZERO_EXTRACT)
494718334Speter		invalidate (XEXP (clobbered, 0), GET_MODE (clobbered));
494818334Speter	    }
494918334Speter	}
495090075Sobrien
495118334Speter      for (i = 0; i < lim; i++)
495218334Speter	{
495390075Sobrien	  rtx y = XVECEXP (x, 0, i);
495418334Speter	  if (GET_CODE (y) == SET)
495518334Speter	    {
495618334Speter	      /* As above, we ignore unconditional jumps and call-insns and
495718334Speter		 ignore the result of apply_change_group.  */
495818334Speter	      if (GET_CODE (SET_SRC (y)) == CALL)
495918334Speter		{
496018334Speter		  canon_reg (SET_SRC (y), insn);
496118334Speter		  apply_change_group ();
496218334Speter		  fold_rtx (SET_SRC (y), insn);
496318334Speter		  invalidate (SET_DEST (y), VOIDmode);
496418334Speter		}
496518334Speter	      else if (SET_DEST (y) == pc_rtx
496618334Speter		       && GET_CODE (SET_SRC (y)) == LABEL_REF)
496718334Speter		;
496818334Speter	      else
496918334Speter		sets[n_sets++].rtl = y;
497018334Speter	    }
497118334Speter	  else if (GET_CODE (y) == CLOBBER)
497218334Speter	    {
497350397Sobrien	      /* If we clobber memory, canon the address.
497418334Speter		 This does nothing when a register is clobbered
497518334Speter		 because we have already invalidated the reg.  */
4976169689Skan	      if (MEM_P (XEXP (y, 0)))
497750397Sobrien		canon_reg (XEXP (y, 0), NULL_RTX);
497818334Speter	    }
497918334Speter	  else if (GET_CODE (y) == USE
4980169689Skan		   && ! (REG_P (XEXP (y, 0))
498118334Speter			 && REGNO (XEXP (y, 0)) < FIRST_PSEUDO_REGISTER))
498218334Speter	    canon_reg (y, NULL_RTX);
498318334Speter	  else if (GET_CODE (y) == CALL)
498418334Speter	    {
498518334Speter	      /* The result of apply_change_group can be ignored; see
498618334Speter		 canon_reg.  */
498718334Speter	      canon_reg (y, insn);
498818334Speter	      apply_change_group ();
498918334Speter	      fold_rtx (y, insn);
499018334Speter	    }
499118334Speter	}
499218334Speter    }
499318334Speter  else if (GET_CODE (x) == CLOBBER)
499418334Speter    {
4995169689Skan      if (MEM_P (XEXP (x, 0)))
499650397Sobrien	canon_reg (XEXP (x, 0), NULL_RTX);
499718334Speter    }
499818334Speter
499918334Speter  /* Canonicalize a USE of a pseudo register or memory location.  */
500018334Speter  else if (GET_CODE (x) == USE
5001169689Skan	   && ! (REG_P (XEXP (x, 0))
500218334Speter		 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER))
500318334Speter    canon_reg (XEXP (x, 0), NULL_RTX);
500418334Speter  else if (GET_CODE (x) == CALL)
500518334Speter    {
500618334Speter      /* The result of apply_change_group can be ignored; see canon_reg.  */
500718334Speter      canon_reg (x, insn);
500818334Speter      apply_change_group ();
500918334Speter      fold_rtx (x, insn);
501018334Speter    }
501118334Speter
501218334Speter  /* Store the equivalent value in SRC_EQV, if different, or if the DEST
501318334Speter     is a STRICT_LOW_PART.  The latter condition is necessary because SRC_EQV
501418334Speter     is handled specially for this case, and if it isn't set, then there will
501518334Speter     be no equivalence for the destination.  */
501618334Speter  if (n_sets == 1 && REG_NOTES (insn) != 0
501718334Speter      && (tem = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0
501818334Speter      && (! rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl))
501918334Speter	  || GET_CODE (SET_DEST (sets[0].rtl)) == STRICT_LOW_PART))
5020102780Skan    {
5021102780Skan      src_eqv = fold_rtx (canon_reg (XEXP (tem, 0), NULL_RTX), insn);
5022102780Skan      XEXP (tem, 0) = src_eqv;
5023102780Skan    }
502418334Speter
502518334Speter  /* Canonicalize sources and addresses of destinations.
502618334Speter     We do this in a separate pass to avoid problems when a MATCH_DUP is
502718334Speter     present in the insn pattern.  In that case, we want to ensure that
502818334Speter     we don't break the duplicate nature of the pattern.  So we will replace
502918334Speter     both operands at the same time.  Otherwise, we would fail to find an
503018334Speter     equivalent substitution in the loop calling validate_change below.
503118334Speter
503218334Speter     We used to suppress canonicalization of DEST if it appears in SRC,
503318334Speter     but we don't do this any more.  */
503418334Speter
503518334Speter  for (i = 0; i < n_sets; i++)
503618334Speter    {
503718334Speter      rtx dest = SET_DEST (sets[i].rtl);
503818334Speter      rtx src = SET_SRC (sets[i].rtl);
503918334Speter      rtx new = canon_reg (src, insn);
504018334Speter
504190075Sobrien      sets[i].orig_src = src;
5042169689Skan      validate_change (insn, &SET_SRC (sets[i].rtl), new, 1);
504318334Speter
5044169689Skan      if (GET_CODE (dest) == ZERO_EXTRACT)
504518334Speter	{
504618334Speter	  validate_change (insn, &XEXP (dest, 1),
504718334Speter			   canon_reg (XEXP (dest, 1), insn), 1);
504818334Speter	  validate_change (insn, &XEXP (dest, 2),
504918334Speter			   canon_reg (XEXP (dest, 2), insn), 1);
505018334Speter	}
505118334Speter
5052169689Skan      while (GET_CODE (dest) == SUBREG
505318334Speter	     || GET_CODE (dest) == ZERO_EXTRACT
5054169689Skan	     || GET_CODE (dest) == STRICT_LOW_PART)
505518334Speter	dest = XEXP (dest, 0);
505618334Speter
5057169689Skan      if (MEM_P (dest))
505818334Speter	canon_reg (dest, insn);
505918334Speter    }
506018334Speter
506118334Speter  /* Now that we have done all the replacements, we can apply the change
506218334Speter     group and see if they all work.  Note that this will cause some
506318334Speter     canonicalizations that would have worked individually not to be applied
506418334Speter     because some other canonicalization didn't work, but this should not
506590075Sobrien     occur often.
506618334Speter
506718334Speter     The result of apply_change_group can be ignored; see canon_reg.  */
506818334Speter
506918334Speter  apply_change_group ();
507018334Speter
507118334Speter  /* Set sets[i].src_elt to the class each source belongs to.
507218334Speter     Detect assignments from or to volatile things
507318334Speter     and set set[i] to zero so they will be ignored
507418334Speter     in the rest of this function.
507518334Speter
507618334Speter     Nothing in this loop changes the hash table or the register chains.  */
507718334Speter
507818334Speter  for (i = 0; i < n_sets; i++)
507918334Speter    {
508090075Sobrien      rtx src, dest;
508190075Sobrien      rtx src_folded;
508290075Sobrien      struct table_elt *elt = 0, *p;
508318334Speter      enum machine_mode mode;
508418334Speter      rtx src_eqv_here;
508518334Speter      rtx src_const = 0;
508618334Speter      rtx src_related = 0;
508718334Speter      struct table_elt *src_const_elt = 0;
508890075Sobrien      int src_cost = MAX_COST;
508990075Sobrien      int src_eqv_cost = MAX_COST;
509090075Sobrien      int src_folded_cost = MAX_COST;
509190075Sobrien      int src_related_cost = MAX_COST;
509290075Sobrien      int src_elt_cost = MAX_COST;
509390075Sobrien      int src_regcost = MAX_COST;
509490075Sobrien      int src_eqv_regcost = MAX_COST;
509590075Sobrien      int src_folded_regcost = MAX_COST;
509690075Sobrien      int src_related_regcost = MAX_COST;
509790075Sobrien      int src_elt_regcost = MAX_COST;
5098117395Skan      /* Set nonzero if we need to call force_const_mem on with the
509918334Speter	 contents of src_folded before using it.  */
510018334Speter      int src_folded_force_flag = 0;
510118334Speter
510218334Speter      dest = SET_DEST (sets[i].rtl);
510318334Speter      src = SET_SRC (sets[i].rtl);
510418334Speter
510518334Speter      /* If SRC is a constant that has no machine mode,
510618334Speter	 hash it with the destination's machine mode.
510718334Speter	 This way we can keep different modes separate.  */
510818334Speter
510918334Speter      mode = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src);
511018334Speter      sets[i].mode = mode;
511118334Speter
511218334Speter      if (src_eqv)
511318334Speter	{
511418334Speter	  enum machine_mode eqvmode = mode;
511518334Speter	  if (GET_CODE (dest) == STRICT_LOW_PART)
511618334Speter	    eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
511718334Speter	  do_not_record = 0;
511818334Speter	  hash_arg_in_memory = 0;
511918334Speter	  src_eqv_hash = HASH (src_eqv, eqvmode);
512018334Speter
512118334Speter	  /* Find the equivalence class for the equivalent expression.  */
512218334Speter
512318334Speter	  if (!do_not_record)
512418334Speter	    src_eqv_elt = lookup (src_eqv, src_eqv_hash, eqvmode);
512518334Speter
512618334Speter	  src_eqv_volatile = do_not_record;
512718334Speter	  src_eqv_in_memory = hash_arg_in_memory;
512818334Speter	}
512918334Speter
513018334Speter      /* If this is a STRICT_LOW_PART assignment, src_eqv corresponds to the
513118334Speter	 value of the INNER register, not the destination.  So it is not
513218334Speter	 a valid substitution for the source.  But save it for later.  */
513318334Speter      if (GET_CODE (dest) == STRICT_LOW_PART)
513418334Speter	src_eqv_here = 0;
513518334Speter      else
513618334Speter	src_eqv_here = src_eqv;
513718334Speter
513818334Speter      /* Simplify and foldable subexpressions in SRC.  Then get the fully-
513918334Speter	 simplified result, which may not necessarily be valid.  */
514018334Speter      src_folded = fold_rtx (src, insn);
514118334Speter
514218334Speter#if 0
514318334Speter      /* ??? This caused bad code to be generated for the m68k port with -O2.
514418334Speter	 Suppose src is (CONST_INT -1), and that after truncation src_folded
514518334Speter	 is (CONST_INT 3).  Suppose src_folded is then used for src_const.
514618334Speter	 At the end we will add src and src_const to the same equivalence
514718334Speter	 class.  We now have 3 and -1 on the same equivalence class.  This
514818334Speter	 causes later instructions to be mis-optimized.  */
514918334Speter      /* If storing a constant in a bitfield, pre-truncate the constant
515018334Speter	 so we will be able to record it later.  */
5151169689Skan      if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT)
515218334Speter	{
515318334Speter	  rtx width = XEXP (SET_DEST (sets[i].rtl), 1);
515418334Speter
515518334Speter	  if (GET_CODE (src) == CONST_INT
515618334Speter	      && GET_CODE (width) == CONST_INT
515718334Speter	      && INTVAL (width) < HOST_BITS_PER_WIDE_INT
515818334Speter	      && (INTVAL (src) & ((HOST_WIDE_INT) (-1) << INTVAL (width))))
515918334Speter	    src_folded
516018334Speter	      = GEN_INT (INTVAL (src) & (((HOST_WIDE_INT) 1
516118334Speter					  << INTVAL (width)) - 1));
516218334Speter	}
516318334Speter#endif
516418334Speter
516518334Speter      /* Compute SRC's hash code, and also notice if it
516618334Speter	 should not be recorded at all.  In that case,
516718334Speter	 prevent any further processing of this assignment.  */
516818334Speter      do_not_record = 0;
516918334Speter      hash_arg_in_memory = 0;
517018334Speter
517118334Speter      sets[i].src = src;
517218334Speter      sets[i].src_hash = HASH (src, mode);
517318334Speter      sets[i].src_volatile = do_not_record;
517418334Speter      sets[i].src_in_memory = hash_arg_in_memory;
517518334Speter
517650397Sobrien      /* If SRC is a MEM, there is a REG_EQUIV note for SRC, and DEST is
517790075Sobrien	 a pseudo, do not record SRC.  Using SRC as a replacement for
517890075Sobrien	 anything else will be incorrect in that situation.  Note that
517990075Sobrien	 this usually occurs only for stack slots, in which case all the
518090075Sobrien	 RTL would be referring to SRC, so we don't lose any optimization
518190075Sobrien	 opportunities by not having SRC in the hash table.  */
518250397Sobrien
5183169689Skan      if (MEM_P (src)
518490075Sobrien	  && find_reg_note (insn, REG_EQUIV, NULL_RTX) != 0
5185169689Skan	  && REG_P (dest)
518690075Sobrien	  && REGNO (dest) >= FIRST_PSEUDO_REGISTER)
518750397Sobrien	sets[i].src_volatile = 1;
518850397Sobrien
518918334Speter#if 0
519018334Speter      /* It is no longer clear why we used to do this, but it doesn't
519118334Speter	 appear to still be needed.  So let's try without it since this
519218334Speter	 code hurts cse'ing widened ops.  */
5193169689Skan      /* If source is a paradoxical subreg (such as QI treated as an SI),
519418334Speter	 treat it as volatile.  It may do the work of an SI in one context
519518334Speter	 where the extra bits are not being used, but cannot replace an SI
519618334Speter	 in general.  */
519718334Speter      if (GET_CODE (src) == SUBREG
519818334Speter	  && (GET_MODE_SIZE (GET_MODE (src))
519918334Speter	      > GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))
520018334Speter	sets[i].src_volatile = 1;
520118334Speter#endif
520218334Speter
520318334Speter      /* Locate all possible equivalent forms for SRC.  Try to replace
520418334Speter         SRC in the insn with each cheaper equivalent.
520518334Speter
520618334Speter         We have the following types of equivalents: SRC itself, a folded
520718334Speter         version, a value given in a REG_EQUAL note, or a value related
520818334Speter	 to a constant.
520918334Speter
521018334Speter         Each of these equivalents may be part of an additional class
521118334Speter         of equivalents (if more than one is in the table, they must be in
521218334Speter         the same class; we check for this).
521318334Speter
521418334Speter	 If the source is volatile, we don't do any table lookups.
521518334Speter
521618334Speter         We note any constant equivalent for possible later use in a
521718334Speter         REG_NOTE.  */
521818334Speter
521918334Speter      if (!sets[i].src_volatile)
522018334Speter	elt = lookup (src, sets[i].src_hash, mode);
522118334Speter
522218334Speter      sets[i].src_elt = elt;
522318334Speter
522418334Speter      if (elt && src_eqv_here && src_eqv_elt)
522590075Sobrien	{
522690075Sobrien	  if (elt->first_same_value != src_eqv_elt->first_same_value)
522718334Speter	    {
522818334Speter	      /* The REG_EQUAL is indicating that two formerly distinct
522918334Speter		 classes are now equivalent.  So merge them.  */
523018334Speter	      merge_equiv_classes (elt, src_eqv_elt);
523118334Speter	      src_eqv_hash = HASH (src_eqv, elt->mode);
523218334Speter	      src_eqv_elt = lookup (src_eqv, src_eqv_hash, elt->mode);
523318334Speter	    }
523418334Speter
523590075Sobrien	  src_eqv_here = 0;
523690075Sobrien	}
523718334Speter
523818334Speter      else if (src_eqv_elt)
523990075Sobrien	elt = src_eqv_elt;
524018334Speter
524118334Speter      /* Try to find a constant somewhere and record it in `src_const'.
524218334Speter	 Record its table element, if any, in `src_const_elt'.  Look in
524318334Speter	 any known equivalences first.  (If the constant is not in the
524418334Speter	 table, also set `sets[i].src_const_hash').  */
524518334Speter      if (elt)
524690075Sobrien	for (p = elt->first_same_value; p; p = p->next_same_value)
524718334Speter	  if (p->is_const)
524818334Speter	    {
524918334Speter	      src_const = p->exp;
525018334Speter	      src_const_elt = elt;
525118334Speter	      break;
525218334Speter	    }
525318334Speter
525418334Speter      if (src_const == 0
525518334Speter	  && (CONSTANT_P (src_folded)
525690075Sobrien	      /* Consider (minus (label_ref L1) (label_ref L2)) as
525718334Speter		 "constant" here so we will record it. This allows us
525818334Speter		 to fold switch statements when an ADDR_DIFF_VEC is used.  */
525918334Speter	      || (GET_CODE (src_folded) == MINUS
526018334Speter		  && GET_CODE (XEXP (src_folded, 0)) == LABEL_REF
526118334Speter		  && GET_CODE (XEXP (src_folded, 1)) == LABEL_REF)))
526218334Speter	src_const = src_folded, src_const_elt = elt;
526318334Speter      else if (src_const == 0 && src_eqv_here && CONSTANT_P (src_eqv_here))
526418334Speter	src_const = src_eqv_here, src_const_elt = src_eqv_elt;
526518334Speter
526618334Speter      /* If we don't know if the constant is in the table, get its
526718334Speter	 hash code and look it up.  */
526818334Speter      if (src_const && src_const_elt == 0)
526918334Speter	{
527018334Speter	  sets[i].src_const_hash = HASH (src_const, mode);
527118334Speter	  src_const_elt = lookup (src_const, sets[i].src_const_hash, mode);
527218334Speter	}
527318334Speter
527418334Speter      sets[i].src_const = src_const;
527518334Speter      sets[i].src_const_elt = src_const_elt;
527618334Speter
527718334Speter      /* If the constant and our source are both in the table, mark them as
527818334Speter	 equivalent.  Otherwise, if a constant is in the table but the source
527918334Speter	 isn't, set ELT to it.  */
528018334Speter      if (src_const_elt && elt
528118334Speter	  && src_const_elt->first_same_value != elt->first_same_value)
528218334Speter	merge_equiv_classes (elt, src_const_elt);
528318334Speter      else if (src_const_elt && elt == 0)
528418334Speter	elt = src_const_elt;
528518334Speter
528618334Speter      /* See if there is a register linearly related to a constant
528718334Speter         equivalent of SRC.  */
528818334Speter      if (src_const
528918334Speter	  && (GET_CODE (src_const) == CONST
529018334Speter	      || (src_const_elt && src_const_elt->related_value != 0)))
529190075Sobrien	{
529290075Sobrien	  src_related = use_related_value (src_const, src_const_elt);
529390075Sobrien	  if (src_related)
529490075Sobrien	    {
529518334Speter	      struct table_elt *src_related_elt
529690075Sobrien		= lookup (src_related, HASH (src_related, mode), mode);
529718334Speter	      if (src_related_elt && elt)
529890075Sobrien		{
529918334Speter		  if (elt->first_same_value
530018334Speter		      != src_related_elt->first_same_value)
530190075Sobrien		    /* This can occur when we previously saw a CONST
530218334Speter		       involving a SYMBOL_REF and then see the SYMBOL_REF
530318334Speter		       twice.  Merge the involved classes.  */
530418334Speter		    merge_equiv_classes (elt, src_related_elt);
530518334Speter
530690075Sobrien		  src_related = 0;
530718334Speter		  src_related_elt = 0;
530890075Sobrien		}
530990075Sobrien	      else if (src_related_elt && elt == 0)
531090075Sobrien		elt = src_related_elt;
531118334Speter	    }
531290075Sobrien	}
531318334Speter
531418334Speter      /* See if we have a CONST_INT that is already in a register in a
531518334Speter	 wider mode.  */
531618334Speter
531718334Speter      if (src_const && src_related == 0 && GET_CODE (src_const) == CONST_INT
531818334Speter	  && GET_MODE_CLASS (mode) == MODE_INT
531918334Speter	  && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
532018334Speter	{
532118334Speter	  enum machine_mode wider_mode;
532218334Speter
532318334Speter	  for (wider_mode = GET_MODE_WIDER_MODE (mode);
532418334Speter	       GET_MODE_BITSIZE (wider_mode) <= BITS_PER_WORD
532518334Speter	       && src_related == 0;
532618334Speter	       wider_mode = GET_MODE_WIDER_MODE (wider_mode))
532718334Speter	    {
532818334Speter	      struct table_elt *const_elt
532918334Speter		= lookup (src_const, HASH (src_const, wider_mode), wider_mode);
533018334Speter
533118334Speter	      if (const_elt == 0)
533218334Speter		continue;
533318334Speter
533418334Speter	      for (const_elt = const_elt->first_same_value;
533518334Speter		   const_elt; const_elt = const_elt->next_same_value)
5336169689Skan		if (REG_P (const_elt->exp))
533718334Speter		  {
5338169689Skan		    src_related = gen_lowpart (mode,
533918334Speter							   const_elt->exp);
534018334Speter		    break;
534118334Speter		  }
534218334Speter	    }
534318334Speter	}
534418334Speter
534518334Speter      /* Another possibility is that we have an AND with a constant in
534618334Speter	 a mode narrower than a word.  If so, it might have been generated
534718334Speter	 as part of an "if" which would narrow the AND.  If we already
534818334Speter	 have done the AND in a wider mode, we can use a SUBREG of that
534918334Speter	 value.  */
535018334Speter
535118334Speter      if (flag_expensive_optimizations && ! src_related
535218334Speter	  && GET_CODE (src) == AND && GET_CODE (XEXP (src, 1)) == CONST_INT
535318334Speter	  && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
535418334Speter	{
535518334Speter	  enum machine_mode tmode;
535650397Sobrien	  rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));
535718334Speter
535818334Speter	  for (tmode = GET_MODE_WIDER_MODE (mode);
535918334Speter	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
536018334Speter	       tmode = GET_MODE_WIDER_MODE (tmode))
536118334Speter	    {
5362169689Skan	      rtx inner = gen_lowpart (tmode, XEXP (src, 0));
536318334Speter	      struct table_elt *larger_elt;
536418334Speter
536518334Speter	      if (inner)
536618334Speter		{
536718334Speter		  PUT_MODE (new_and, tmode);
536818334Speter		  XEXP (new_and, 0) = inner;
536918334Speter		  larger_elt = lookup (new_and, HASH (new_and, tmode), tmode);
537018334Speter		  if (larger_elt == 0)
537118334Speter		    continue;
537218334Speter
537318334Speter		  for (larger_elt = larger_elt->first_same_value;
537418334Speter		       larger_elt; larger_elt = larger_elt->next_same_value)
5375169689Skan		    if (REG_P (larger_elt->exp))
537618334Speter		      {
537718334Speter			src_related
5378169689Skan			  = gen_lowpart (mode, larger_elt->exp);
537918334Speter			break;
538018334Speter		      }
538118334Speter
538218334Speter		  if (src_related)
538318334Speter		    break;
538418334Speter		}
538518334Speter	    }
538618334Speter	}
538718334Speter
538818334Speter#ifdef LOAD_EXTEND_OP
538918334Speter      /* See if a MEM has already been loaded with a widening operation;
539018334Speter	 if it has, we can use a subreg of that.  Many CISC machines
539118334Speter	 also have such operations, but this is only likely to be
5392169689Skan	 beneficial on these machines.  */
539390075Sobrien
539490075Sobrien      if (flag_expensive_optimizations && src_related == 0
539518334Speter	  && (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
539618334Speter	  && GET_MODE_CLASS (mode) == MODE_INT
5397169689Skan	  && MEM_P (src) && ! do_not_record
5398169689Skan	  && LOAD_EXTEND_OP (mode) != UNKNOWN)
539918334Speter	{
5400169689Skan	  struct rtx_def memory_extend_buf;
5401169689Skan	  rtx memory_extend_rtx = &memory_extend_buf;
540218334Speter	  enum machine_mode tmode;
540390075Sobrien
540418334Speter	  /* Set what we are trying to extend and the operation it might
540518334Speter	     have been extended with.  */
5406169689Skan	  memset (memory_extend_rtx, 0, sizeof(*memory_extend_rtx));
540718334Speter	  PUT_CODE (memory_extend_rtx, LOAD_EXTEND_OP (mode));
540818334Speter	  XEXP (memory_extend_rtx, 0) = src;
540990075Sobrien
541018334Speter	  for (tmode = GET_MODE_WIDER_MODE (mode);
541118334Speter	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
541218334Speter	       tmode = GET_MODE_WIDER_MODE (tmode))
541318334Speter	    {
541418334Speter	      struct table_elt *larger_elt;
541590075Sobrien
541618334Speter	      PUT_MODE (memory_extend_rtx, tmode);
541790075Sobrien	      larger_elt = lookup (memory_extend_rtx,
541818334Speter				   HASH (memory_extend_rtx, tmode), tmode);
541918334Speter	      if (larger_elt == 0)
542018334Speter		continue;
542190075Sobrien
542218334Speter	      for (larger_elt = larger_elt->first_same_value;
542318334Speter		   larger_elt; larger_elt = larger_elt->next_same_value)
5424169689Skan		if (REG_P (larger_elt->exp))
542518334Speter		  {
5426169689Skan		    src_related = gen_lowpart (mode,
542718334Speter							   larger_elt->exp);
542818334Speter		    break;
542918334Speter		  }
543090075Sobrien
543118334Speter	      if (src_related)
543218334Speter		break;
543318334Speter	    }
543418334Speter	}
543518334Speter#endif /* LOAD_EXTEND_OP */
543690075Sobrien
543718334Speter      if (src == src_folded)
543890075Sobrien	src_folded = 0;
543918334Speter
5440117395Skan      /* At this point, ELT, if nonzero, points to a class of expressions
544118334Speter         equivalent to the source of this SET and SRC, SRC_EQV, SRC_FOLDED,
5442117395Skan	 and SRC_RELATED, if nonzero, each contain additional equivalent
544318334Speter	 expressions.  Prune these latter expressions by deleting expressions
544418334Speter	 already in the equivalence class.
544518334Speter
544618334Speter	 Check for an equivalent identical to the destination.  If found,
544718334Speter	 this is the preferred equivalent since it will likely lead to
544818334Speter	 elimination of the insn.  Indicate this by placing it in
544918334Speter	 `src_related'.  */
545018334Speter
545190075Sobrien      if (elt)
545290075Sobrien	elt = elt->first_same_value;
545318334Speter      for (p = elt; p; p = p->next_same_value)
545490075Sobrien	{
545518334Speter	  enum rtx_code code = GET_CODE (p->exp);
545618334Speter
545718334Speter	  /* If the expression is not valid, ignore it.  Then we do not
545818334Speter	     have to check for validity below.  In most cases, we can use
545918334Speter	     `rtx_equal_p', since canonicalization has already been done.  */
5460169689Skan	  if (code != REG && ! exp_equiv_p (p->exp, p->exp, 1, false))
546118334Speter	    continue;
546218334Speter
546350397Sobrien	  /* Also skip paradoxical subregs, unless that's what we're
546450397Sobrien	     looking for.  */
546550397Sobrien	  if (code == SUBREG
546650397Sobrien	      && (GET_MODE_SIZE (GET_MODE (p->exp))
546750397Sobrien		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (p->exp))))
546850397Sobrien	      && ! (src != 0
546950397Sobrien		    && GET_CODE (src) == SUBREG
547050397Sobrien		    && GET_MODE (src) == GET_MODE (p->exp)
547150397Sobrien		    && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
547250397Sobrien			< GET_MODE_SIZE (GET_MODE (SUBREG_REG (p->exp))))))
547350397Sobrien	    continue;
547450397Sobrien
547590075Sobrien	  if (src && GET_CODE (src) == code && rtx_equal_p (src, p->exp))
547618334Speter	    src = 0;
547790075Sobrien	  else if (src_folded && GET_CODE (src_folded) == code
547818334Speter		   && rtx_equal_p (src_folded, p->exp))
547918334Speter	    src_folded = 0;
548090075Sobrien	  else if (src_eqv_here && GET_CODE (src_eqv_here) == code
548118334Speter		   && rtx_equal_p (src_eqv_here, p->exp))
548218334Speter	    src_eqv_here = 0;
548390075Sobrien	  else if (src_related && GET_CODE (src_related) == code
548418334Speter		   && rtx_equal_p (src_related, p->exp))
548518334Speter	    src_related = 0;
548618334Speter
548718334Speter	  /* This is the same as the destination of the insns, we want
548818334Speter	     to prefer it.  Copy it to src_related.  The code below will
548918334Speter	     then give it a negative cost.  */
549018334Speter	  if (GET_CODE (dest) == code && rtx_equal_p (p->exp, dest))
549118334Speter	    src_related = dest;
549290075Sobrien	}
549318334Speter
549418334Speter      /* Find the cheapest valid equivalent, trying all the available
549518334Speter         possibilities.  Prefer items not in the hash table to ones
549618334Speter         that are when they are equal cost.  Note that we can never
549718334Speter         worsen an insn as the current contents will also succeed.
549818334Speter	 If we find an equivalent identical to the destination, use it as best,
549950397Sobrien	 since this insn will probably be eliminated in that case.  */
550018334Speter      if (src)
550118334Speter	{
550218334Speter	  if (rtx_equal_p (src, dest))
550390075Sobrien	    src_cost = src_regcost = -1;
550418334Speter	  else
550590075Sobrien	    {
550690075Sobrien	      src_cost = COST (src);
550790075Sobrien	      src_regcost = approx_reg_cost (src);
550890075Sobrien	    }
550918334Speter	}
551018334Speter
551118334Speter      if (src_eqv_here)
551218334Speter	{
551318334Speter	  if (rtx_equal_p (src_eqv_here, dest))
551490075Sobrien	    src_eqv_cost = src_eqv_regcost = -1;
551518334Speter	  else
551690075Sobrien	    {
551790075Sobrien	      src_eqv_cost = COST (src_eqv_here);
551890075Sobrien	      src_eqv_regcost = approx_reg_cost (src_eqv_here);
551990075Sobrien	    }
552018334Speter	}
552118334Speter
552218334Speter      if (src_folded)
552318334Speter	{
552418334Speter	  if (rtx_equal_p (src_folded, dest))
552590075Sobrien	    src_folded_cost = src_folded_regcost = -1;
552618334Speter	  else
552790075Sobrien	    {
552890075Sobrien	      src_folded_cost = COST (src_folded);
552990075Sobrien	      src_folded_regcost = approx_reg_cost (src_folded);
553090075Sobrien	    }
553118334Speter	}
553218334Speter
553318334Speter      if (src_related)
553418334Speter	{
553518334Speter	  if (rtx_equal_p (src_related, dest))
553690075Sobrien	    src_related_cost = src_related_regcost = -1;
553718334Speter	  else
553890075Sobrien	    {
553990075Sobrien	      src_related_cost = COST (src_related);
554090075Sobrien	      src_related_regcost = approx_reg_cost (src_related);
554190075Sobrien	    }
554218334Speter	}
554318334Speter
554418334Speter      /* If this was an indirect jump insn, a known label will really be
554518334Speter	 cheaper even though it looks more expensive.  */
554618334Speter      if (dest == pc_rtx && src_const && GET_CODE (src_const) == LABEL_REF)
554790075Sobrien	src_folded = src_const, src_folded_cost = src_folded_regcost = -1;
554890075Sobrien
554918334Speter      /* Terminate loop when replacement made.  This must terminate since
555018334Speter         the current contents will be tested and will always be valid.  */
555118334Speter      while (1)
555290075Sobrien	{
555390075Sobrien	  rtx trial;
555418334Speter
555590075Sobrien	  /* Skip invalid entries.  */
5556169689Skan	  while (elt && !REG_P (elt->exp)
5557169689Skan		 && ! exp_equiv_p (elt->exp, elt->exp, 1, false))
555890075Sobrien	    elt = elt->next_same_value;
555950397Sobrien
556050397Sobrien	  /* A paradoxical subreg would be bad here: it'll be the right
556150397Sobrien	     size, but later may be adjusted so that the upper bits aren't
556250397Sobrien	     what we want.  So reject it.  */
556350397Sobrien	  if (elt != 0
556450397Sobrien	      && GET_CODE (elt->exp) == SUBREG
556550397Sobrien	      && (GET_MODE_SIZE (GET_MODE (elt->exp))
556650397Sobrien		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (elt->exp))))
556750397Sobrien	      /* It is okay, though, if the rtx we're trying to match
556850397Sobrien		 will ignore any of the bits we can't predict.  */
556950397Sobrien	      && ! (src != 0
557050397Sobrien		    && GET_CODE (src) == SUBREG
557150397Sobrien		    && GET_MODE (src) == GET_MODE (elt->exp)
557250397Sobrien		    && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
557350397Sobrien			< GET_MODE_SIZE (GET_MODE (SUBREG_REG (elt->exp))))))
557450397Sobrien	    {
557550397Sobrien	      elt = elt->next_same_value;
557650397Sobrien	      continue;
557750397Sobrien	    }
557818334Speter
5579117395Skan	  if (elt)
558090075Sobrien	    {
558190075Sobrien	      src_elt_cost = elt->cost;
558290075Sobrien	      src_elt_regcost = elt->regcost;
558390075Sobrien	    }
558490075Sobrien
5585117395Skan	  /* Find cheapest and skip it for the next time.   For items
558618334Speter	     of equal cost, use this order:
558718334Speter	     src_folded, src, src_eqv, src_related and hash table entry.  */
558890075Sobrien	  if (src_folded
5589169689Skan	      && preferable (src_folded_cost, src_folded_regcost,
5590169689Skan			     src_cost, src_regcost) <= 0
5591169689Skan	      && preferable (src_folded_cost, src_folded_regcost,
5592169689Skan			     src_eqv_cost, src_eqv_regcost) <= 0
5593169689Skan	      && preferable (src_folded_cost, src_folded_regcost,
5594169689Skan			     src_related_cost, src_related_regcost) <= 0
5595169689Skan	      && preferable (src_folded_cost, src_folded_regcost,
5596169689Skan			     src_elt_cost, src_elt_regcost) <= 0)
559718334Speter	    {
559890075Sobrien	      trial = src_folded, src_folded_cost = MAX_COST;
559918334Speter	      if (src_folded_force_flag)
5600132718Skan		{
5601132718Skan		  rtx forced = force_const_mem (mode, trial);
5602132718Skan		  if (forced)
5603132718Skan		    trial = forced;
5604132718Skan		}
560518334Speter	    }
560690075Sobrien	  else if (src
5607169689Skan		   && preferable (src_cost, src_regcost,
5608169689Skan				  src_eqv_cost, src_eqv_regcost) <= 0
5609169689Skan		   && preferable (src_cost, src_regcost,
5610169689Skan				  src_related_cost, src_related_regcost) <= 0
5611169689Skan		   && preferable (src_cost, src_regcost,
5612169689Skan				  src_elt_cost, src_elt_regcost) <= 0)
561390075Sobrien	    trial = src, src_cost = MAX_COST;
561490075Sobrien	  else if (src_eqv_here
5615169689Skan		   && preferable (src_eqv_cost, src_eqv_regcost,
5616169689Skan				  src_related_cost, src_related_regcost) <= 0
5617169689Skan		   && preferable (src_eqv_cost, src_eqv_regcost,
5618169689Skan				  src_elt_cost, src_elt_regcost) <= 0)
561990075Sobrien	    trial = copy_rtx (src_eqv_here), src_eqv_cost = MAX_COST;
562090075Sobrien	  else if (src_related
5621169689Skan		   && preferable (src_related_cost, src_related_regcost,
5622169689Skan				  src_elt_cost, src_elt_regcost) <= 0)
5623117395Skan	    trial = copy_rtx (src_related), src_related_cost = MAX_COST;
562490075Sobrien	  else
562518334Speter	    {
562618334Speter	      trial = copy_rtx (elt->exp);
562718334Speter	      elt = elt->next_same_value;
562890075Sobrien	      src_elt_cost = MAX_COST;
562918334Speter	    }
563018334Speter
563118334Speter	  /* We don't normally have an insn matching (set (pc) (pc)), so
563218334Speter	     check for this separately here.  We will delete such an
563318334Speter	     insn below.
563418334Speter
563590075Sobrien	     For other cases such as a table jump or conditional jump
563690075Sobrien	     where we know the ultimate target, go ahead and replace the
563790075Sobrien	     operand.  While that may not make a valid insn, we will
563890075Sobrien	     reemit the jump below (and also insert any necessary
563990075Sobrien	     barriers).  */
564018334Speter	  if (n_sets == 1 && dest == pc_rtx
564118334Speter	      && (trial == pc_rtx
564218334Speter		  || (GET_CODE (trial) == LABEL_REF
564318334Speter		      && ! condjump_p (insn))))
564418334Speter	    {
5645169689Skan	      /* Don't substitute non-local labels, this confuses CFG.  */
5646169689Skan	      if (GET_CODE (trial) == LABEL_REF
5647169689Skan		  && LABEL_REF_NONLOCAL_P (trial))
5648169689Skan		continue;
5649169689Skan
565018334Speter	      SET_SRC (sets[i].rtl) = trial;
565190075Sobrien	      cse_jumps_altered = 1;
565218334Speter	      break;
565318334Speter	    }
565490075Sobrien
5655169689Skan	  /* Reject certain invalid forms of CONST that we create.  */
5656169689Skan	  else if (CONSTANT_P (trial)
5657169689Skan		   && GET_CODE (trial) == CONST
5658169689Skan		   /* Reject cases that will cause decode_rtx_const to
5659169689Skan		      die.  On the alpha when simplifying a switch, we
5660169689Skan		      get (const (truncate (minus (label_ref)
5661169689Skan		      (label_ref)))).  */
5662169689Skan		   && (GET_CODE (XEXP (trial, 0)) == TRUNCATE
5663169689Skan		       /* Likewise on IA-64, except without the
5664169689Skan			  truncate.  */
5665169689Skan		       || (GET_CODE (XEXP (trial, 0)) == MINUS
5666169689Skan			   && GET_CODE (XEXP (XEXP (trial, 0), 0)) == LABEL_REF
5667169689Skan			   && GET_CODE (XEXP (XEXP (trial, 0), 1)) == LABEL_REF)))
5668169689Skan	    /* Do nothing for this case.  */
5669169689Skan	    ;
5670169689Skan
567118334Speter	  /* Look for a substitution that makes a valid insn.  */
567290075Sobrien	  else if (validate_change (insn, &SET_SRC (sets[i].rtl), trial, 0))
567318334Speter	    {
5674132718Skan	      rtx new = canon_reg (SET_SRC (sets[i].rtl), insn);
5675132718Skan
567650397Sobrien	      /* If we just made a substitution inside a libcall, then we
567750397Sobrien		 need to make the same substitution in any notes attached
567850397Sobrien		 to the RETVAL insn.  */
567950397Sobrien	      if (libcall_insn
5680169689Skan		  && (REG_P (sets[i].orig_src)
568190075Sobrien		      || GET_CODE (sets[i].orig_src) == SUBREG
5682169689Skan		      || MEM_P (sets[i].orig_src)))
5683169689Skan		{
5684169689Skan	          rtx note = find_reg_equal_equiv_note (libcall_insn);
5685169689Skan		  if (note != 0)
5686169689Skan		    XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0),
5687169689Skan							   sets[i].orig_src,
5688169689Skan							   copy_rtx (new));
5689169689Skan		}
569050397Sobrien
569118334Speter	      /* The result of apply_change_group can be ignored; see
569218334Speter		 canon_reg.  */
569318334Speter
5694132718Skan	      validate_change (insn, &SET_SRC (sets[i].rtl), new, 1);
569518334Speter	      apply_change_group ();
569618334Speter	      break;
569718334Speter	    }
569818334Speter
569990075Sobrien	  /* If we previously found constant pool entries for
570018334Speter	     constants and this is a constant, try making a
570118334Speter	     pool entry.  Put it in src_folded unless we already have done
570218334Speter	     this since that is where it likely came from.  */
570318334Speter
570418334Speter	  else if (constant_pool_entries_cost
570518334Speter		   && CONSTANT_P (trial)
570618334Speter		   && (src_folded == 0
5707169689Skan		       || (!MEM_P (src_folded)
570818334Speter			   && ! src_folded_force_flag))
570950397Sobrien		   && GET_MODE_CLASS (mode) != MODE_CC
571050397Sobrien		   && mode != VOIDmode)
571118334Speter	    {
571218334Speter	      src_folded_force_flag = 1;
571318334Speter	      src_folded = trial;
571418334Speter	      src_folded_cost = constant_pool_entries_cost;
5715132718Skan	      src_folded_regcost = constant_pool_entries_regcost;
571618334Speter	    }
571790075Sobrien	}
571818334Speter
571918334Speter      src = SET_SRC (sets[i].rtl);
572018334Speter
572118334Speter      /* In general, it is good to have a SET with SET_SRC == SET_DEST.
572218334Speter	 However, there is an important exception:  If both are registers
572318334Speter	 that are not the head of their equivalence class, replace SET_SRC
572418334Speter	 with the head of the class.  If we do not do this, we will have
572518334Speter	 both registers live over a portion of the basic block.  This way,
572618334Speter	 their lifetimes will likely abut instead of overlapping.  */
5727169689Skan      if (REG_P (dest)
572890075Sobrien	  && REGNO_QTY_VALID_P (REGNO (dest)))
572918334Speter	{
573090075Sobrien	  int dest_q = REG_QTY (REGNO (dest));
573190075Sobrien	  struct qty_table_elem *dest_ent = &qty_table[dest_q];
573218334Speter
573390075Sobrien	  if (dest_ent->mode == GET_MODE (dest)
573490075Sobrien	      && dest_ent->first_reg != REGNO (dest)
5735169689Skan	      && REG_P (src) && REGNO (src) == REGNO (dest)
573690075Sobrien	      /* Don't do this if the original insn had a hard reg as
573790075Sobrien		 SET_SRC or SET_DEST.  */
5738169689Skan	      && (!REG_P (sets[i].src)
573990075Sobrien		  || REGNO (sets[i].src) >= FIRST_PSEUDO_REGISTER)
5740169689Skan	      && (!REG_P (dest) || REGNO (dest) >= FIRST_PSEUDO_REGISTER))
574190075Sobrien	    /* We can't call canon_reg here because it won't do anything if
574290075Sobrien	       SRC is a hard register.  */
574350397Sobrien	    {
574490075Sobrien	      int src_q = REG_QTY (REGNO (src));
574590075Sobrien	      struct qty_table_elem *src_ent = &qty_table[src_q];
574690075Sobrien	      int first = src_ent->first_reg;
574790075Sobrien	      rtx new_src
574890075Sobrien		= (first >= FIRST_PSEUDO_REGISTER
574990075Sobrien		   ? regno_reg_rtx[first] : gen_rtx_REG (GET_MODE (src), first));
575090075Sobrien
575190075Sobrien	      /* We must use validate-change even for this, because this
575290075Sobrien		 might be a special no-op instruction, suitable only to
575390075Sobrien		 tag notes onto.  */
575490075Sobrien	      if (validate_change (insn, &SET_SRC (sets[i].rtl), new_src, 0))
575590075Sobrien		{
575690075Sobrien		  src = new_src;
575790075Sobrien		  /* If we had a constant that is cheaper than what we are now
575890075Sobrien		     setting SRC to, use that constant.  We ignored it when we
575990075Sobrien		     thought we could make this into a no-op.  */
576090075Sobrien		  if (src_const && COST (src_const) < COST (src)
576190075Sobrien		      && validate_change (insn, &SET_SRC (sets[i].rtl),
576290075Sobrien					  src_const, 0))
576390075Sobrien		    src = src_const;
576490075Sobrien		}
576550397Sobrien	    }
576618334Speter	}
576718334Speter
576818334Speter      /* If we made a change, recompute SRC values.  */
576918334Speter      if (src != sets[i].src)
577090075Sobrien	{
577190075Sobrien	  cse_altered = 1;
577290075Sobrien	  do_not_record = 0;
577390075Sobrien	  hash_arg_in_memory = 0;
577418334Speter	  sets[i].src = src;
577590075Sobrien	  sets[i].src_hash = HASH (src, mode);
577690075Sobrien	  sets[i].src_volatile = do_not_record;
577790075Sobrien	  sets[i].src_in_memory = hash_arg_in_memory;
577890075Sobrien	  sets[i].src_elt = lookup (src, sets[i].src_hash, mode);
577990075Sobrien	}
578018334Speter
578118334Speter      /* If this is a single SET, we are setting a register, and we have an
578218334Speter	 equivalent constant, we want to add a REG_NOTE.   We don't want
578318334Speter	 to write a REG_EQUAL note for a constant pseudo since verifying that
578418334Speter	 that pseudo hasn't been eliminated is a pain.  Such a note also
578590075Sobrien	 won't help anything.
578650397Sobrien
578750397Sobrien	 Avoid a REG_EQUAL note for (CONST (MINUS (LABEL_REF) (LABEL_REF)))
578850397Sobrien	 which can be created for a reference to a compile time computable
578950397Sobrien	 entry in a jump table.  */
579050397Sobrien
5791169689Skan      if (n_sets == 1 && src_const && REG_P (dest)
5792169689Skan	  && !REG_P (src_const)
579350397Sobrien	  && ! (GET_CODE (src_const) == CONST
579450397Sobrien		&& GET_CODE (XEXP (src_const, 0)) == MINUS
579550397Sobrien		&& GET_CODE (XEXP (XEXP (src_const, 0), 0)) == LABEL_REF
579650397Sobrien		&& GET_CODE (XEXP (XEXP (src_const, 0), 1)) == LABEL_REF))
579718334Speter	{
5798132718Skan	  /* We only want a REG_EQUAL note if src_const != src.  */
5799132718Skan	  if (! rtx_equal_p (src, src_const))
580018334Speter	    {
5801132718Skan	      /* Make sure that the rtx is not shared.  */
5802132718Skan	      src_const = copy_rtx (src_const);
580318334Speter
5804132718Skan	      /* Record the actual constant value in a REG_EQUAL note,
5805132718Skan		 making a new one if one does not already exist.  */
5806132718Skan	      set_unique_reg_note (insn, REG_EQUAL, src_const);
580718334Speter	    }
580818334Speter	}
580918334Speter
581018334Speter      /* Now deal with the destination.  */
581118334Speter      do_not_record = 0;
581218334Speter
5813169689Skan      /* Look within any ZERO_EXTRACT to the MEM or REG within it.  */
5814169689Skan      while (GET_CODE (dest) == SUBREG
581518334Speter	     || GET_CODE (dest) == ZERO_EXTRACT
581618334Speter	     || GET_CODE (dest) == STRICT_LOW_PART)
581790075Sobrien	dest = XEXP (dest, 0);
581818334Speter
581918334Speter      sets[i].inner_dest = dest;
582018334Speter
5821169689Skan      if (MEM_P (dest))
582218334Speter	{
582350397Sobrien#ifdef PUSH_ROUNDING
582450397Sobrien	  /* Stack pushes invalidate the stack pointer.  */
582550397Sobrien	  rtx addr = XEXP (dest, 0);
5826169689Skan	  if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC
582750397Sobrien	      && XEXP (addr, 0) == stack_pointer_rtx)
5828169689Skan	    invalidate (stack_pointer_rtx, VOIDmode);
582950397Sobrien#endif
583018334Speter	  dest = fold_rtx (dest, insn);
583118334Speter	}
583218334Speter
583318334Speter      /* Compute the hash code of the destination now,
583418334Speter	 before the effects of this instruction are recorded,
583518334Speter	 since the register values used in the address computation
583618334Speter	 are those before this instruction.  */
583718334Speter      sets[i].dest_hash = HASH (dest, mode);
583818334Speter
583918334Speter      /* Don't enter a bit-field in the hash table
584018334Speter	 because the value in it after the store
584118334Speter	 may not equal what was stored, due to truncation.  */
584218334Speter
5843169689Skan      if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT)
584418334Speter	{
584518334Speter	  rtx width = XEXP (SET_DEST (sets[i].rtl), 1);
584618334Speter
584718334Speter	  if (src_const != 0 && GET_CODE (src_const) == CONST_INT
584818334Speter	      && GET_CODE (width) == CONST_INT
584918334Speter	      && INTVAL (width) < HOST_BITS_PER_WIDE_INT
585018334Speter	      && ! (INTVAL (src_const)
585118334Speter		    & ((HOST_WIDE_INT) (-1) << INTVAL (width))))
585218334Speter	    /* Exception: if the value is constant,
585318334Speter	       and it won't be truncated, record it.  */
585418334Speter	    ;
585518334Speter	  else
585618334Speter	    {
585718334Speter	      /* This is chosen so that the destination will be invalidated
585818334Speter		 but no new value will be recorded.
585918334Speter		 We must invalidate because sometimes constant
586018334Speter		 values can be recorded for bitfields.  */
586118334Speter	      sets[i].src_elt = 0;
586218334Speter	      sets[i].src_volatile = 1;
586318334Speter	      src_eqv = 0;
586418334Speter	      src_eqv_elt = 0;
586518334Speter	    }
586618334Speter	}
586718334Speter
586818334Speter      /* If only one set in a JUMP_INSN and it is now a no-op, we can delete
586918334Speter	 the insn.  */
587018334Speter      else if (n_sets == 1 && dest == pc_rtx && src == pc_rtx)
587118334Speter	{
587290075Sobrien	  /* One less use of the label this insn used to jump to.  */
587390075Sobrien	  delete_insn (insn);
587418334Speter	  cse_jumps_altered = 1;
587518334Speter	  /* No more processing for this set.  */
587618334Speter	  sets[i].rtl = 0;
587718334Speter	}
587818334Speter
587918334Speter      /* If this SET is now setting PC to a label, we know it used to
588090075Sobrien	 be a conditional or computed branch.  */
5881169689Skan      else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF
5882169689Skan	       && !LABEL_REF_NONLOCAL_P (src))
588318334Speter	{
588490075Sobrien	  /* Now emit a BARRIER after the unconditional jump.  */
588590075Sobrien	  if (NEXT_INSN (insn) == 0
5886169689Skan	      || !BARRIER_P (NEXT_INSN (insn)))
588790075Sobrien	    emit_barrier_after (insn);
588818334Speter
588990075Sobrien	  /* We reemit the jump in as many cases as possible just in
589090075Sobrien	     case the form of an unconditional jump is significantly
589190075Sobrien	     different than a computed jump or conditional jump.
589290075Sobrien
589390075Sobrien	     If this insn has multiple sets, then reemitting the
589490075Sobrien	     jump is nontrivial.  So instead we just force rerecognition
589590075Sobrien	     and hope for the best.  */
589690075Sobrien	  if (n_sets == 1)
589718334Speter	    {
5898169689Skan	      rtx new, note;
589990075Sobrien
5900169689Skan	      new = emit_jump_insn_after (gen_jump (XEXP (src, 0)), insn);
590118334Speter	      JUMP_LABEL (new) = XEXP (src, 0);
590218334Speter	      LABEL_NUSES (XEXP (src, 0))++;
5903169689Skan
5904169689Skan	      /* Make sure to copy over REG_NON_LOCAL_GOTO.  */
5905169689Skan	      note = find_reg_note (insn, REG_NON_LOCAL_GOTO, 0);
5906169689Skan	      if (note)
5907169689Skan		{
5908169689Skan		  XEXP (note, 1) = NULL_RTX;
5909169689Skan		  REG_NOTES (new) = note;
5910169689Skan		}
5911169689Skan
5912117395Skan	      delete_insn (insn);
591318334Speter	      insn = new;
591490075Sobrien
591590075Sobrien	      /* Now emit a BARRIER after the unconditional jump.  */
591690075Sobrien	      if (NEXT_INSN (insn) == 0
5917169689Skan		  || !BARRIER_P (NEXT_INSN (insn)))
591890075Sobrien		emit_barrier_after (insn);
591918334Speter	    }
592018334Speter	  else
592118334Speter	    INSN_CODE (insn) = -1;
592218334Speter
592390075Sobrien	  /* Do not bother deleting any unreachable code,
592490075Sobrien	     let jump/flow do that.  */
592590075Sobrien
592618334Speter	  cse_jumps_altered = 1;
592718334Speter	  sets[i].rtl = 0;
592818334Speter	}
592918334Speter
593018334Speter      /* If destination is volatile, invalidate it and then do no further
593118334Speter	 processing for this assignment.  */
593218334Speter
593318334Speter      else if (do_not_record)
593418334Speter	{
5935169689Skan	  if (REG_P (dest) || GET_CODE (dest) == SUBREG)
593618334Speter	    invalidate (dest, VOIDmode);
5937169689Skan	  else if (MEM_P (dest))
5938169689Skan	    invalidate (dest, VOIDmode);
593918334Speter	  else if (GET_CODE (dest) == STRICT_LOW_PART
594018334Speter		   || GET_CODE (dest) == ZERO_EXTRACT)
594118334Speter	    invalidate (XEXP (dest, 0), GET_MODE (dest));
594218334Speter	  sets[i].rtl = 0;
594318334Speter	}
594418334Speter
594518334Speter      if (sets[i].rtl != 0 && dest != SET_DEST (sets[i].rtl))
594618334Speter	sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode);
594718334Speter
594818334Speter#ifdef HAVE_cc0
594918334Speter      /* If setting CC0, record what it was set to, or a constant, if it
595018334Speter	 is equivalent to a constant.  If it is being set to a floating-point
595118334Speter	 value, make a COMPARE with the appropriate constant of 0.  If we
595218334Speter	 don't do this, later code can interpret this as a test against
595318334Speter	 const0_rtx, which can cause problems if we try to put it into an
595418334Speter	 insn as a floating-point operand.  */
595518334Speter      if (dest == cc0_rtx)
595618334Speter	{
595718334Speter	  this_insn_cc0 = src_const && mode != VOIDmode ? src_const : src;
595818334Speter	  this_insn_cc0_mode = mode;
595918334Speter	  if (FLOAT_MODE_P (mode))
596050397Sobrien	    this_insn_cc0 = gen_rtx_COMPARE (VOIDmode, this_insn_cc0,
596150397Sobrien					     CONST0_RTX (mode));
596218334Speter	}
596318334Speter#endif
596418334Speter    }
596518334Speter
596618334Speter  /* Now enter all non-volatile source expressions in the hash table
596718334Speter     if they are not already present.
596818334Speter     Record their equivalence classes in src_elt.
596918334Speter     This way we can insert the corresponding destinations into
597018334Speter     the same classes even if the actual sources are no longer in them
597118334Speter     (having been invalidated).  */
597218334Speter
597318334Speter  if (src_eqv && src_eqv_elt == 0 && sets[0].rtl != 0 && ! src_eqv_volatile
597418334Speter      && ! rtx_equal_p (src_eqv, SET_DEST (sets[0].rtl)))
597518334Speter    {
597690075Sobrien      struct table_elt *elt;
597790075Sobrien      struct table_elt *classp = sets[0].src_elt;
597818334Speter      rtx dest = SET_DEST (sets[0].rtl);
597918334Speter      enum machine_mode eqvmode = GET_MODE (dest);
598018334Speter
598118334Speter      if (GET_CODE (dest) == STRICT_LOW_PART)
598218334Speter	{
598318334Speter	  eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
598418334Speter	  classp = 0;
598518334Speter	}
598618334Speter      if (insert_regs (src_eqv, classp, 0))
598718334Speter	{
598818334Speter	  rehash_using_reg (src_eqv);
598918334Speter	  src_eqv_hash = HASH (src_eqv, eqvmode);
599018334Speter	}
599118334Speter      elt = insert (src_eqv, classp, src_eqv_hash, eqvmode);
599218334Speter      elt->in_memory = src_eqv_in_memory;
599318334Speter      src_eqv_elt = elt;
599418334Speter
599518334Speter      /* Check to see if src_eqv_elt is the same as a set source which
599618334Speter	 does not yet have an elt, and if so set the elt of the set source
599718334Speter	 to src_eqv_elt.  */
599818334Speter      for (i = 0; i < n_sets; i++)
599918334Speter	if (sets[i].rtl && sets[i].src_elt == 0
600018334Speter	    && rtx_equal_p (SET_SRC (sets[i].rtl), src_eqv))
600118334Speter	  sets[i].src_elt = src_eqv_elt;
600218334Speter    }
600318334Speter
600418334Speter  for (i = 0; i < n_sets; i++)
600518334Speter    if (sets[i].rtl && ! sets[i].src_volatile
600618334Speter	&& ! rtx_equal_p (SET_SRC (sets[i].rtl), SET_DEST (sets[i].rtl)))
600718334Speter      {
600818334Speter	if (GET_CODE (SET_DEST (sets[i].rtl)) == STRICT_LOW_PART)
600918334Speter	  {
601018334Speter	    /* REG_EQUAL in setting a STRICT_LOW_PART
601118334Speter	       gives an equivalent for the entire destination register,
601218334Speter	       not just for the subreg being stored in now.
601318334Speter	       This is a more interesting equivalence, so we arrange later
601418334Speter	       to treat the entire reg as the destination.  */
601518334Speter	    sets[i].src_elt = src_eqv_elt;
601618334Speter	    sets[i].src_hash = src_eqv_hash;
601718334Speter	  }
601818334Speter	else
601918334Speter	  {
602018334Speter	    /* Insert source and constant equivalent into hash table, if not
602118334Speter	       already present.  */
602290075Sobrien	    struct table_elt *classp = src_eqv_elt;
602390075Sobrien	    rtx src = sets[i].src;
602490075Sobrien	    rtx dest = SET_DEST (sets[i].rtl);
602518334Speter	    enum machine_mode mode
602618334Speter	      = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src);
602718334Speter
6028132718Skan	    /* It's possible that we have a source value known to be
6029132718Skan	       constant but don't have a REG_EQUAL note on the insn.
6030132718Skan	       Lack of a note will mean src_eqv_elt will be NULL.  This
6031132718Skan	       can happen where we've generated a SUBREG to access a
6032132718Skan	       CONST_INT that is already in a register in a wider mode.
6033132718Skan	       Ensure that the source expression is put in the proper
6034132718Skan	       constant class.  */
6035132718Skan	    if (!classp)
6036132718Skan	      classp = sets[i].src_const_elt;
6037132718Skan
603890075Sobrien	    if (sets[i].src_elt == 0)
603918334Speter	      {
604090075Sobrien		/* Don't put a hard register source into the table if this is
604190075Sobrien		   the last insn of a libcall.  In this case, we only need
604290075Sobrien		   to put src_eqv_elt in src_elt.  */
604390075Sobrien		if (! find_reg_note (insn, REG_RETVAL, NULL_RTX))
604490075Sobrien		  {
604590075Sobrien		    struct table_elt *elt;
604618334Speter
604790075Sobrien		    /* Note that these insert_regs calls cannot remove
604890075Sobrien		       any of the src_elt's, because they would have failed to
604990075Sobrien		       match if not still valid.  */
605090075Sobrien		    if (insert_regs (src, classp, 0))
605190075Sobrien		      {
605290075Sobrien			rehash_using_reg (src);
605390075Sobrien			sets[i].src_hash = HASH (src, mode);
605490075Sobrien		      }
605590075Sobrien		    elt = insert (src, classp, sets[i].src_hash, mode);
605690075Sobrien		    elt->in_memory = sets[i].src_in_memory;
605790075Sobrien		    sets[i].src_elt = classp = elt;
605818334Speter		  }
605990075Sobrien		else
606090075Sobrien		  sets[i].src_elt = classp;
606118334Speter	      }
606218334Speter	    if (sets[i].src_const && sets[i].src_const_elt == 0
606318334Speter		&& src != sets[i].src_const
606418334Speter		&& ! rtx_equal_p (sets[i].src_const, src))
606518334Speter	      sets[i].src_elt = insert (sets[i].src_const, classp,
606618334Speter					sets[i].src_const_hash, mode);
606718334Speter	  }
606818334Speter      }
606918334Speter    else if (sets[i].src_elt == 0)
607018334Speter      /* If we did not insert the source into the hash table (e.g., it was
607118334Speter	 volatile), note the equivalence class for the REG_EQUAL value, if any,
607218334Speter	 so that the destination goes into that class.  */
607318334Speter      sets[i].src_elt = src_eqv_elt;
607418334Speter
6075169689Skan  /* Record destination addresses in the hash table.  This allows us to
6076169689Skan     check if they are invalidated by other sets.  */
6077169689Skan  for (i = 0; i < n_sets; i++)
6078169689Skan    {
6079169689Skan      if (sets[i].rtl)
6080169689Skan	{
6081169689Skan	  rtx x = sets[i].inner_dest;
6082169689Skan	  struct table_elt *elt;
6083169689Skan	  enum machine_mode mode;
6084169689Skan	  unsigned hash;
6085169689Skan
6086169689Skan	  if (MEM_P (x))
6087169689Skan	    {
6088169689Skan	      x = XEXP (x, 0);
6089169689Skan	      mode = GET_MODE (x);
6090169689Skan	      hash = HASH (x, mode);
6091169689Skan	      elt = lookup (x, hash, mode);
6092169689Skan	      if (!elt)
6093169689Skan		{
6094169689Skan		  if (insert_regs (x, NULL, 0))
6095169689Skan		    {
6096169689Skan		      rtx dest = SET_DEST (sets[i].rtl);
6097169689Skan
6098169689Skan		      rehash_using_reg (x);
6099169689Skan		      hash = HASH (x, mode);
6100169689Skan		      sets[i].dest_hash = HASH (dest, GET_MODE (dest));
6101169689Skan		    }
6102169689Skan		  elt = insert (x, NULL, hash, mode);
6103169689Skan		}
6104169689Skan
6105169689Skan	      sets[i].dest_addr_elt = elt;
6106169689Skan	    }
6107169689Skan	  else
6108169689Skan	    sets[i].dest_addr_elt = NULL;
6109169689Skan	}
6110169689Skan    }
6111169689Skan
611250397Sobrien  invalidate_from_clobbers (x);
611318334Speter
611490075Sobrien  /* Some registers are invalidated by subroutine calls.  Memory is
611518334Speter     invalidated by non-constant calls.  */
611618334Speter
6117169689Skan  if (CALL_P (insn))
611818334Speter    {
611990075Sobrien      if (! CONST_OR_PURE_CALL_P (insn))
612050397Sobrien	invalidate_memory ();
612118334Speter      invalidate_for_call ();
612218334Speter    }
612318334Speter
612418334Speter  /* Now invalidate everything set by this instruction.
612518334Speter     If a SUBREG or other funny destination is being set,
612618334Speter     sets[i].rtl is still nonzero, so here we invalidate the reg
612718334Speter     a part of which is being set.  */
612818334Speter
612918334Speter  for (i = 0; i < n_sets; i++)
613018334Speter    if (sets[i].rtl)
613118334Speter      {
613218334Speter	/* We can't use the inner dest, because the mode associated with
613318334Speter	   a ZERO_EXTRACT is significant.  */
613490075Sobrien	rtx dest = SET_DEST (sets[i].rtl);
613518334Speter
613618334Speter	/* Needed for registers to remove the register from its
613718334Speter	   previous quantity's chain.
613818334Speter	   Needed for memory if this is a nonvarying address, unless
613918334Speter	   we have just done an invalidate_memory that covers even those.  */
6140169689Skan	if (REG_P (dest) || GET_CODE (dest) == SUBREG)
614118334Speter	  invalidate (dest, VOIDmode);
6142169689Skan	else if (MEM_P (dest))
6143169689Skan	  invalidate (dest, VOIDmode);
614418334Speter	else if (GET_CODE (dest) == STRICT_LOW_PART
614518334Speter		 || GET_CODE (dest) == ZERO_EXTRACT)
614618334Speter	  invalidate (XEXP (dest, 0), GET_MODE (dest));
614718334Speter      }
614818334Speter
614952284Sobrien  /* A volatile ASM invalidates everything.  */
6150169689Skan  if (NONJUMP_INSN_P (insn)
615152284Sobrien      && GET_CODE (PATTERN (insn)) == ASM_OPERANDS
615252284Sobrien      && MEM_VOLATILE_P (PATTERN (insn)))
615352284Sobrien    flush_hash_table ();
615452284Sobrien
615518334Speter  /* Make sure registers mentioned in destinations
615618334Speter     are safe for use in an expression to be inserted.
615718334Speter     This removes from the hash table
615818334Speter     any invalid entry that refers to one of these registers.
615918334Speter
616018334Speter     We don't care about the return value from mention_regs because
616118334Speter     we are going to hash the SET_DEST values unconditionally.  */
616218334Speter
616318334Speter  for (i = 0; i < n_sets; i++)
616452284Sobrien    {
616552284Sobrien      if (sets[i].rtl)
616652284Sobrien	{
616752284Sobrien	  rtx x = SET_DEST (sets[i].rtl);
616818334Speter
6169169689Skan	  if (!REG_P (x))
617052284Sobrien	    mention_regs (x);
617152284Sobrien	  else
617252284Sobrien	    {
617352284Sobrien	      /* We used to rely on all references to a register becoming
617452284Sobrien		 inaccessible when a register changes to a new quantity,
617552284Sobrien		 since that changes the hash code.  However, that is not
617690075Sobrien		 safe, since after HASH_SIZE new quantities we get a
617752284Sobrien		 hash 'collision' of a register with its own invalid
617852284Sobrien		 entries.  And since SUBREGs have been changed not to
617952284Sobrien		 change their hash code with the hash code of the register,
618052284Sobrien		 it wouldn't work any longer at all.  So we have to check
618152284Sobrien		 for any invalid references lying around now.
618252284Sobrien		 This code is similar to the REG case in mention_regs,
618352284Sobrien		 but it knows that reg_tick has been incremented, and
618452284Sobrien		 it leaves reg_in_table as -1 .  */
618590075Sobrien	      unsigned int regno = REGNO (x);
618690075Sobrien	      unsigned int endregno
618752284Sobrien		= regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
6188169689Skan			   : hard_regno_nregs[regno][GET_MODE (x)]);
618990075Sobrien	      unsigned int i;
619052284Sobrien
619152284Sobrien	      for (i = regno; i < endregno; i++)
619252284Sobrien		{
619352284Sobrien		  if (REG_IN_TABLE (i) >= 0)
619452284Sobrien		    {
619552284Sobrien		      remove_invalid_refs (i);
619652284Sobrien		      REG_IN_TABLE (i) = -1;
619752284Sobrien		    }
619852284Sobrien		}
619952284Sobrien	    }
620052284Sobrien	}
620152284Sobrien    }
620252284Sobrien
620318334Speter  /* We may have just removed some of the src_elt's from the hash table.
6204169689Skan     So replace each one with the current head of the same class.
6205169689Skan     Also check if destination addresses have been removed.  */
620618334Speter
620718334Speter  for (i = 0; i < n_sets; i++)
620818334Speter    if (sets[i].rtl)
620918334Speter      {
6210169689Skan	if (sets[i].dest_addr_elt
6211169689Skan	    && sets[i].dest_addr_elt->first_same_value == 0)
6212169689Skan	  {
6213169689Skan	    /* The elt was removed, which means this destination is not
6214169689Skan	       valid after this instruction.  */
6215169689Skan	    sets[i].rtl = NULL_RTX;
6216169689Skan	  }
6217169689Skan	else if (sets[i].src_elt && sets[i].src_elt->first_same_value == 0)
621818334Speter	  /* If elt was removed, find current head of same class,
621918334Speter	     or 0 if nothing remains of that class.  */
622018334Speter	  {
622190075Sobrien	    struct table_elt *elt = sets[i].src_elt;
622218334Speter
622318334Speter	    while (elt && elt->prev_same_value)
622418334Speter	      elt = elt->prev_same_value;
622518334Speter
622618334Speter	    while (elt && elt->first_same_value == 0)
622718334Speter	      elt = elt->next_same_value;
622818334Speter	    sets[i].src_elt = elt ? elt->first_same_value : 0;
622918334Speter	  }
623018334Speter      }
623118334Speter
623218334Speter  /* Now insert the destinations into their equivalence classes.  */
623318334Speter
623418334Speter  for (i = 0; i < n_sets; i++)
623518334Speter    if (sets[i].rtl)
623618334Speter      {
623790075Sobrien	rtx dest = SET_DEST (sets[i].rtl);
623890075Sobrien	struct table_elt *elt;
623918334Speter
624018334Speter	/* Don't record value if we are not supposed to risk allocating
624118334Speter	   floating-point values in registers that might be wider than
624218334Speter	   memory.  */
624318334Speter	if ((flag_float_store
6244169689Skan	     && MEM_P (dest)
624518334Speter	     && FLOAT_MODE_P (GET_MODE (dest)))
624650397Sobrien	    /* Don't record BLKmode values, because we don't know the
624750397Sobrien	       size of it, and can't be sure that other BLKmode values
624850397Sobrien	       have the same or smaller size.  */
624950397Sobrien	    || GET_MODE (dest) == BLKmode
625018334Speter	    /* Don't record values of destinations set inside a libcall block
625118334Speter	       since we might delete the libcall.  Things should have been set
625218334Speter	       up so we won't want to reuse such a value, but we play it safe
625318334Speter	       here.  */
625450397Sobrien	    || libcall_insn
625518334Speter	    /* If we didn't put a REG_EQUAL value or a source into the hash
625618334Speter	       table, there is no point is recording DEST.  */
625718334Speter	    || sets[i].src_elt == 0
625818334Speter	    /* If DEST is a paradoxical SUBREG and SRC is a ZERO_EXTEND
625918334Speter	       or SIGN_EXTEND, don't record DEST since it can cause
626018334Speter	       some tracking to be wrong.
626118334Speter
626218334Speter	       ??? Think about this more later.  */
626318334Speter	    || (GET_CODE (dest) == SUBREG
626418334Speter		&& (GET_MODE_SIZE (GET_MODE (dest))
626518334Speter		    > GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))))
626618334Speter		&& (GET_CODE (sets[i].src) == SIGN_EXTEND
626718334Speter		    || GET_CODE (sets[i].src) == ZERO_EXTEND)))
626818334Speter	  continue;
626918334Speter
627018334Speter	/* STRICT_LOW_PART isn't part of the value BEING set,
627118334Speter	   and neither is the SUBREG inside it.
627218334Speter	   Note that in this case SETS[I].SRC_ELT is really SRC_EQV_ELT.  */
627318334Speter	if (GET_CODE (dest) == STRICT_LOW_PART)
627418334Speter	  dest = SUBREG_REG (XEXP (dest, 0));
627518334Speter
6276169689Skan	if (REG_P (dest) || GET_CODE (dest) == SUBREG)
627718334Speter	  /* Registers must also be inserted into chains for quantities.  */
627818334Speter	  if (insert_regs (dest, sets[i].src_elt, 1))
627918334Speter	    {
628018334Speter	      /* If `insert_regs' changes something, the hash code must be
628118334Speter		 recalculated.  */
628218334Speter	      rehash_using_reg (dest);
628318334Speter	      sets[i].dest_hash = HASH (dest, GET_MODE (dest));
628418334Speter	    }
628518334Speter
6286169689Skan	elt = insert (dest, sets[i].src_elt,
6287169689Skan		      sets[i].dest_hash, GET_MODE (dest));
628850397Sobrien
6289169689Skan	elt->in_memory = (MEM_P (sets[i].inner_dest)
6290169689Skan			  && !MEM_READONLY_P (sets[i].inner_dest));
629118334Speter
629218334Speter	/* If we have (set (subreg:m1 (reg:m2 foo) 0) (bar:m1)), M1 is no
629318334Speter	   narrower than M2, and both M1 and M2 are the same number of words,
629418334Speter	   we are also doing (set (reg:m2 foo) (subreg:m2 (bar:m1) 0)) so
629518334Speter	   make that equivalence as well.
629618334Speter
6297169689Skan	   However, BAR may have equivalences for which gen_lowpart
6298169689Skan	   will produce a simpler value than gen_lowpart applied to
629918334Speter	   BAR (e.g., if BAR was ZERO_EXTENDed from M2), so we will scan all
630090075Sobrien	   BAR's equivalences.  If we don't get a simplified form, make
630118334Speter	   the SUBREG.  It will not be used in an equivalence, but will
630218334Speter	   cause two similar assignments to be detected.
630318334Speter
630418334Speter	   Note the loop below will find SUBREG_REG (DEST) since we have
630518334Speter	   already entered SRC and DEST of the SET in the table.  */
630618334Speter
630718334Speter	if (GET_CODE (dest) == SUBREG
630818334Speter	    && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) - 1)
630918334Speter		 / UNITS_PER_WORD)
631090075Sobrien		== (GET_MODE_SIZE (GET_MODE (dest)) - 1) / UNITS_PER_WORD)
631118334Speter	    && (GET_MODE_SIZE (GET_MODE (dest))
631218334Speter		>= GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))))
631318334Speter	    && sets[i].src_elt != 0)
631418334Speter	  {
631518334Speter	    enum machine_mode new_mode = GET_MODE (SUBREG_REG (dest));
631618334Speter	    struct table_elt *elt, *classp = 0;
631718334Speter
631818334Speter	    for (elt = sets[i].src_elt->first_same_value; elt;
631918334Speter		 elt = elt->next_same_value)
632018334Speter	      {
632118334Speter		rtx new_src = 0;
632218334Speter		unsigned src_hash;
632318334Speter		struct table_elt *src_elt;
6324117395Skan		int byte = 0;
632518334Speter
632618334Speter		/* Ignore invalid entries.  */
6327169689Skan		if (!REG_P (elt->exp)
6328169689Skan		    && ! exp_equiv_p (elt->exp, elt->exp, 1, false))
632918334Speter		  continue;
633018334Speter
6331117395Skan		/* We may have already been playing subreg games.  If the
6332117395Skan		   mode is already correct for the destination, use it.  */
6333117395Skan		if (GET_MODE (elt->exp) == new_mode)
6334117395Skan		  new_src = elt->exp;
6335117395Skan		else
6336117395Skan		  {
6337117395Skan		    /* Calculate big endian correction for the SUBREG_BYTE.
6338117395Skan		       We have already checked that M1 (GET_MODE (dest))
6339117395Skan		       is not narrower than M2 (new_mode).  */
6340117395Skan		    if (BYTES_BIG_ENDIAN)
6341117395Skan		      byte = (GET_MODE_SIZE (GET_MODE (dest))
6342117395Skan			      - GET_MODE_SIZE (new_mode));
634318334Speter
6344117395Skan		    new_src = simplify_gen_subreg (new_mode, elt->exp,
6345117395Skan					           GET_MODE (dest), byte);
6346117395Skan		  }
6347117395Skan
6348117395Skan		/* The call to simplify_gen_subreg fails if the value
6349117395Skan		   is VOIDmode, yet we can't do any simplification, e.g.
6350117395Skan		   for EXPR_LISTs denoting function call results.
6351117395Skan		   It is invalid to construct a SUBREG with a VOIDmode
6352117395Skan		   SUBREG_REG, hence a zero new_src means we can't do
6353117395Skan		   this substitution.  */
6354117395Skan		if (! new_src)
6355117395Skan		  continue;
6356117395Skan
635718334Speter		src_hash = HASH (new_src, new_mode);
635818334Speter		src_elt = lookup (new_src, src_hash, new_mode);
635918334Speter
636018334Speter		/* Put the new source in the hash table is if isn't
636118334Speter		   already.  */
636218334Speter		if (src_elt == 0)
636318334Speter		  {
636418334Speter		    if (insert_regs (new_src, classp, 0))
636518334Speter		      {
636618334Speter			rehash_using_reg (new_src);
636718334Speter			src_hash = HASH (new_src, new_mode);
636818334Speter		      }
636918334Speter		    src_elt = insert (new_src, classp, src_hash, new_mode);
637018334Speter		    src_elt->in_memory = elt->in_memory;
637118334Speter		  }
637218334Speter		else if (classp && classp != src_elt->first_same_value)
637390075Sobrien		  /* Show that two things that we've seen before are
637418334Speter		     actually the same.  */
637518334Speter		  merge_equiv_classes (src_elt, classp);
637618334Speter
637718334Speter		classp = src_elt->first_same_value;
637850397Sobrien		/* Ignore invalid entries.  */
637950397Sobrien		while (classp
6380169689Skan		       && !REG_P (classp->exp)
6381169689Skan		       && ! exp_equiv_p (classp->exp, classp->exp, 1, false))
638250397Sobrien		  classp = classp->next_same_value;
638318334Speter	      }
638418334Speter	  }
638518334Speter      }
638618334Speter
638790075Sobrien  /* Special handling for (set REG0 REG1) where REG0 is the
638890075Sobrien     "cheapest", cheaper than REG1.  After cse, REG1 will probably not
638990075Sobrien     be used in the sequel, so (if easily done) change this insn to
639090075Sobrien     (set REG1 REG0) and replace REG1 with REG0 in the previous insn
639190075Sobrien     that computed their value.  Then REG1 will become a dead store
639290075Sobrien     and won't cloud the situation for later optimizations.
639318334Speter
639418334Speter     Do not make this change if REG1 is a hard register, because it will
639518334Speter     then be used in the sequel and we may be changing a two-operand insn
639618334Speter     into a three-operand insn.
639718334Speter
639852284Sobrien     Also do not do this if we are operating on a copy of INSN.
639918334Speter
640052284Sobrien     Also don't do this if INSN ends a libcall; this would cause an unrelated
640152284Sobrien     register to be set in the middle of a libcall, and we then get bad code
640252284Sobrien     if the libcall is deleted.  */
640352284Sobrien
6404169689Skan  if (n_sets == 1 && sets[0].rtl && REG_P (SET_DEST (sets[0].rtl))
640518334Speter      && NEXT_INSN (PREV_INSN (insn)) == insn
6406169689Skan      && REG_P (SET_SRC (sets[0].rtl))
640718334Speter      && REGNO (SET_SRC (sets[0].rtl)) >= FIRST_PSEUDO_REGISTER
640890075Sobrien      && REGNO_QTY_VALID_P (REGNO (SET_SRC (sets[0].rtl))))
640918334Speter    {
641090075Sobrien      int src_q = REG_QTY (REGNO (SET_SRC (sets[0].rtl)));
641190075Sobrien      struct qty_table_elem *src_ent = &qty_table[src_q];
641218334Speter
641390075Sobrien      if ((src_ent->first_reg == REGNO (SET_DEST (sets[0].rtl)))
641490075Sobrien	  && ! find_reg_note (insn, REG_RETVAL, NULL_RTX))
641518334Speter	{
6416117395Skan	  rtx prev = insn;
6417117395Skan	  /* Scan for the previous nonnote insn, but stop at a basic
6418117395Skan	     block boundary.  */
6419117395Skan	  do
6420117395Skan	    {
6421117395Skan	      prev = PREV_INSN (prev);
6422117395Skan	    }
6423169689Skan	  while (prev && NOTE_P (prev)
6424117395Skan		 && NOTE_LINE_NUMBER (prev) != NOTE_INSN_BASIC_BLOCK);
6425132718Skan
642690075Sobrien	  /* Do not swap the registers around if the previous instruction
642790075Sobrien	     attaches a REG_EQUIV note to REG1.
642818334Speter
642990075Sobrien	     ??? It's not entirely clear whether we can transfer a REG_EQUIV
643090075Sobrien	     from the pseudo that originally shadowed an incoming argument
643190075Sobrien	     to another register.  Some uses of REG_EQUIV might rely on it
643290075Sobrien	     being attached to REG1 rather than REG2.
643318334Speter
643490075Sobrien	     This section previously turned the REG_EQUIV into a REG_EQUAL
643590075Sobrien	     note.  We cannot do that because REG_EQUIV may provide an
6436117395Skan	     uninitialized stack slot when REG_PARM_STACK_SPACE is used.  */
643718334Speter
6438169689Skan	  if (prev != 0 && NONJUMP_INSN_P (prev)
643990075Sobrien	      && GET_CODE (PATTERN (prev)) == SET
644090075Sobrien	      && SET_DEST (PATTERN (prev)) == SET_SRC (sets[0].rtl)
644190075Sobrien	      && ! find_reg_note (prev, REG_EQUIV, NULL_RTX))
644218334Speter	    {
644390075Sobrien	      rtx dest = SET_DEST (sets[0].rtl);
644490075Sobrien	      rtx src = SET_SRC (sets[0].rtl);
644590075Sobrien	      rtx note;
644690075Sobrien
644790075Sobrien	      validate_change (prev, &SET_DEST (PATTERN (prev)), dest, 1);
644890075Sobrien	      validate_change (insn, &SET_DEST (sets[0].rtl), src, 1);
644990075Sobrien	      validate_change (insn, &SET_SRC (sets[0].rtl), dest, 1);
645090075Sobrien	      apply_change_group ();
645190075Sobrien
645290075Sobrien	      /* If INSN has a REG_EQUAL note, and this note mentions
645390075Sobrien		 REG0, then we must delete it, because the value in
645490075Sobrien		 REG0 has changed.  If the note's value is REG1, we must
645590075Sobrien		 also delete it because that is now this insn's dest.  */
645690075Sobrien	      note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
645790075Sobrien	      if (note != 0
645890075Sobrien		  && (reg_mentioned_p (dest, XEXP (note, 0))
645990075Sobrien		      || rtx_equal_p (src, XEXP (note, 0))))
646090075Sobrien		remove_note (insn, note);
646118334Speter	    }
646218334Speter	}
646318334Speter    }
646418334Speter
646518334Speter  /* If this is a conditional jump insn, record any known equivalences due to
646618334Speter     the condition being tested.  */
646718334Speter
6468169689Skan  if (JUMP_P (insn)
646918334Speter      && n_sets == 1 && GET_CODE (x) == SET
647018334Speter      && GET_CODE (SET_SRC (x)) == IF_THEN_ELSE)
647118334Speter    record_jump_equiv (insn, 0);
647218334Speter
647318334Speter#ifdef HAVE_cc0
647418334Speter  /* If the previous insn set CC0 and this insn no longer references CC0,
647518334Speter     delete the previous insn.  Here we use the fact that nothing expects CC0
647618334Speter     to be valid over an insn, which is true until the final pass.  */
6477169689Skan  if (prev_insn && NONJUMP_INSN_P (prev_insn)
647818334Speter      && (tem = single_set (prev_insn)) != 0
647918334Speter      && SET_DEST (tem) == cc0_rtx
648018334Speter      && ! reg_mentioned_p (cc0_rtx, x))
648190075Sobrien    delete_insn (prev_insn);
648218334Speter
648318334Speter  prev_insn_cc0 = this_insn_cc0;
648418334Speter  prev_insn_cc0_mode = this_insn_cc0_mode;
6485132718Skan  prev_insn = insn;
648618334Speter#endif
648718334Speter}
648818334Speter
648952284Sobrien/* Remove from the hash table all expressions that reference memory.  */
649090075Sobrien
649118334Speterstatic void
6492132718Skaninvalidate_memory (void)
649318334Speter{
649490075Sobrien  int i;
649590075Sobrien  struct table_elt *p, *next;
649618334Speter
649790075Sobrien  for (i = 0; i < HASH_SIZE; i++)
649850397Sobrien    for (p = table[i]; p; p = next)
649950397Sobrien      {
650050397Sobrien	next = p->next_same_hash;
650150397Sobrien	if (p->in_memory)
650250397Sobrien	  remove_from_table (p, i);
650350397Sobrien      }
650450397Sobrien}
650550397Sobrien
650690075Sobrien/* If ADDR is an address that implicitly affects the stack pointer, return
650790075Sobrien   1 and update the register tables to show the effect.  Else, return 0.  */
650890075Sobrien
650950397Sobrienstatic int
6510132718Skanaddr_affects_sp_p (rtx addr)
651150397Sobrien{
6512169689Skan  if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC
6513169689Skan      && REG_P (XEXP (addr, 0))
651450397Sobrien      && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
651518334Speter    {
651652284Sobrien      if (REG_TICK (STACK_POINTER_REGNUM) >= 0)
6517117395Skan	{
6518117395Skan	  REG_TICK (STACK_POINTER_REGNUM)++;
6519117395Skan	  /* Is it possible to use a subreg of SP?  */
6520117395Skan	  SUBREG_TICKED (STACK_POINTER_REGNUM) = -1;
6521117395Skan	}
652250397Sobrien
652350397Sobrien      /* This should be *very* rare.  */
652450397Sobrien      if (TEST_HARD_REG_BIT (hard_regs_in_table, STACK_POINTER_REGNUM))
652550397Sobrien	invalidate (stack_pointer_rtx, VOIDmode);
652690075Sobrien
652750397Sobrien      return 1;
652818334Speter    }
652990075Sobrien
653050397Sobrien  return 0;
653118334Speter}
653218334Speter
653318334Speter/* Perform invalidation on the basis of everything about an insn
653418334Speter   except for invalidating the actual places that are SET in it.
653518334Speter   This includes the places CLOBBERed, and anything that might
653618334Speter   alias with something that is SET or CLOBBERed.
653718334Speter
653818334Speter   X is the pattern of the insn.  */
653918334Speter
654018334Speterstatic void
6541132718Skaninvalidate_from_clobbers (rtx x)
654218334Speter{
654318334Speter  if (GET_CODE (x) == CLOBBER)
654418334Speter    {
654518334Speter      rtx ref = XEXP (x, 0);
654618334Speter      if (ref)
654718334Speter	{
6548169689Skan	  if (REG_P (ref) || GET_CODE (ref) == SUBREG
6549169689Skan	      || MEM_P (ref))
655018334Speter	    invalidate (ref, VOIDmode);
655118334Speter	  else if (GET_CODE (ref) == STRICT_LOW_PART
655218334Speter		   || GET_CODE (ref) == ZERO_EXTRACT)
655318334Speter	    invalidate (XEXP (ref, 0), GET_MODE (ref));
655418334Speter	}
655518334Speter    }
655618334Speter  else if (GET_CODE (x) == PARALLEL)
655718334Speter    {
655890075Sobrien      int i;
655918334Speter      for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
656018334Speter	{
656190075Sobrien	  rtx y = XVECEXP (x, 0, i);
656218334Speter	  if (GET_CODE (y) == CLOBBER)
656318334Speter	    {
656418334Speter	      rtx ref = XEXP (y, 0);
6565169689Skan	      if (REG_P (ref) || GET_CODE (ref) == SUBREG
6566169689Skan		  || MEM_P (ref))
656750397Sobrien		invalidate (ref, VOIDmode);
656850397Sobrien	      else if (GET_CODE (ref) == STRICT_LOW_PART
656950397Sobrien		       || GET_CODE (ref) == ZERO_EXTRACT)
657050397Sobrien		invalidate (XEXP (ref, 0), GET_MODE (ref));
657118334Speter	    }
657218334Speter	}
657318334Speter    }
657418334Speter}
657518334Speter
657618334Speter/* Process X, part of the REG_NOTES of an insn.  Look at any REG_EQUAL notes
657718334Speter   and replace any registers in them with either an equivalent constant
657818334Speter   or the canonical form of the register.  If we are inside an address,
657918334Speter   only do this if the address remains valid.
658018334Speter
658118334Speter   OBJECT is 0 except when within a MEM in which case it is the MEM.
658218334Speter
658318334Speter   Return the replacement for X.  */
658418334Speter
658518334Speterstatic rtx
6586132718Skancse_process_notes (rtx x, rtx object)
658718334Speter{
658818334Speter  enum rtx_code code = GET_CODE (x);
658990075Sobrien  const char *fmt = GET_RTX_FORMAT (code);
659018334Speter  int i;
659118334Speter
659218334Speter  switch (code)
659318334Speter    {
659418334Speter    case CONST_INT:
659518334Speter    case CONST:
659618334Speter    case SYMBOL_REF:
659718334Speter    case LABEL_REF:
659818334Speter    case CONST_DOUBLE:
659996263Sobrien    case CONST_VECTOR:
660018334Speter    case PC:
660118334Speter    case CC0:
660218334Speter    case LO_SUM:
660318334Speter      return x;
660418334Speter
660518334Speter    case MEM:
660690075Sobrien      validate_change (x, &XEXP (x, 0),
660790075Sobrien		       cse_process_notes (XEXP (x, 0), x), 0);
660818334Speter      return x;
660918334Speter
661018334Speter    case EXPR_LIST:
661118334Speter    case INSN_LIST:
661218334Speter      if (REG_NOTE_KIND (x) == REG_EQUAL)
661318334Speter	XEXP (x, 0) = cse_process_notes (XEXP (x, 0), NULL_RTX);
661418334Speter      if (XEXP (x, 1))
661518334Speter	XEXP (x, 1) = cse_process_notes (XEXP (x, 1), NULL_RTX);
661618334Speter      return x;
661718334Speter
661818334Speter    case SIGN_EXTEND:
661918334Speter    case ZERO_EXTEND:
662050397Sobrien    case SUBREG:
662118334Speter      {
662218334Speter	rtx new = cse_process_notes (XEXP (x, 0), object);
662318334Speter	/* We don't substitute VOIDmode constants into these rtx,
662418334Speter	   since they would impede folding.  */
662518334Speter	if (GET_MODE (new) != VOIDmode)
662618334Speter	  validate_change (object, &XEXP (x, 0), new, 0);
662718334Speter	return x;
662818334Speter      }
662918334Speter
663018334Speter    case REG:
663152284Sobrien      i = REG_QTY (REGNO (x));
663218334Speter
663318334Speter      /* Return a constant or a constant register.  */
663490075Sobrien      if (REGNO_QTY_VALID_P (REGNO (x)))
663518334Speter	{
663690075Sobrien	  struct qty_table_elem *ent = &qty_table[i];
663790075Sobrien
663890075Sobrien	  if (ent->const_rtx != NULL_RTX
663990075Sobrien	      && (CONSTANT_P (ent->const_rtx)
6640169689Skan		  || REG_P (ent->const_rtx)))
664190075Sobrien	    {
6642169689Skan	      rtx new = gen_lowpart (GET_MODE (x), ent->const_rtx);
664390075Sobrien	      if (new)
664490075Sobrien		return new;
664590075Sobrien	    }
664618334Speter	}
664718334Speter
664818334Speter      /* Otherwise, canonicalize this register.  */
664918334Speter      return canon_reg (x, NULL_RTX);
665090075Sobrien
665150397Sobrien    default:
665250397Sobrien      break;
665318334Speter    }
665418334Speter
665518334Speter  for (i = 0; i < GET_RTX_LENGTH (code); i++)
665618334Speter    if (fmt[i] == 'e')
665718334Speter      validate_change (object, &XEXP (x, i),
665818334Speter		       cse_process_notes (XEXP (x, i), object), 0);
665918334Speter
666018334Speter  return x;
666118334Speter}
666218334Speter
666318334Speter/* Process one SET of an insn that was skipped.  We ignore CLOBBERs
666418334Speter   since they are done elsewhere.  This function is called via note_stores.  */
666518334Speter
666618334Speterstatic void
6667132718Skaninvalidate_skipped_set (rtx dest, rtx set, void *data ATTRIBUTE_UNUSED)
666818334Speter{
666950397Sobrien  enum rtx_code code = GET_CODE (dest);
667018334Speter
667150397Sobrien  if (code == MEM
667290075Sobrien      && ! addr_affects_sp_p (dest)	/* If this is not a stack push ...  */
667350397Sobrien      /* There are times when an address can appear varying and be a PLUS
667450397Sobrien	 during this scan when it would be a fixed address were we to know
667550397Sobrien	 the proper equivalences.  So invalidate all memory if there is
667650397Sobrien	 a BLKmode or nonscalar memory reference or a reference to a
667750397Sobrien	 variable address.  */
667850397Sobrien      && (MEM_IN_STRUCT_P (dest) || GET_MODE (dest) == BLKmode
667990075Sobrien	  || cse_rtx_varies_p (XEXP (dest, 0), 0)))
668050397Sobrien    {
668150397Sobrien      invalidate_memory ();
668250397Sobrien      return;
668350397Sobrien    }
668418334Speter
668548743Sobrien  if (GET_CODE (set) == CLOBBER
6686132718Skan      || CC0_P (dest)
668748743Sobrien      || dest == pc_rtx)
668848743Sobrien    return;
668948743Sobrien
669050397Sobrien  if (code == STRICT_LOW_PART || code == ZERO_EXTRACT)
669150397Sobrien    invalidate (XEXP (dest, 0), GET_MODE (dest));
669250397Sobrien  else if (code == REG || code == SUBREG || code == MEM)
669318334Speter    invalidate (dest, VOIDmode);
669418334Speter}
669518334Speter
669618334Speter/* Invalidate all insns from START up to the end of the function or the
669718334Speter   next label.  This called when we wish to CSE around a block that is
669818334Speter   conditionally executed.  */
669918334Speter
670018334Speterstatic void
6701132718Skaninvalidate_skipped_block (rtx start)
670218334Speter{
670318334Speter  rtx insn;
670418334Speter
6705169689Skan  for (insn = start; insn && !LABEL_P (insn);
670618334Speter       insn = NEXT_INSN (insn))
670718334Speter    {
670890075Sobrien      if (! INSN_P (insn))
670918334Speter	continue;
671018334Speter
6711169689Skan      if (CALL_P (insn))
671218334Speter	{
671390075Sobrien	  if (! CONST_OR_PURE_CALL_P (insn))
671450397Sobrien	    invalidate_memory ();
671518334Speter	  invalidate_for_call ();
671618334Speter	}
671718334Speter
671850397Sobrien      invalidate_from_clobbers (PATTERN (insn));
671990075Sobrien      note_stores (PATTERN (insn), invalidate_skipped_set, NULL);
672018334Speter    }
672118334Speter}
672218334Speter
672318334Speter/* Find the end of INSN's basic block and return its range,
672418334Speter   the total number of SETs in all the insns of the block, the last insn of the
672518334Speter   block, and the branch path.
672618334Speter
6727117395Skan   The branch path indicates which branches should be followed.  If a nonzero
672818334Speter   path size is specified, the block should be rescanned and a different set
672918334Speter   of branches will be taken.  The branch path is only used if
6730117395Skan   FLAG_CSE_FOLLOW_JUMPS or FLAG_CSE_SKIP_BLOCKS is nonzero.
673118334Speter
673218334Speter   DATA is a pointer to a struct cse_basic_block_data, defined below, that is
673318334Speter   used to describe the block.  It is filled in with the information about
673418334Speter   the current block.  The incoming structure's branch path, if any, is used
673518334Speter   to construct the output branch path.  */
673618334Speter
6737169689Skanstatic void
6738132718Skancse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
6739169689Skan			int follow_jumps, int skip_blocks)
674018334Speter{
674118334Speter  rtx p = insn, q;
674218334Speter  int nsets = 0;
674318334Speter  int low_cuid = INSN_CUID (insn), high_cuid = INSN_CUID (insn);
674490075Sobrien  rtx next = INSN_P (insn) ? insn : next_real_insn (insn);
674518334Speter  int path_size = data->path_size;
674618334Speter  int path_entry = 0;
674718334Speter  int i;
674818334Speter
674918334Speter  /* Update the previous branch path, if any.  If the last branch was
6750169689Skan     previously PATH_TAKEN, mark it PATH_NOT_TAKEN.
6751169689Skan     If it was previously PATH_NOT_TAKEN,
675218334Speter     shorten the path by one and look at the previous branch.  We know that
6753117395Skan     at least one branch must have been taken if PATH_SIZE is nonzero.  */
675418334Speter  while (path_size > 0)
675518334Speter    {
6756169689Skan      if (data->path[path_size - 1].status != PATH_NOT_TAKEN)
675718334Speter	{
6758169689Skan	  data->path[path_size - 1].status = PATH_NOT_TAKEN;
675918334Speter	  break;
676018334Speter	}
676118334Speter      else
676218334Speter	path_size--;
676318334Speter    }
676418334Speter
676590075Sobrien  /* If the first instruction is marked with QImode, that means we've
676690075Sobrien     already processed this block.  Our caller will look at DATA->LAST
676790075Sobrien     to figure out where to go next.  We want to return the next block
676890075Sobrien     in the instruction stream, not some branched-to block somewhere
676990075Sobrien     else.  We accomplish this by pretending our called forbid us to
677090075Sobrien     follow jumps, or skip blocks.  */
677190075Sobrien  if (GET_MODE (insn) == QImode)
677290075Sobrien    follow_jumps = skip_blocks = 0;
677390075Sobrien
677418334Speter  /* Scan to end of this basic block.  */
6775169689Skan  while (p && !LABEL_P (p))
677618334Speter    {
677790075Sobrien      /* Don't cse over a call to setjmp; on some machines (eg VAX)
677818334Speter	 the regs restored by the longjmp come from
677918334Speter	 a later time than the setjmp.  */
6780169689Skan      if (PREV_INSN (p) && CALL_P (PREV_INSN (p))
678190075Sobrien	  && find_reg_note (PREV_INSN (p), REG_SETJMP, NULL))
678218334Speter	break;
678318334Speter
678418334Speter      /* A PARALLEL can have lots of SETs in it,
678518334Speter	 especially if it is really an ASM_OPERANDS.  */
678690075Sobrien      if (INSN_P (p) && GET_CODE (PATTERN (p)) == PARALLEL)
678718334Speter	nsets += XVECLEN (PATTERN (p), 0);
6788169689Skan      else if (!NOTE_P (p))
678918334Speter	nsets += 1;
679090075Sobrien
679118334Speter      /* Ignore insns made by CSE; they cannot affect the boundaries of
679218334Speter	 the basic block.  */
679318334Speter
679418334Speter      if (INSN_UID (p) <= max_uid && INSN_CUID (p) > high_cuid)
679518334Speter	high_cuid = INSN_CUID (p);
679618334Speter      if (INSN_UID (p) <= max_uid && INSN_CUID (p) < low_cuid)
679718334Speter	low_cuid = INSN_CUID (p);
679818334Speter
679918334Speter      /* See if this insn is in our branch path.  If it is and we are to
680018334Speter	 take it, do so.  */
680118334Speter      if (path_entry < path_size && data->path[path_entry].branch == p)
680218334Speter	{
6803169689Skan	  if (data->path[path_entry].status != PATH_NOT_TAKEN)
680418334Speter	    p = JUMP_LABEL (p);
680590075Sobrien
680618334Speter	  /* Point to next entry in path, if any.  */
680718334Speter	  path_entry++;
680818334Speter	}
680918334Speter
681018334Speter      /* If this is a conditional jump, we can follow it if -fcse-follow-jumps
681118334Speter	 was specified, we haven't reached our maximum path length, there are
681218334Speter	 insns following the target of the jump, this is the only use of the
681318334Speter	 jump label, and the target label is preceded by a BARRIER.
681418334Speter
681518334Speter	 Alternatively, we can follow the jump if it branches around a
681618334Speter	 block of code and there are no other branches into the block.
681718334Speter	 In this case invalidate_skipped_block will be called to invalidate any
681818334Speter	 registers set in the block when following the jump.  */
681918334Speter
6820132718Skan      else if ((follow_jumps || skip_blocks) && path_size < PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH) - 1
6821169689Skan	       && JUMP_P (p)
682290075Sobrien	       && GET_CODE (PATTERN (p)) == SET
682318334Speter	       && GET_CODE (SET_SRC (PATTERN (p))) == IF_THEN_ELSE
682450397Sobrien	       && JUMP_LABEL (p) != 0
682518334Speter	       && LABEL_NUSES (JUMP_LABEL (p)) == 1
682618334Speter	       && NEXT_INSN (JUMP_LABEL (p)) != 0)
682718334Speter	{
682818334Speter	  for (q = PREV_INSN (JUMP_LABEL (p)); q; q = PREV_INSN (q))
6829169689Skan	    if ((!NOTE_P (q)
6830169689Skan		 || (PREV_INSN (q) && CALL_P (PREV_INSN (q))
683190075Sobrien		     && find_reg_note (PREV_INSN (q), REG_SETJMP, NULL)))
6832169689Skan		&& (!LABEL_P (q) || LABEL_NUSES (q) != 0))
683318334Speter	      break;
683418334Speter
683518334Speter	  /* If we ran into a BARRIER, this code is an extension of the
683618334Speter	     basic block when the branch is taken.  */
6837169689Skan	  if (follow_jumps && q != 0 && BARRIER_P (q))
683818334Speter	    {
683918334Speter	      /* Don't allow ourself to keep walking around an
684018334Speter		 always-executed loop.  */
684118334Speter	      if (next_real_insn (q) == next)
684218334Speter		{
684318334Speter		  p = NEXT_INSN (p);
684418334Speter		  continue;
684518334Speter		}
684618334Speter
684718334Speter	      /* Similarly, don't put a branch in our path more than once.  */
684818334Speter	      for (i = 0; i < path_entry; i++)
684918334Speter		if (data->path[i].branch == p)
685018334Speter		  break;
685118334Speter
685218334Speter	      if (i != path_entry)
685318334Speter		break;
685418334Speter
685518334Speter	      data->path[path_entry].branch = p;
6856169689Skan	      data->path[path_entry++].status = PATH_TAKEN;
685718334Speter
685818334Speter	      /* This branch now ends our path.  It was possible that we
685918334Speter		 didn't see this branch the last time around (when the
686018334Speter		 insn in front of the target was a JUMP_INSN that was
686118334Speter		 turned into a no-op).  */
686218334Speter	      path_size = path_entry;
686318334Speter
686418334Speter	      p = JUMP_LABEL (p);
686518334Speter	      /* Mark block so we won't scan it again later.  */
686618334Speter	      PUT_MODE (NEXT_INSN (p), QImode);
686718334Speter	    }
686818334Speter	  /* Detect a branch around a block of code.  */
6869169689Skan	  else if (skip_blocks && q != 0 && !LABEL_P (q))
687018334Speter	    {
687190075Sobrien	      rtx tmp;
687218334Speter
687318334Speter	      if (next_real_insn (q) == next)
687418334Speter		{
687518334Speter		  p = NEXT_INSN (p);
687618334Speter		  continue;
687718334Speter		}
687818334Speter
687918334Speter	      for (i = 0; i < path_entry; i++)
688018334Speter		if (data->path[i].branch == p)
688118334Speter		  break;
688218334Speter
688318334Speter	      if (i != path_entry)
688418334Speter		break;
688518334Speter
688618334Speter	      /* This is no_labels_between_p (p, q) with an added check for
688718334Speter		 reaching the end of a function (in case Q precedes P).  */
688818334Speter	      for (tmp = NEXT_INSN (p); tmp && tmp != q; tmp = NEXT_INSN (tmp))
6889169689Skan		if (LABEL_P (tmp))
689018334Speter		  break;
689190075Sobrien
689218334Speter	      if (tmp == q)
689318334Speter		{
689418334Speter		  data->path[path_entry].branch = p;
6895169689Skan		  data->path[path_entry++].status = PATH_AROUND;
689618334Speter
689718334Speter		  path_size = path_entry;
689818334Speter
689918334Speter		  p = JUMP_LABEL (p);
690018334Speter		  /* Mark block so we won't scan it again later.  */
690118334Speter		  PUT_MODE (NEXT_INSN (p), QImode);
690218334Speter		}
690318334Speter	    }
690418334Speter	}
690518334Speter      p = NEXT_INSN (p);
690618334Speter    }
690718334Speter
690818334Speter  data->low_cuid = low_cuid;
690918334Speter  data->high_cuid = high_cuid;
691018334Speter  data->nsets = nsets;
691118334Speter  data->last = p;
691218334Speter
691318334Speter  /* If all jumps in the path are not taken, set our path length to zero
691418334Speter     so a rescan won't be done.  */
691518334Speter  for (i = path_size - 1; i >= 0; i--)
6916169689Skan    if (data->path[i].status != PATH_NOT_TAKEN)
691718334Speter      break;
691818334Speter
691918334Speter  if (i == -1)
692018334Speter    data->path_size = 0;
692118334Speter  else
692218334Speter    data->path_size = path_size;
692318334Speter
692418334Speter  /* End the current branch path.  */
692518334Speter  data->path[path_size].branch = 0;
692618334Speter}
692718334Speter
692818334Speter/* Perform cse on the instructions of a function.
692918334Speter   F is the first instruction.
693018334Speter   NREGS is one plus the highest pseudo-reg number used in the instruction.
693118334Speter
693218334Speter   Returns 1 if jump_optimize should be redone due to simplifications
693318334Speter   in conditional jump instructions.  */
693418334Speter
693518334Speterint
6936169689Skancse_main (rtx f, int nregs)
693718334Speter{
693818334Speter  struct cse_basic_block_data val;
693990075Sobrien  rtx insn = f;
694090075Sobrien  int i;
694118334Speter
6942169689Skan  init_cse_reg_info (nregs);
6943132718Skan
6944169689Skan  val.path = XNEWVEC (struct branch_path, PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH));
6945169689Skan
694618334Speter  cse_jumps_altered = 0;
694718334Speter  recorded_label_ref = 0;
694818334Speter  constant_pool_entries_cost = 0;
6949132718Skan  constant_pool_entries_regcost = 0;
695018334Speter  val.path_size = 0;
6951169689Skan  rtl_hooks = cse_rtl_hooks;
695218334Speter
695318334Speter  init_recog ();
695450397Sobrien  init_alias_analysis ();
695518334Speter
6956169689Skan  reg_eqv_table = XNEWVEC (struct reg_eqv_elem, nregs);
695718334Speter
695818334Speter  /* Find the largest uid.  */
695918334Speter
696018334Speter  max_uid = get_max_uid ();
6961169689Skan  uid_cuid = XCNEWVEC (int, max_uid + 1);
696218334Speter
696318334Speter  /* Compute the mapping from uids to cuids.
696418334Speter     CUIDs are numbers assigned to insns, like uids,
696518334Speter     except that cuids increase monotonically through the code.
696618334Speter     Don't assign cuids to line-number NOTEs, so that the distance in cuids
696718334Speter     between two insns is not affected by -g.  */
696818334Speter
696918334Speter  for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
697018334Speter    {
6971169689Skan      if (!NOTE_P (insn)
697218334Speter	  || NOTE_LINE_NUMBER (insn) < 0)
697318334Speter	INSN_CUID (insn) = ++i;
697418334Speter      else
697518334Speter	/* Give a line number note the same cuid as preceding insn.  */
697618334Speter	INSN_CUID (insn) = i;
697718334Speter    }
697818334Speter
697918334Speter  /* Loop over basic blocks.
698018334Speter     Compute the maximum number of qty's needed for each basic block
698118334Speter     (which is 2 for each SET).  */
698218334Speter  insn = f;
698318334Speter  while (insn)
698418334Speter    {
698590075Sobrien      cse_altered = 0;
6986169689Skan      cse_end_of_basic_block (insn, &val, flag_cse_follow_jumps,
698718334Speter			      flag_cse_skip_blocks);
698818334Speter
698918334Speter      /* If this basic block was already processed or has no sets, skip it.  */
699018334Speter      if (val.nsets == 0 || GET_MODE (insn) == QImode)
699118334Speter	{
699218334Speter	  PUT_MODE (insn, VOIDmode);
699318334Speter	  insn = (val.last ? NEXT_INSN (val.last) : 0);
699418334Speter	  val.path_size = 0;
699518334Speter	  continue;
699618334Speter	}
699718334Speter
699818334Speter      cse_basic_block_start = val.low_cuid;
699918334Speter      cse_basic_block_end = val.high_cuid;
700018334Speter      max_qty = val.nsets * 2;
700190075Sobrien
7002169689Skan      if (dump_file)
7003169689Skan	fprintf (dump_file, ";; Processing block from %d to %d, %d sets.\n",
700418334Speter		 INSN_UID (insn), val.last ? INSN_UID (val.last) : 0,
700518334Speter		 val.nsets);
700618334Speter
700718334Speter      /* Make MAX_QTY bigger to give us room to optimize
700818334Speter	 past the end of this basic block, if that should prove useful.  */
700918334Speter      if (max_qty < 500)
701018334Speter	max_qty = 500;
701118334Speter
701218334Speter      /* If this basic block is being extended by following certain jumps,
701318334Speter         (see `cse_end_of_basic_block'), we reprocess the code from the start.
701418334Speter         Otherwise, we start after this basic block.  */
701518334Speter      if (val.path_size > 0)
7016169689Skan	cse_basic_block (insn, val.last, val.path);
701718334Speter      else
701818334Speter	{
701918334Speter	  int old_cse_jumps_altered = cse_jumps_altered;
702018334Speter	  rtx temp;
702118334Speter
702218334Speter	  /* When cse changes a conditional jump to an unconditional
702318334Speter	     jump, we want to reprocess the block, since it will give
702418334Speter	     us a new branch path to investigate.  */
702518334Speter	  cse_jumps_altered = 0;
7026169689Skan	  temp = cse_basic_block (insn, val.last, val.path);
702718334Speter	  if (cse_jumps_altered == 0
702818334Speter	      || (flag_cse_follow_jumps == 0 && flag_cse_skip_blocks == 0))
702918334Speter	    insn = temp;
703018334Speter
703118334Speter	  cse_jumps_altered |= old_cse_jumps_altered;
703218334Speter	}
703318334Speter
703490075Sobrien      if (cse_altered)
703590075Sobrien	ggc_collect ();
703690075Sobrien
703718334Speter#ifdef USE_C_ALLOCA
703818334Speter      alloca (0);
703918334Speter#endif
704018334Speter    }
704118334Speter
704290075Sobrien  /* Clean up.  */
704390075Sobrien  end_alias_analysis ();
704490075Sobrien  free (uid_cuid);
704590075Sobrien  free (reg_eqv_table);
7046132718Skan  free (val.path);
7047169689Skan  rtl_hooks = general_rtl_hooks;
704890075Sobrien
704918334Speter  return cse_jumps_altered || recorded_label_ref;
705018334Speter}
705118334Speter
705218334Speter/* Process a single basic block.  FROM and TO and the limits of the basic
705318334Speter   block.  NEXT_BRANCH points to the branch path when following jumps or
7054169689Skan   a null path when not following jumps.  */
705518334Speter
705618334Speterstatic rtx
7057169689Skancse_basic_block (rtx from, rtx to, struct branch_path *next_branch)
705818334Speter{
705990075Sobrien  rtx insn;
706018334Speter  int to_usage = 0;
706150397Sobrien  rtx libcall_insn = NULL_RTX;
706250397Sobrien  int num_insns = 0;
7063132718Skan  int no_conflict = 0;
706418334Speter
7065146895Skan  /* Allocate the space needed by qty_table.  */
7066169689Skan  qty_table = XNEWVEC (struct qty_table_elem, max_qty);
706718334Speter
706818334Speter  new_basic_block ();
706918334Speter
707018334Speter  /* TO might be a label.  If so, protect it from being deleted.  */
7071169689Skan  if (to != 0 && LABEL_P (to))
707218334Speter    ++LABEL_NUSES (to);
707318334Speter
707418334Speter  for (insn = from; insn != to; insn = NEXT_INSN (insn))
707518334Speter    {
707690075Sobrien      enum rtx_code code = GET_CODE (insn);
707718334Speter
707850397Sobrien      /* If we have processed 1,000 insns, flush the hash table to
707950397Sobrien	 avoid extreme quadratic behavior.  We must not include NOTEs
708090075Sobrien	 in the count since there may be more of them when generating
708150397Sobrien	 debugging information.  If we clear the table at different
708250397Sobrien	 times, code generated with -g -O might be different than code
708350397Sobrien	 generated with -O but not -g.
708450397Sobrien
708550397Sobrien	 ??? This is a real kludge and needs to be done some other way.
708650397Sobrien	 Perhaps for 2.9.  */
7087169689Skan      if (code != NOTE && num_insns++ > PARAM_VALUE (PARAM_MAX_CSE_INSNS))
708850397Sobrien	{
708952284Sobrien	  flush_hash_table ();
709050397Sobrien	  num_insns = 0;
709150397Sobrien	}
709250397Sobrien
709318334Speter      /* See if this is a branch that is part of the path.  If so, and it is
709418334Speter	 to be taken, do so.  */
709518334Speter      if (next_branch->branch == insn)
709618334Speter	{
709718334Speter	  enum taken status = next_branch++->status;
7098169689Skan	  if (status != PATH_NOT_TAKEN)
709918334Speter	    {
7100169689Skan	      if (status == PATH_TAKEN)
710118334Speter		record_jump_equiv (insn, 1);
710218334Speter	      else
710318334Speter		invalidate_skipped_block (NEXT_INSN (insn));
710418334Speter
710518334Speter	      /* Set the last insn as the jump insn; it doesn't affect cc0.
710618334Speter		 Then follow this branch.  */
710718334Speter#ifdef HAVE_cc0
710818334Speter	      prev_insn_cc0 = 0;
7109132718Skan	      prev_insn = insn;
711018334Speter#endif
711118334Speter	      insn = JUMP_LABEL (insn);
711218334Speter	      continue;
711318334Speter	    }
711418334Speter	}
711590075Sobrien
711618334Speter      if (GET_MODE (insn) == QImode)
711718334Speter	PUT_MODE (insn, VOIDmode);
711818334Speter
7119169689Skan      if (GET_RTX_CLASS (code) == RTX_INSN)
712018334Speter	{
712150397Sobrien	  rtx p;
712250397Sobrien
712318334Speter	  /* Process notes first so we have all notes in canonical forms when
712418334Speter	     looking for duplicate operations.  */
712518334Speter
712618334Speter	  if (REG_NOTES (insn))
712718334Speter	    REG_NOTES (insn) = cse_process_notes (REG_NOTES (insn), NULL_RTX);
712818334Speter
712918334Speter	  /* Track when we are inside in LIBCALL block.  Inside such a block,
713018334Speter	     we do not want to record destinations.  The last insn of a
713118334Speter	     LIBCALL block is not considered to be part of the block, since
713218334Speter	     its destination is the result of the block and hence should be
713318334Speter	     recorded.  */
713418334Speter
713590075Sobrien	  if (REG_NOTES (insn) != 0)
713690075Sobrien	    {
713790075Sobrien	      if ((p = find_reg_note (insn, REG_LIBCALL, NULL_RTX)))
713890075Sobrien		libcall_insn = XEXP (p, 0);
713990075Sobrien	      else if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
7140132718Skan		{
7141132718Skan		  /* Keep libcall_insn for the last SET insn of a no-conflict
7142132718Skan		     block to prevent changing the destination.  */
7143132718Skan		  if (! no_conflict)
7144132718Skan		    libcall_insn = 0;
7145132718Skan		  else
7146132718Skan		    no_conflict = -1;
7147132718Skan		}
7148132718Skan	      else if (find_reg_note (insn, REG_NO_CONFLICT, NULL_RTX))
7149132718Skan		no_conflict = 1;
715090075Sobrien	    }
715118334Speter
715250397Sobrien	  cse_insn (insn, libcall_insn);
715390075Sobrien
7154132718Skan	  if (no_conflict == -1)
7155132718Skan	    {
7156132718Skan	      libcall_insn = 0;
7157132718Skan	      no_conflict = 0;
7158132718Skan	    }
7159132718Skan
716090075Sobrien	  /* If we haven't already found an insn where we added a LABEL_REF,
716190075Sobrien	     check this one.  */
7162169689Skan	  if (NONJUMP_INSN_P (insn) && ! recorded_label_ref
716390075Sobrien	      && for_each_rtx (&PATTERN (insn), check_for_label_ref,
716490075Sobrien			       (void *) insn))
716590075Sobrien	    recorded_label_ref = 1;
716618334Speter	}
716718334Speter
716818334Speter      /* If INSN is now an unconditional jump, skip to the end of our
716918334Speter	 basic block by pretending that we just did the last insn in the
717018334Speter	 basic block.  If we are jumping to the end of our block, show
717118334Speter	 that we can have one usage of TO.  */
717218334Speter
717390075Sobrien      if (any_uncondjump_p (insn))
717418334Speter	{
717518334Speter	  if (to == 0)
717690075Sobrien	    {
7177146895Skan	      free (qty_table);
717890075Sobrien	      return 0;
717990075Sobrien	    }
718018334Speter
718118334Speter	  if (JUMP_LABEL (insn) == to)
718218334Speter	    to_usage = 1;
718318334Speter
718418334Speter	  /* Maybe TO was deleted because the jump is unconditional.
718518334Speter	     If so, there is nothing left in this basic block.  */
718618334Speter	  /* ??? Perhaps it would be smarter to set TO
718790075Sobrien	     to whatever follows this insn,
718818334Speter	     and pretend the basic block had always ended here.  */
718918334Speter	  if (INSN_DELETED_P (to))
719018334Speter	    break;
719118334Speter
719218334Speter	  insn = PREV_INSN (to);
719318334Speter	}
719418334Speter
719518334Speter      /* See if it is ok to keep on going past the label
719618334Speter	 which used to end our basic block.  Remember that we incremented
719718334Speter	 the count of that label, so we decrement it here.  If we made
719818334Speter	 a jump unconditional, TO_USAGE will be one; in that case, we don't
719918334Speter	 want to count the use in that jump.  */
720018334Speter
720118334Speter      if (to != 0 && NEXT_INSN (insn) == to
7202169689Skan	  && LABEL_P (to) && --LABEL_NUSES (to) == to_usage)
720318334Speter	{
720418334Speter	  struct cse_basic_block_data val;
720518334Speter	  rtx prev;
720618334Speter
720718334Speter	  insn = NEXT_INSN (to);
720818334Speter
720918334Speter	  /* If TO was the last insn in the function, we are done.  */
721018334Speter	  if (insn == 0)
721190075Sobrien	    {
7212146895Skan	      free (qty_table);
721390075Sobrien	      return 0;
721490075Sobrien	    }
721518334Speter
721618334Speter	  /* If TO was preceded by a BARRIER we are done with this block
721718334Speter	     because it has no continuation.  */
721818334Speter	  prev = prev_nonnote_insn (to);
7219169689Skan	  if (prev && BARRIER_P (prev))
722090075Sobrien	    {
7221146895Skan	      free (qty_table);
722290075Sobrien	      return insn;
722390075Sobrien	    }
722418334Speter
722518334Speter	  /* Find the end of the following block.  Note that we won't be
722618334Speter	     following branches in this case.  */
722718334Speter	  to_usage = 0;
722818334Speter	  val.path_size = 0;
7229169689Skan	  val.path = XNEWVEC (struct branch_path, PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH));
7230169689Skan	  cse_end_of_basic_block (insn, &val, 0, 0);
7231132718Skan	  free (val.path);
723218334Speter
723318334Speter	  /* If the tables we allocated have enough space left
723418334Speter	     to handle all the SETs in the next basic block,
723518334Speter	     continue through it.  Otherwise, return,
723618334Speter	     and that block will be scanned individually.  */
723718334Speter	  if (val.nsets * 2 + next_qty > max_qty)
723818334Speter	    break;
723918334Speter
724018334Speter	  cse_basic_block_start = val.low_cuid;
724118334Speter	  cse_basic_block_end = val.high_cuid;
724218334Speter	  to = val.last;
724318334Speter
724418334Speter	  /* Prevent TO from being deleted if it is a label.  */
7245169689Skan	  if (to != 0 && LABEL_P (to))
724618334Speter	    ++LABEL_NUSES (to);
724718334Speter
724818334Speter	  /* Back up so we process the first insn in the extension.  */
724918334Speter	  insn = PREV_INSN (insn);
725018334Speter	}
725118334Speter    }
725218334Speter
7253169689Skan  gcc_assert (next_qty <= max_qty);
725418334Speter
7255146895Skan  free (qty_table);
725690075Sobrien
725718334Speter  return to ? NEXT_INSN (to) : 0;
725818334Speter}
725918334Speter
726090075Sobrien/* Called via for_each_rtx to see if an insn is using a LABEL_REF for which
726190075Sobrien   there isn't a REG_LABEL note.  Return one if so.  DATA is the insn.  */
726290075Sobrien
726390075Sobrienstatic int
7264132718Skancheck_for_label_ref (rtx *rtl, void *data)
726590075Sobrien{
726690075Sobrien  rtx insn = (rtx) data;
726790075Sobrien
726890075Sobrien  /* If this insn uses a LABEL_REF and there isn't a REG_LABEL note for it,
726990075Sobrien     we must rerun jump since it needs to place the note.  If this is a
727090075Sobrien     LABEL_REF for a CODE_LABEL that isn't in the insn chain, don't do this
727190075Sobrien     since no REG_LABEL will be added.  */
727290075Sobrien  return (GET_CODE (*rtl) == LABEL_REF
727390075Sobrien	  && ! LABEL_REF_NONLOCAL_P (*rtl)
727490075Sobrien	  && LABEL_P (XEXP (*rtl, 0))
727590075Sobrien	  && INSN_UID (XEXP (*rtl, 0)) != 0
727690075Sobrien	  && ! find_reg_note (insn, REG_LABEL, XEXP (*rtl, 0)));
727790075Sobrien}
727890075Sobrien
727918334Speter/* Count the number of times registers are used (not set) in X.
728018334Speter   COUNTS is an array in which we accumulate the count, INCR is how much
7281169689Skan   we count each register usage.
728218334Speter
7283169689Skan   Don't count a usage of DEST, which is the SET_DEST of a SET which
7284169689Skan   contains X in its SET_SRC.  This is because such a SET does not
7285169689Skan   modify the liveness of DEST.
7286169689Skan   DEST is set to pc_rtx for a trapping insn, which means that we must count
7287169689Skan   uses of a SET_DEST regardless because the insn can't be deleted here.  */
7288169689Skan
728918334Speterstatic void
7290169689Skancount_reg_usage (rtx x, int *counts, rtx dest, int incr)
729118334Speter{
729218334Speter  enum rtx_code code;
7293117395Skan  rtx note;
729490075Sobrien  const char *fmt;
729518334Speter  int i, j;
729618334Speter
729718334Speter  if (x == 0)
729818334Speter    return;
729918334Speter
730018334Speter  switch (code = GET_CODE (x))
730118334Speter    {
730218334Speter    case REG:
7303169689Skan      if (x != dest)
7304169689Skan	counts[REGNO (x)] += incr;
730518334Speter      return;
730618334Speter
730718334Speter    case PC:
730818334Speter    case CC0:
730918334Speter    case CONST:
731018334Speter    case CONST_INT:
731118334Speter    case CONST_DOUBLE:
731296263Sobrien    case CONST_VECTOR:
731318334Speter    case SYMBOL_REF:
731418334Speter    case LABEL_REF:
731518334Speter      return;
731618334Speter
731790075Sobrien    case CLOBBER:
731850397Sobrien      /* If we are clobbering a MEM, mark any registers inside the address
731950397Sobrien         as being used.  */
7320169689Skan      if (MEM_P (XEXP (x, 0)))
7321169689Skan	count_reg_usage (XEXP (XEXP (x, 0), 0), counts, NULL_RTX, incr);
732250397Sobrien      return;
732350397Sobrien
732418334Speter    case SET:
732518334Speter      /* Unless we are setting a REG, count everything in SET_DEST.  */
7326169689Skan      if (!REG_P (SET_DEST (x)))
7327169689Skan	count_reg_usage (SET_DEST (x), counts, NULL_RTX, incr);
7328169689Skan      count_reg_usage (SET_SRC (x), counts,
7329169689Skan		       dest ? dest : SET_DEST (x),
7330169689Skan		       incr);
733118334Speter      return;
733218334Speter
733318334Speter    case CALL_INSN:
733418334Speter    case INSN:
733518334Speter    case JUMP_INSN:
7336169689Skan    /* We expect dest to be NULL_RTX here.  If the insn may trap, mark
7337169689Skan       this fact by setting DEST to pc_rtx.  */
7338169689Skan      if (flag_non_call_exceptions && may_trap_p (PATTERN (x)))
7339169689Skan	dest = pc_rtx;
7340169689Skan      if (code == CALL_INSN)
7341169689Skan	count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, dest, incr);
7342169689Skan      count_reg_usage (PATTERN (x), counts, dest, incr);
734318334Speter
734418334Speter      /* Things used in a REG_EQUAL note aren't dead since loop may try to
734518334Speter	 use them.  */
734618334Speter
7347117395Skan      note = find_reg_equal_equiv_note (x);
7348117395Skan      if (note)
7349132718Skan	{
7350132718Skan	  rtx eqv = XEXP (note, 0);
7351132718Skan
7352132718Skan	  if (GET_CODE (eqv) == EXPR_LIST)
7353132718Skan	  /* This REG_EQUAL note describes the result of a function call.
7354132718Skan	     Process all the arguments.  */
7355132718Skan	    do
7356132718Skan	      {
7357169689Skan		count_reg_usage (XEXP (eqv, 0), counts, dest, incr);
7358132718Skan		eqv = XEXP (eqv, 1);
7359132718Skan	      }
7360132718Skan	    while (eqv && GET_CODE (eqv) == EXPR_LIST);
7361132718Skan	  else
7362169689Skan	    count_reg_usage (eqv, counts, dest, incr);
7363132718Skan	}
736418334Speter      return;
736518334Speter
7366132718Skan    case EXPR_LIST:
7367132718Skan      if (REG_NOTE_KIND (x) == REG_EQUAL
7368132718Skan	  || (REG_NOTE_KIND (x) != REG_NONNEG && GET_CODE (XEXP (x,0)) == USE)
7369132718Skan	  /* FUNCTION_USAGE expression lists may include (CLOBBER (mem /u)),
7370132718Skan	     involving registers in the address.  */
7371132718Skan	  || GET_CODE (XEXP (x, 0)) == CLOBBER)
7372169689Skan	count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr);
7373132718Skan
7374169689Skan      count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr);
7375132718Skan      return;
7376132718Skan
7377132718Skan    case ASM_OPERANDS:
7378169689Skan      /* If the asm is volatile, then this insn cannot be deleted,
7379169689Skan	 and so the inputs *must* be live.  */
7380169689Skan      if (MEM_VOLATILE_P (x))
7381169689Skan	dest = NULL_RTX;
7382132718Skan      /* Iterate over just the inputs, not the constraints as well.  */
7383132718Skan      for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
7384169689Skan	count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, dest, incr);
7385132718Skan      return;
7386132718Skan
738718334Speter    case INSN_LIST:
7388169689Skan      gcc_unreachable ();
738990075Sobrien
739050397Sobrien    default:
739150397Sobrien      break;
739218334Speter    }
739318334Speter
739418334Speter  fmt = GET_RTX_FORMAT (code);
739518334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
739618334Speter    {
739718334Speter      if (fmt[i] == 'e')
7398169689Skan	count_reg_usage (XEXP (x, i), counts, dest, incr);
739918334Speter      else if (fmt[i] == 'E')
740018334Speter	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
7401169689Skan	  count_reg_usage (XVECEXP (x, i, j), counts, dest, incr);
740218334Speter    }
740318334Speter}
740418334Speter
740590075Sobrien/* Return true if set is live.  */
740690075Sobrienstatic bool
7407132718Skanset_live_p (rtx set, rtx insn ATTRIBUTE_UNUSED, /* Only used with HAVE_cc0.  */
7408132718Skan	    int *counts)
740990075Sobrien{
741090075Sobrien#ifdef HAVE_cc0
741190075Sobrien  rtx tem;
741290075Sobrien#endif
741390075Sobrien
741490075Sobrien  if (set_noop_p (set))
741590075Sobrien    ;
741690075Sobrien
741790075Sobrien#ifdef HAVE_cc0
741890075Sobrien  else if (GET_CODE (SET_DEST (set)) == CC0
741990075Sobrien	   && !side_effects_p (SET_SRC (set))
742090075Sobrien	   && ((tem = next_nonnote_insn (insn)) == 0
742190075Sobrien	       || !INSN_P (tem)
742290075Sobrien	       || !reg_referenced_p (cc0_rtx, PATTERN (tem))))
742390075Sobrien    return false;
742490075Sobrien#endif
7425169689Skan  else if (!REG_P (SET_DEST (set))
742690075Sobrien	   || REGNO (SET_DEST (set)) < FIRST_PSEUDO_REGISTER
742790075Sobrien	   || counts[REGNO (SET_DEST (set))] != 0
7428169689Skan	   || side_effects_p (SET_SRC (set)))
742990075Sobrien    return true;
743090075Sobrien  return false;
743190075Sobrien}
743290075Sobrien
743390075Sobrien/* Return true if insn is live.  */
743490075Sobrien
743590075Sobrienstatic bool
7436132718Skaninsn_live_p (rtx insn, int *counts)
743790075Sobrien{
743890075Sobrien  int i;
7439117395Skan  if (flag_non_call_exceptions && may_trap_p (PATTERN (insn)))
7440117395Skan    return true;
7441117395Skan  else if (GET_CODE (PATTERN (insn)) == SET)
744290075Sobrien    return set_live_p (PATTERN (insn), insn, counts);
744390075Sobrien  else if (GET_CODE (PATTERN (insn)) == PARALLEL)
744490075Sobrien    {
744590075Sobrien      for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
744690075Sobrien	{
744790075Sobrien	  rtx elt = XVECEXP (PATTERN (insn), 0, i);
744890075Sobrien
744990075Sobrien	  if (GET_CODE (elt) == SET)
745090075Sobrien	    {
745190075Sobrien	      if (set_live_p (elt, insn, counts))
745290075Sobrien		return true;
745390075Sobrien	    }
745490075Sobrien	  else if (GET_CODE (elt) != CLOBBER && GET_CODE (elt) != USE)
745590075Sobrien	    return true;
745690075Sobrien	}
745790075Sobrien      return false;
745890075Sobrien    }
745990075Sobrien  else
746090075Sobrien    return true;
746190075Sobrien}
746290075Sobrien
746390075Sobrien/* Return true if libcall is dead as a whole.  */
746490075Sobrien
746590075Sobrienstatic bool
7466132718Skandead_libcall_p (rtx insn, int *counts)
746790075Sobrien{
7468132718Skan  rtx note, set, new;
7469132718Skan
747090075Sobrien  /* See if there's a REG_EQUAL note on this insn and try to
747190075Sobrien     replace the source with the REG_EQUAL expression.
747290075Sobrien
747390075Sobrien     We assume that insns with REG_RETVALs can only be reg->reg
747490075Sobrien     copies at this point.  */
747590075Sobrien  note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
7476132718Skan  if (!note)
7477132718Skan    return false;
747890075Sobrien
7479132718Skan  set = single_set (insn);
7480132718Skan  if (!set)
7481132718Skan    return false;
748290075Sobrien
7483132718Skan  new = simplify_rtx (XEXP (note, 0));
7484132718Skan  if (!new)
7485132718Skan    new = XEXP (note, 0);
7486117395Skan
7487132718Skan  /* While changing insn, we must update the counts accordingly.  */
7488169689Skan  count_reg_usage (insn, counts, NULL_RTX, -1);
7489132718Skan
7490132718Skan  if (validate_change (insn, &SET_SRC (set), new, 0))
7491132718Skan    {
7492169689Skan      count_reg_usage (insn, counts, NULL_RTX, 1);
7493132718Skan      remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
7494132718Skan      remove_note (insn, note);
7495132718Skan      return true;
7496132718Skan    }
7497132718Skan
7498132718Skan  if (CONSTANT_P (new))
7499132718Skan    {
7500132718Skan      new = force_const_mem (GET_MODE (SET_DEST (set)), new);
7501132718Skan      if (new && validate_change (insn, &SET_SRC (set), new, 0))
750290075Sobrien	{
7503169689Skan	  count_reg_usage (insn, counts, NULL_RTX, 1);
750490075Sobrien	  remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
7505117395Skan	  remove_note (insn, note);
750690075Sobrien	  return true;
750790075Sobrien	}
750890075Sobrien    }
7509132718Skan
7510169689Skan  count_reg_usage (insn, counts, NULL_RTX, 1);
751190075Sobrien  return false;
751290075Sobrien}
751390075Sobrien
751418334Speter/* Scan all the insns and delete any that are dead; i.e., they store a register
751518334Speter   that is never used or they copy a register to itself.
751618334Speter
751750397Sobrien   This is used to remove insns made obviously dead by cse, loop or other
751850397Sobrien   optimizations.  It improves the heuristics in loop since it won't try to
751950397Sobrien   move dead invariants out of loops or make givs for dead quantities.  The
752050397Sobrien   remaining passes of the compilation are also sped up.  */
752118334Speter
7522117395Skanint
7523132718Skandelete_trivially_dead_insns (rtx insns, int nreg)
752418334Speter{
752590075Sobrien  int *counts;
752618334Speter  rtx insn, prev;
752750397Sobrien  int in_libcall = 0, dead_libcall = 0;
7528169689Skan  int ndead = 0;
752918334Speter
7530117395Skan  timevar_push (TV_DELETE_TRIVIALLY_DEAD);
753118334Speter  /* First count the number of times each register is used.  */
7532169689Skan  counts = XCNEWVEC (int, nreg);
7533169689Skan  for (insn = insns; insn; insn = NEXT_INSN (insn))
7534169689Skan    if (INSN_P (insn))
7535169689Skan      count_reg_usage (insn, counts, NULL_RTX, 1);
753618334Speter
7537169689Skan  /* Go from the last insn to the first and delete insns that only set unused
7538169689Skan     registers or copy a register to itself.  As we delete an insn, remove
7539169689Skan     usage counts for registers it uses.
7540169689Skan
7541169689Skan     The first jump optimization pass may leave a real insn as the last
7542169689Skan     insn in the function.   We must not skip that insn or we may end
7543169689Skan     up deleting code that is not really dead.  */
7544169689Skan  for (insn = get_last_insn (); insn; insn = prev)
7545117395Skan    {
7546169689Skan      int live_insn = 0;
754718334Speter
7548169689Skan      prev = PREV_INSN (insn);
7549169689Skan      if (!INSN_P (insn))
7550169689Skan	continue;
755118334Speter
7552169689Skan      /* Don't delete any insns that are part of a libcall block unless
7553169689Skan	 we can delete the whole libcall block.
7554169689Skan
7555169689Skan	 Flow or loop might get confused if we did that.  Remember
7556169689Skan	 that we are scanning backwards.  */
7557169689Skan      if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
755890075Sobrien	{
7559169689Skan	  in_libcall = 1;
7560169689Skan	  live_insn = 1;
7561169689Skan	  dead_libcall = dead_libcall_p (insn, counts);
7562169689Skan	}
7563169689Skan      else if (in_libcall)
7564169689Skan	live_insn = ! dead_libcall;
7565169689Skan      else
7566169689Skan	live_insn = insn_live_p (insn, counts);
756718334Speter
7568169689Skan      /* If this is a dead insn, delete it and show registers in it aren't
7569169689Skan	 being used.  */
757090075Sobrien
7571169689Skan      if (! live_insn)
7572169689Skan	{
7573169689Skan	  count_reg_usage (insn, counts, NULL_RTX, -1);
7574169689Skan	  delete_insn_and_edges (insn);
7575169689Skan	  ndead++;
7576169689Skan	}
757790075Sobrien
7578169689Skan      if (in_libcall && find_reg_note (insn, REG_LIBCALL, NULL_RTX))
7579169689Skan	{
7580169689Skan	  in_libcall = 0;
7581169689Skan	  dead_libcall = 0;
758218334Speter	}
7583117395Skan    }
758418334Speter
7585169689Skan  if (dump_file && ndead)
7586169689Skan    fprintf (dump_file, "Deleted %i trivially dead insns\n",
7587169689Skan	     ndead);
758890075Sobrien  /* Clean up.  */
758990075Sobrien  free (counts);
7590117395Skan  timevar_pop (TV_DELETE_TRIVIALLY_DEAD);
7591117395Skan  return ndead;
759218334Speter}
7593132718Skan
7594132718Skan/* This function is called via for_each_rtx.  The argument, NEWREG, is
7595132718Skan   a condition code register with the desired mode.  If we are looking
7596132718Skan   at the same register in a different mode, replace it with
7597132718Skan   NEWREG.  */
7598132718Skan
7599132718Skanstatic int
7600132718Skancse_change_cc_mode (rtx *loc, void *data)
7601132718Skan{
7602169689Skan  struct change_cc_mode_args* args = (struct change_cc_mode_args*)data;
7603132718Skan
7604132718Skan  if (*loc
7605169689Skan      && REG_P (*loc)
7606169689Skan      && REGNO (*loc) == REGNO (args->newreg)
7607169689Skan      && GET_MODE (*loc) != GET_MODE (args->newreg))
7608132718Skan    {
7609169689Skan      validate_change (args->insn, loc, args->newreg, 1);
7610169689Skan
7611132718Skan      return -1;
7612132718Skan    }
7613132718Skan  return 0;
7614132718Skan}
7615132718Skan
7616132718Skan/* Change the mode of any reference to the register REGNO (NEWREG) to
7617169689Skan   GET_MODE (NEWREG) in INSN.  */
7618169689Skan
7619169689Skanstatic void
7620169689Skancse_change_cc_mode_insn (rtx insn, rtx newreg)
7621169689Skan{
7622169689Skan  struct change_cc_mode_args args;
7623169689Skan  int success;
7624169689Skan
7625169689Skan  if (!INSN_P (insn))
7626169689Skan    return;
7627169689Skan
7628169689Skan  args.insn = insn;
7629169689Skan  args.newreg = newreg;
7630169689Skan
7631169689Skan  for_each_rtx (&PATTERN (insn), cse_change_cc_mode, &args);
7632169689Skan  for_each_rtx (&REG_NOTES (insn), cse_change_cc_mode, &args);
7633169689Skan
7634169689Skan  /* If the following assertion was triggered, there is most probably
7635169689Skan     something wrong with the cc_modes_compatible back end function.
7636169689Skan     CC modes only can be considered compatible if the insn - with the mode
7637169689Skan     replaced by any of the compatible modes - can still be recognized.  */
7638169689Skan  success = apply_change_group ();
7639169689Skan  gcc_assert (success);
7640169689Skan}
7641169689Skan
7642169689Skan/* Change the mode of any reference to the register REGNO (NEWREG) to
7643132718Skan   GET_MODE (NEWREG), starting at START.  Stop before END.  Stop at
7644132718Skan   any instruction which modifies NEWREG.  */
7645132718Skan
7646132718Skanstatic void
7647132718Skancse_change_cc_mode_insns (rtx start, rtx end, rtx newreg)
7648132718Skan{
7649132718Skan  rtx insn;
7650132718Skan
7651132718Skan  for (insn = start; insn != end; insn = NEXT_INSN (insn))
7652132718Skan    {
7653132718Skan      if (! INSN_P (insn))
7654132718Skan	continue;
7655132718Skan
7656132718Skan      if (reg_set_p (newreg, insn))
7657132718Skan	return;
7658132718Skan
7659169689Skan      cse_change_cc_mode_insn (insn, newreg);
7660132718Skan    }
7661132718Skan}
7662132718Skan
7663132718Skan/* BB is a basic block which finishes with CC_REG as a condition code
7664132718Skan   register which is set to CC_SRC.  Look through the successors of BB
7665132718Skan   to find blocks which have a single predecessor (i.e., this one),
7666132718Skan   and look through those blocks for an assignment to CC_REG which is
7667132718Skan   equivalent to CC_SRC.  CAN_CHANGE_MODE indicates whether we are
7668132718Skan   permitted to change the mode of CC_SRC to a compatible mode.  This
7669132718Skan   returns VOIDmode if no equivalent assignments were found.
7670132718Skan   Otherwise it returns the mode which CC_SRC should wind up with.
7671132718Skan
7672132718Skan   The main complexity in this function is handling the mode issues.
7673132718Skan   We may have more than one duplicate which we can eliminate, and we
7674132718Skan   try to find a mode which will work for multiple duplicates.  */
7675132718Skan
7676132718Skanstatic enum machine_mode
7677132718Skancse_cc_succs (basic_block bb, rtx cc_reg, rtx cc_src, bool can_change_mode)
7678132718Skan{
7679132718Skan  bool found_equiv;
7680132718Skan  enum machine_mode mode;
7681132718Skan  unsigned int insn_count;
7682132718Skan  edge e;
7683132718Skan  rtx insns[2];
7684132718Skan  enum machine_mode modes[2];
7685132718Skan  rtx last_insns[2];
7686132718Skan  unsigned int i;
7687132718Skan  rtx newreg;
7688169689Skan  edge_iterator ei;
7689132718Skan
7690132718Skan  /* We expect to have two successors.  Look at both before picking
7691132718Skan     the final mode for the comparison.  If we have more successors
7692132718Skan     (i.e., some sort of table jump, although that seems unlikely),
7693132718Skan     then we require all beyond the first two to use the same
7694132718Skan     mode.  */
7695132718Skan
7696132718Skan  found_equiv = false;
7697132718Skan  mode = GET_MODE (cc_src);
7698132718Skan  insn_count = 0;
7699169689Skan  FOR_EACH_EDGE (e, ei, bb->succs)
7700132718Skan    {
7701132718Skan      rtx insn;
7702132718Skan      rtx end;
7703132718Skan
7704132718Skan      if (e->flags & EDGE_COMPLEX)
7705132718Skan	continue;
7706132718Skan
7707169689Skan      if (EDGE_COUNT (e->dest->preds) != 1
7708132718Skan	  || e->dest == EXIT_BLOCK_PTR)
7709132718Skan	continue;
7710132718Skan
7711132718Skan      end = NEXT_INSN (BB_END (e->dest));
7712132718Skan      for (insn = BB_HEAD (e->dest); insn != end; insn = NEXT_INSN (insn))
7713132718Skan	{
7714132718Skan	  rtx set;
7715132718Skan
7716132718Skan	  if (! INSN_P (insn))
7717132718Skan	    continue;
7718132718Skan
7719132718Skan	  /* If CC_SRC is modified, we have to stop looking for
7720132718Skan	     something which uses it.  */
7721132718Skan	  if (modified_in_p (cc_src, insn))
7722132718Skan	    break;
7723132718Skan
7724132718Skan	  /* Check whether INSN sets CC_REG to CC_SRC.  */
7725132718Skan	  set = single_set (insn);
7726132718Skan	  if (set
7727169689Skan	      && REG_P (SET_DEST (set))
7728132718Skan	      && REGNO (SET_DEST (set)) == REGNO (cc_reg))
7729132718Skan	    {
7730132718Skan	      bool found;
7731132718Skan	      enum machine_mode set_mode;
7732132718Skan	      enum machine_mode comp_mode;
7733132718Skan
7734132718Skan	      found = false;
7735132718Skan	      set_mode = GET_MODE (SET_SRC (set));
7736132718Skan	      comp_mode = set_mode;
7737132718Skan	      if (rtx_equal_p (cc_src, SET_SRC (set)))
7738132718Skan		found = true;
7739132718Skan	      else if (GET_CODE (cc_src) == COMPARE
7740132718Skan		       && GET_CODE (SET_SRC (set)) == COMPARE
7741132718Skan		       && mode != set_mode
7742132718Skan		       && rtx_equal_p (XEXP (cc_src, 0),
7743132718Skan				       XEXP (SET_SRC (set), 0))
7744132718Skan		       && rtx_equal_p (XEXP (cc_src, 1),
7745132718Skan				       XEXP (SET_SRC (set), 1)))
7746132718Skan
7747132718Skan		{
7748169689Skan		  comp_mode = targetm.cc_modes_compatible (mode, set_mode);
7749132718Skan		  if (comp_mode != VOIDmode
7750132718Skan		      && (can_change_mode || comp_mode == mode))
7751132718Skan		    found = true;
7752132718Skan		}
7753132718Skan
7754132718Skan	      if (found)
7755132718Skan		{
7756132718Skan		  found_equiv = true;
7757132718Skan		  if (insn_count < ARRAY_SIZE (insns))
7758132718Skan		    {
7759132718Skan		      insns[insn_count] = insn;
7760132718Skan		      modes[insn_count] = set_mode;
7761132718Skan		      last_insns[insn_count] = end;
7762132718Skan		      ++insn_count;
7763132718Skan
7764132718Skan		      if (mode != comp_mode)
7765132718Skan			{
7766169689Skan			  gcc_assert (can_change_mode);
7767132718Skan			  mode = comp_mode;
7768169689Skan
7769169689Skan			  /* The modified insn will be re-recognized later.  */
7770132718Skan			  PUT_MODE (cc_src, mode);
7771132718Skan			}
7772132718Skan		    }
7773132718Skan		  else
7774132718Skan		    {
7775132718Skan		      if (set_mode != mode)
7776132718Skan			{
7777132718Skan			  /* We found a matching expression in the
7778132718Skan			     wrong mode, but we don't have room to
7779132718Skan			     store it in the array.  Punt.  This case
7780132718Skan			     should be rare.  */
7781132718Skan			  break;
7782132718Skan			}
7783132718Skan		      /* INSN sets CC_REG to a value equal to CC_SRC
7784132718Skan			 with the right mode.  We can simply delete
7785132718Skan			 it.  */
7786132718Skan		      delete_insn (insn);
7787132718Skan		    }
7788132718Skan
7789132718Skan		  /* We found an instruction to delete.  Keep looking,
7790132718Skan		     in the hopes of finding a three-way jump.  */
7791132718Skan		  continue;
7792132718Skan		}
7793132718Skan
7794132718Skan	      /* We found an instruction which sets the condition
7795132718Skan		 code, so don't look any farther.  */
7796132718Skan	      break;
7797132718Skan	    }
7798132718Skan
7799132718Skan	  /* If INSN sets CC_REG in some other way, don't look any
7800132718Skan	     farther.  */
7801132718Skan	  if (reg_set_p (cc_reg, insn))
7802132718Skan	    break;
7803132718Skan	}
7804132718Skan
7805132718Skan      /* If we fell off the bottom of the block, we can keep looking
7806132718Skan	 through successors.  We pass CAN_CHANGE_MODE as false because
7807132718Skan	 we aren't prepared to handle compatibility between the
7808132718Skan	 further blocks and this block.  */
7809132718Skan      if (insn == end)
7810132718Skan	{
7811132718Skan	  enum machine_mode submode;
7812132718Skan
7813132718Skan	  submode = cse_cc_succs (e->dest, cc_reg, cc_src, false);
7814132718Skan	  if (submode != VOIDmode)
7815132718Skan	    {
7816169689Skan	      gcc_assert (submode == mode);
7817132718Skan	      found_equiv = true;
7818132718Skan	      can_change_mode = false;
7819132718Skan	    }
7820132718Skan	}
7821132718Skan    }
7822132718Skan
7823132718Skan  if (! found_equiv)
7824132718Skan    return VOIDmode;
7825132718Skan
7826132718Skan  /* Now INSN_COUNT is the number of instructions we found which set
7827132718Skan     CC_REG to a value equivalent to CC_SRC.  The instructions are in
7828132718Skan     INSNS.  The modes used by those instructions are in MODES.  */
7829132718Skan
7830132718Skan  newreg = NULL_RTX;
7831132718Skan  for (i = 0; i < insn_count; ++i)
7832132718Skan    {
7833132718Skan      if (modes[i] != mode)
7834132718Skan	{
7835132718Skan	  /* We need to change the mode of CC_REG in INSNS[i] and
7836132718Skan	     subsequent instructions.  */
7837132718Skan	  if (! newreg)
7838132718Skan	    {
7839132718Skan	      if (GET_MODE (cc_reg) == mode)
7840132718Skan		newreg = cc_reg;
7841132718Skan	      else
7842132718Skan		newreg = gen_rtx_REG (mode, REGNO (cc_reg));
7843132718Skan	    }
7844132718Skan	  cse_change_cc_mode_insns (NEXT_INSN (insns[i]), last_insns[i],
7845132718Skan				    newreg);
7846132718Skan	}
7847132718Skan
7848132718Skan      delete_insn (insns[i]);
7849132718Skan    }
7850132718Skan
7851132718Skan  return mode;
7852132718Skan}
7853132718Skan
7854132718Skan/* If we have a fixed condition code register (or two), walk through
7855132718Skan   the instructions and try to eliminate duplicate assignments.  */
7856132718Skan
7857169689Skanstatic void
7858132718Skancse_condition_code_reg (void)
7859132718Skan{
7860132718Skan  unsigned int cc_regno_1;
7861132718Skan  unsigned int cc_regno_2;
7862132718Skan  rtx cc_reg_1;
7863132718Skan  rtx cc_reg_2;
7864132718Skan  basic_block bb;
7865132718Skan
7866169689Skan  if (! targetm.fixed_condition_code_regs (&cc_regno_1, &cc_regno_2))
7867132718Skan    return;
7868132718Skan
7869132718Skan  cc_reg_1 = gen_rtx_REG (CCmode, cc_regno_1);
7870132718Skan  if (cc_regno_2 != INVALID_REGNUM)
7871132718Skan    cc_reg_2 = gen_rtx_REG (CCmode, cc_regno_2);
7872132718Skan  else
7873132718Skan    cc_reg_2 = NULL_RTX;
7874132718Skan
7875132718Skan  FOR_EACH_BB (bb)
7876132718Skan    {
7877132718Skan      rtx last_insn;
7878132718Skan      rtx cc_reg;
7879132718Skan      rtx insn;
7880132718Skan      rtx cc_src_insn;
7881132718Skan      rtx cc_src;
7882132718Skan      enum machine_mode mode;
7883132718Skan      enum machine_mode orig_mode;
7884132718Skan
7885132718Skan      /* Look for blocks which end with a conditional jump based on a
7886132718Skan	 condition code register.  Then look for the instruction which
7887132718Skan	 sets the condition code register.  Then look through the
7888132718Skan	 successor blocks for instructions which set the condition
7889132718Skan	 code register to the same value.  There are other possible
7890132718Skan	 uses of the condition code register, but these are by far the
7891132718Skan	 most common and the ones which we are most likely to be able
7892132718Skan	 to optimize.  */
7893132718Skan
7894132718Skan      last_insn = BB_END (bb);
7895169689Skan      if (!JUMP_P (last_insn))
7896132718Skan	continue;
7897132718Skan
7898132718Skan      if (reg_referenced_p (cc_reg_1, PATTERN (last_insn)))
7899132718Skan	cc_reg = cc_reg_1;
7900132718Skan      else if (cc_reg_2 && reg_referenced_p (cc_reg_2, PATTERN (last_insn)))
7901132718Skan	cc_reg = cc_reg_2;
7902132718Skan      else
7903132718Skan	continue;
7904132718Skan
7905132718Skan      cc_src_insn = NULL_RTX;
7906132718Skan      cc_src = NULL_RTX;
7907132718Skan      for (insn = PREV_INSN (last_insn);
7908132718Skan	   insn && insn != PREV_INSN (BB_HEAD (bb));
7909132718Skan	   insn = PREV_INSN (insn))
7910132718Skan	{
7911132718Skan	  rtx set;
7912132718Skan
7913132718Skan	  if (! INSN_P (insn))
7914132718Skan	    continue;
7915132718Skan	  set = single_set (insn);
7916132718Skan	  if (set
7917169689Skan	      && REG_P (SET_DEST (set))
7918132718Skan	      && REGNO (SET_DEST (set)) == REGNO (cc_reg))
7919132718Skan	    {
7920132718Skan	      cc_src_insn = insn;
7921132718Skan	      cc_src = SET_SRC (set);
7922132718Skan	      break;
7923132718Skan	    }
7924132718Skan	  else if (reg_set_p (cc_reg, insn))
7925132718Skan	    break;
7926132718Skan	}
7927132718Skan
7928132718Skan      if (! cc_src_insn)
7929132718Skan	continue;
7930132718Skan
7931132718Skan      if (modified_between_p (cc_src, cc_src_insn, NEXT_INSN (last_insn)))
7932132718Skan	continue;
7933132718Skan
7934132718Skan      /* Now CC_REG is a condition code register used for a
7935132718Skan	 conditional jump at the end of the block, and CC_SRC, in
7936132718Skan	 CC_SRC_INSN, is the value to which that condition code
7937132718Skan	 register is set, and CC_SRC is still meaningful at the end of
7938132718Skan	 the basic block.  */
7939132718Skan
7940132718Skan      orig_mode = GET_MODE (cc_src);
7941132718Skan      mode = cse_cc_succs (bb, cc_reg, cc_src, true);
7942132718Skan      if (mode != VOIDmode)
7943132718Skan	{
7944169689Skan	  gcc_assert (mode == GET_MODE (cc_src));
7945132718Skan	  if (mode != orig_mode)
7946132718Skan	    {
7947132718Skan	      rtx newreg = gen_rtx_REG (mode, REGNO (cc_reg));
7948132718Skan
7949169689Skan	      cse_change_cc_mode_insn (cc_src_insn, newreg);
7950132718Skan
7951132718Skan	      /* Do the same in the following insns that use the
7952132718Skan		 current value of CC_REG within BB.  */
7953132718Skan	      cse_change_cc_mode_insns (NEXT_INSN (cc_src_insn),
7954132718Skan					NEXT_INSN (last_insn),
7955132718Skan					newreg);
7956132718Skan	    }
7957132718Skan	}
7958132718Skan    }
7959132718Skan}
7960169689Skan
7961169689Skan
7962169689Skan/* Perform common subexpression elimination.  Nonzero value from
7963169689Skan   `cse_main' means that jumps were simplified and some code may now
7964169689Skan   be unreachable, so do jump optimization again.  */
7965169689Skanstatic bool
7966169689Skangate_handle_cse (void)
7967169689Skan{
7968169689Skan  return optimize > 0;
7969169689Skan}
7970169689Skan
7971169689Skanstatic unsigned int
7972169689Skanrest_of_handle_cse (void)
7973169689Skan{
7974169689Skan  int tem;
7975169689Skan
7976169689Skan  if (dump_file)
7977169689Skan    dump_flow_info (dump_file, dump_flags);
7978169689Skan
7979169689Skan  reg_scan (get_insns (), max_reg_num ());
7980169689Skan
7981169689Skan  tem = cse_main (get_insns (), max_reg_num ());
7982169689Skan  if (tem)
7983169689Skan    rebuild_jump_labels (get_insns ());
7984169689Skan  if (purge_all_dead_edges ())
7985169689Skan    delete_unreachable_blocks ();
7986169689Skan
7987169689Skan  delete_trivially_dead_insns (get_insns (), max_reg_num ());
7988169689Skan
7989169689Skan  /* If we are not running more CSE passes, then we are no longer
7990169689Skan     expecting CSE to be run.  But always rerun it in a cheap mode.  */
7991169689Skan  cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse;
7992169689Skan
7993169689Skan  if (tem)
7994169689Skan    delete_dead_jumptables ();
7995169689Skan
7996169689Skan  if (tem || optimize > 1)
7997169689Skan    cleanup_cfg (CLEANUP_EXPENSIVE);
7998169689Skan  return 0;
7999169689Skan}
8000169689Skan
8001169689Skanstruct tree_opt_pass pass_cse =
8002169689Skan{
8003169689Skan  "cse1",                               /* name */
8004169689Skan  gate_handle_cse,                      /* gate */
8005169689Skan  rest_of_handle_cse,			/* execute */
8006169689Skan  NULL,                                 /* sub */
8007169689Skan  NULL,                                 /* next */
8008169689Skan  0,                                    /* static_pass_number */
8009169689Skan  TV_CSE,                               /* tv_id */
8010169689Skan  0,                                    /* properties_required */
8011169689Skan  0,                                    /* properties_provided */
8012169689Skan  0,                                    /* properties_destroyed */
8013169689Skan  0,                                    /* todo_flags_start */
8014169689Skan  TODO_dump_func |
8015169689Skan  TODO_ggc_collect,                     /* todo_flags_finish */
8016169689Skan  's'                                   /* letter */
8017169689Skan};
8018169689Skan
8019169689Skan
8020169689Skanstatic bool
8021169689Skangate_handle_cse2 (void)
8022169689Skan{
8023169689Skan  return optimize > 0 && flag_rerun_cse_after_loop;
8024169689Skan}
8025169689Skan
8026169689Skan/* Run second CSE pass after loop optimizations.  */
8027169689Skanstatic unsigned int
8028169689Skanrest_of_handle_cse2 (void)
8029169689Skan{
8030169689Skan  int tem;
8031169689Skan
8032169689Skan  if (dump_file)
8033169689Skan    dump_flow_info (dump_file, dump_flags);
8034169689Skan
8035169689Skan  tem = cse_main (get_insns (), max_reg_num ());
8036169689Skan
8037169689Skan  /* Run a pass to eliminate duplicated assignments to condition code
8038169689Skan     registers.  We have to run this after bypass_jumps, because it
8039169689Skan     makes it harder for that pass to determine whether a jump can be
8040169689Skan     bypassed safely.  */
8041169689Skan  cse_condition_code_reg ();
8042169689Skan
8043169689Skan  purge_all_dead_edges ();
8044169689Skan  delete_trivially_dead_insns (get_insns (), max_reg_num ());
8045169689Skan
8046169689Skan  if (tem)
8047169689Skan    {
8048169689Skan      timevar_push (TV_JUMP);
8049169689Skan      rebuild_jump_labels (get_insns ());
8050169689Skan      delete_dead_jumptables ();
8051169689Skan      cleanup_cfg (CLEANUP_EXPENSIVE);
8052169689Skan      timevar_pop (TV_JUMP);
8053169689Skan    }
8054169689Skan  reg_scan (get_insns (), max_reg_num ());
8055169689Skan  cse_not_expected = 1;
8056169689Skan  return 0;
8057169689Skan}
8058169689Skan
8059169689Skan
8060169689Skanstruct tree_opt_pass pass_cse2 =
8061169689Skan{
8062169689Skan  "cse2",                               /* name */
8063169689Skan  gate_handle_cse2,                     /* gate */
8064169689Skan  rest_of_handle_cse2,			/* execute */
8065169689Skan  NULL,                                 /* sub */
8066169689Skan  NULL,                                 /* next */
8067169689Skan  0,                                    /* static_pass_number */
8068169689Skan  TV_CSE2,                              /* tv_id */
8069169689Skan  0,                                    /* properties_required */
8070169689Skan  0,                                    /* properties_provided */
8071169689Skan  0,                                    /* properties_destroyed */
8072169689Skan  0,                                    /* todo_flags_start */
8073169689Skan  TODO_dump_func |
8074169689Skan  TODO_ggc_collect,                     /* todo_flags_finish */
8075169689Skan  't'                                   /* letter */
8076169689Skan};
8077169689Skan
8078