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); 586235623Spfgstatic void remove_pseudo_from_table (rtx, unsigned); 587235623Spfgstatic 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 = ®_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 1385235623Spfg/* Same as above, but X is a pseudo-register. */ 1386235623Spfg 1387235623Spfgstatic void 1388235623Spfgremove_pseudo_from_table (rtx x, unsigned int hash) 1389235623Spfg{ 1390235623Spfg struct table_elt *elt; 1391235623Spfg 1392235623Spfg /* Because a pseudo-register can be referenced in more than one 1393235623Spfg mode, we might have to remove more than one table entry. */ 1394235623Spfg while ((elt = lookup_for_remove (x, hash, VOIDmode))) 1395235623Spfg remove_from_table (elt, hash); 1396235623Spfg} 1397235623Spfg 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 1724235623Spfg if (REG_P (exp) && REGNO (exp) >= FIRST_PSEUDO_REGISTER) 1725235623Spfg remove_pseudo_from_table (exp, hash); 1726235623Spfg else 1727235623Spfg 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) 1823235623Spfg 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 (®_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