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