cse.c revision 48743
118334Speter/* Common subexpression elimination for GNU compiler. 218334Speter Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. 318334Speter 418334SpeterThis file is part of GNU CC. 518334Speter 618334SpeterGNU CC is free software; you can redistribute it and/or modify 718334Speterit under the terms of the GNU General Public License as published by 818334Speterthe Free Software Foundation; either version 2, or (at your option) 918334Speterany later version. 1018334Speter 1118334SpeterGNU CC is distributed in the hope that it will be useful, 1218334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of 1318334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1418334SpeterGNU General Public License for more details. 1518334Speter 1618334SpeterYou should have received a copy of the GNU General Public License 1718334Speteralong with GNU CC; see the file COPYING. If not, write to 1818334Speterthe Free Software Foundation, 59 Temple Place - Suite 330, 1918334SpeterBoston, MA 02111-1307, USA. */ 2018334Speter 2118334Speter 2218334Speter#include "config.h" 2318334Speter/* Must precede rtl.h for FFS. */ 2418334Speter#include <stdio.h> 2518334Speter 2618334Speter#include "rtl.h" 2718334Speter#include "regs.h" 2818334Speter#include "hard-reg-set.h" 2918334Speter#include "flags.h" 3018334Speter#include "real.h" 3118334Speter#include "insn-config.h" 3218334Speter#include "recog.h" 3318334Speter 3418334Speter#include <setjmp.h> 3518334Speter 3618334Speter/* The basic idea of common subexpression elimination is to go 3718334Speter through the code, keeping a record of expressions that would 3818334Speter have the same value at the current scan point, and replacing 3918334Speter expressions encountered with the cheapest equivalent expression. 4018334Speter 4118334Speter It is too complicated to keep track of the different possibilities 4218334Speter when control paths merge; so, at each label, we forget all that is 4318334Speter known and start fresh. This can be described as processing each 4418334Speter basic block separately. Note, however, that these are not quite 4518334Speter the same as the basic blocks found by a later pass and used for 4618334Speter data flow analysis and register packing. We do not need to start fresh 4718334Speter after a conditional jump instruction if there is no label there. 4818334Speter 4918334Speter We use two data structures to record the equivalent expressions: 5018334Speter a hash table for most expressions, and several vectors together 5118334Speter with "quantity numbers" to record equivalent (pseudo) registers. 5218334Speter 5318334Speter The use of the special data structure for registers is desirable 5418334Speter because it is faster. It is possible because registers references 5518334Speter contain a fairly small number, the register number, taken from 5618334Speter a contiguously allocated series, and two register references are 5718334Speter identical if they have the same number. General expressions 5818334Speter do not have any such thing, so the only way to retrieve the 5918334Speter information recorded on an expression other than a register 6018334Speter is to keep it in a hash table. 6118334Speter 6218334SpeterRegisters and "quantity numbers": 6318334Speter 6418334Speter At the start of each basic block, all of the (hardware and pseudo) 6518334Speter registers used in the function are given distinct quantity 6618334Speter numbers to indicate their contents. During scan, when the code 6718334Speter copies one register into another, we copy the quantity number. 6818334Speter When a register is loaded in any other way, we allocate a new 6918334Speter quantity number to describe the value generated by this operation. 7018334Speter `reg_qty' records what quantity a register is currently thought 7118334Speter of as containing. 7218334Speter 7318334Speter All real quantity numbers are greater than or equal to `max_reg'. 7418334Speter If register N has not been assigned a quantity, reg_qty[N] will equal N. 7518334Speter 7618334Speter Quantity numbers below `max_reg' do not exist and none of the `qty_...' 7718334Speter variables should be referenced with an index below `max_reg'. 7818334Speter 7918334Speter We also maintain a bidirectional chain of registers for each 8018334Speter quantity number. `qty_first_reg', `qty_last_reg', 8118334Speter `reg_next_eqv' and `reg_prev_eqv' hold these chains. 8218334Speter 8318334Speter The first register in a chain is the one whose lifespan is least local. 8418334Speter Among equals, it is the one that was seen first. 8518334Speter We replace any equivalent register with that one. 8618334Speter 8718334Speter If two registers have the same quantity number, it must be true that 8818334Speter REG expressions with `qty_mode' must be in the hash table for both 8918334Speter registers and must be in the same class. 9018334Speter 9118334Speter The converse is not true. Since hard registers may be referenced in 9218334Speter any mode, two REG expressions might be equivalent in the hash table 9318334Speter but not have the same quantity number if the quantity number of one 9418334Speter of the registers is not the same mode as those expressions. 9518334Speter 9618334SpeterConstants and quantity numbers 9718334Speter 9818334Speter When a quantity has a known constant value, that value is stored 9918334Speter in the appropriate element of qty_const. This is in addition to 10018334Speter putting the constant in the hash table as is usual for non-regs. 10118334Speter 10218334Speter Whether a reg or a constant is preferred is determined by the configuration 10318334Speter macro CONST_COSTS and will often depend on the constant value. In any 10418334Speter event, expressions containing constants can be simplified, by fold_rtx. 10518334Speter 10618334Speter When a quantity has a known nearly constant value (such as an address 10718334Speter of a stack slot), that value is stored in the appropriate element 10818334Speter of qty_const. 10918334Speter 11018334Speter Integer constants don't have a machine mode. However, cse 11118334Speter determines the intended machine mode from the destination 11218334Speter of the instruction that moves the constant. The machine mode 11318334Speter is recorded in the hash table along with the actual RTL 11418334Speter constant expression so that different modes are kept separate. 11518334Speter 11618334SpeterOther expressions: 11718334Speter 11818334Speter To record known equivalences among expressions in general 11918334Speter we use a hash table called `table'. It has a fixed number of buckets 12018334Speter that contain chains of `struct table_elt' elements for expressions. 12118334Speter These chains connect the elements whose expressions have the same 12218334Speter hash codes. 12318334Speter 12418334Speter Other chains through the same elements connect the elements which 12518334Speter currently have equivalent values. 12618334Speter 12718334Speter Register references in an expression are canonicalized before hashing 12818334Speter the expression. This is done using `reg_qty' and `qty_first_reg'. 12918334Speter The hash code of a register reference is computed using the quantity 13018334Speter number, not the register number. 13118334Speter 13218334Speter When the value of an expression changes, it is necessary to remove from the 13318334Speter hash table not just that expression but all expressions whose values 13418334Speter could be different as a result. 13518334Speter 13618334Speter 1. If the value changing is in memory, except in special cases 13718334Speter ANYTHING referring to memory could be changed. That is because 13818334Speter nobody knows where a pointer does not point. 13918334Speter The function `invalidate_memory' removes what is necessary. 14018334Speter 14118334Speter The special cases are when the address is constant or is 14218334Speter a constant plus a fixed register such as the frame pointer 14318334Speter or a static chain pointer. When such addresses are stored in, 14418334Speter we can tell exactly which other such addresses must be invalidated 14518334Speter due to overlap. `invalidate' does this. 14618334Speter All expressions that refer to non-constant 14718334Speter memory addresses are also invalidated. `invalidate_memory' does this. 14818334Speter 14918334Speter 2. If the value changing is a register, all expressions 15018334Speter containing references to that register, and only those, 15118334Speter must be removed. 15218334Speter 15318334Speter Because searching the entire hash table for expressions that contain 15418334Speter a register is very slow, we try to figure out when it isn't necessary. 15518334Speter Precisely, this is necessary only when expressions have been 15618334Speter entered in the hash table using this register, and then the value has 15718334Speter changed, and then another expression wants to be added to refer to 15818334Speter the register's new value. This sequence of circumstances is rare 15918334Speter within any one basic block. 16018334Speter 16118334Speter The vectors `reg_tick' and `reg_in_table' are used to detect this case. 16218334Speter reg_tick[i] is incremented whenever a value is stored in register i. 16318334Speter reg_in_table[i] holds -1 if no references to register i have been 16418334Speter entered in the table; otherwise, it contains the value reg_tick[i] had 16518334Speter when the references were entered. If we want to enter a reference 16618334Speter and reg_in_table[i] != reg_tick[i], we must scan and remove old references. 16718334Speter Until we want to enter a new entry, the mere fact that the two vectors 16818334Speter don't match makes the entries be ignored if anyone tries to match them. 16918334Speter 17018334Speter Registers themselves are entered in the hash table as well as in 17118334Speter the equivalent-register chains. However, the vectors `reg_tick' 17218334Speter and `reg_in_table' do not apply to expressions which are simple 17318334Speter register references. These expressions are removed from the table 17418334Speter immediately when they become invalid, and this can be done even if 17518334Speter we do not immediately search for all the expressions that refer to 17618334Speter the register. 17718334Speter 17818334Speter A CLOBBER rtx in an instruction invalidates its operand for further 17918334Speter reuse. A CLOBBER or SET rtx whose operand is a MEM:BLK 18018334Speter invalidates everything that resides in memory. 18118334Speter 18218334SpeterRelated expressions: 18318334Speter 18418334Speter Constant expressions that differ only by an additive integer 18518334Speter are called related. When a constant expression is put in 18618334Speter the table, the related expression with no constant term 18718334Speter is also entered. These are made to point at each other 18818334Speter so that it is possible to find out if there exists any 18918334Speter register equivalent to an expression related to a given expression. */ 19018334Speter 19118334Speter/* One plus largest register number used in this function. */ 19218334Speter 19318334Speterstatic int max_reg; 19418334Speter 19518334Speter/* Length of vectors indexed by quantity number. 19618334Speter We know in advance we will not need a quantity number this big. */ 19718334Speter 19818334Speterstatic int max_qty; 19918334Speter 20018334Speter/* Next quantity number to be allocated. 20118334Speter This is 1 + the largest number needed so far. */ 20218334Speter 20318334Speterstatic int next_qty; 20418334Speter 20518334Speter/* Indexed by quantity number, gives the first (or last) (pseudo) register 20618334Speter in the chain of registers that currently contain this quantity. */ 20718334Speter 20818334Speterstatic int *qty_first_reg; 20918334Speterstatic int *qty_last_reg; 21018334Speter 21118334Speter/* Index by quantity number, gives the mode of the quantity. */ 21218334Speter 21318334Speterstatic enum machine_mode *qty_mode; 21418334Speter 21518334Speter/* Indexed by quantity number, gives the rtx of the constant value of the 21618334Speter quantity, or zero if it does not have a known value. 21718334Speter A sum of the frame pointer (or arg pointer) plus a constant 21818334Speter can also be entered here. */ 21918334Speter 22018334Speterstatic rtx *qty_const; 22118334Speter 22218334Speter/* Indexed by qty number, gives the insn that stored the constant value 22318334Speter recorded in `qty_const'. */ 22418334Speter 22518334Speterstatic rtx *qty_const_insn; 22618334Speter 22718334Speter/* The next three variables are used to track when a comparison between a 22818334Speter quantity and some constant or register has been passed. In that case, we 22918334Speter know the results of the comparison in case we see it again. These variables 23018334Speter record a comparison that is known to be true. */ 23118334Speter 23218334Speter/* Indexed by qty number, gives the rtx code of a comparison with a known 23318334Speter result involving this quantity. If none, it is UNKNOWN. */ 23418334Speterstatic enum rtx_code *qty_comparison_code; 23518334Speter 23618334Speter/* Indexed by qty number, gives the constant being compared against in a 23718334Speter comparison of known result. If no such comparison, it is undefined. 23818334Speter If the comparison is not with a constant, it is zero. */ 23918334Speter 24018334Speterstatic rtx *qty_comparison_const; 24118334Speter 24218334Speter/* Indexed by qty number, gives the quantity being compared against in a 24318334Speter comparison of known result. If no such comparison, if it undefined. 24418334Speter If the comparison is not with a register, it is -1. */ 24518334Speter 24618334Speterstatic int *qty_comparison_qty; 24718334Speter 24818334Speter#ifdef HAVE_cc0 24918334Speter/* For machines that have a CC0, we do not record its value in the hash 25018334Speter table since its use is guaranteed to be the insn immediately following 25118334Speter its definition and any other insn is presumed to invalidate it. 25218334Speter 25318334Speter Instead, we store below the value last assigned to CC0. If it should 25418334Speter happen to be a constant, it is stored in preference to the actual 25518334Speter assigned value. In case it is a constant, we store the mode in which 25618334Speter the constant should be interpreted. */ 25718334Speter 25818334Speterstatic rtx prev_insn_cc0; 25918334Speterstatic enum machine_mode prev_insn_cc0_mode; 26018334Speter#endif 26118334Speter 26218334Speter/* Previous actual insn. 0 if at first insn of basic block. */ 26318334Speter 26418334Speterstatic rtx prev_insn; 26518334Speter 26618334Speter/* Insn being scanned. */ 26718334Speter 26818334Speterstatic rtx this_insn; 26918334Speter 27018334Speter/* Index by (pseudo) register number, gives the quantity number 27118334Speter of the register's current contents. */ 27218334Speter 27318334Speterstatic int *reg_qty; 27418334Speter 27518334Speter/* Index by (pseudo) register number, gives the number of the next (or 27618334Speter previous) (pseudo) register in the chain of registers sharing the same 27718334Speter value. 27818334Speter 27918334Speter Or -1 if this register is at the end of the chain. 28018334Speter 28118334Speter If reg_qty[N] == N, reg_next_eqv[N] is undefined. */ 28218334Speter 28318334Speterstatic int *reg_next_eqv; 28418334Speterstatic int *reg_prev_eqv; 28518334Speter 28618334Speter/* Index by (pseudo) register number, gives the number of times 28718334Speter that register has been altered in the current basic block. */ 28818334Speter 28918334Speterstatic int *reg_tick; 29018334Speter 29118334Speter/* Index by (pseudo) register number, gives the reg_tick value at which 29218334Speter rtx's containing this register are valid in the hash table. 29318334Speter If this does not equal the current reg_tick value, such expressions 29418334Speter existing in the hash table are invalid. 29518334Speter If this is -1, no expressions containing this register have been 29618334Speter entered in the table. */ 29718334Speter 29818334Speterstatic int *reg_in_table; 29918334Speter 30018334Speter/* A HARD_REG_SET containing all the hard registers for which there is 30118334Speter currently a REG expression in the hash table. Note the difference 30218334Speter from the above variables, which indicate if the REG is mentioned in some 30318334Speter expression in the table. */ 30418334Speter 30518334Speterstatic HARD_REG_SET hard_regs_in_table; 30618334Speter 30718334Speter/* A HARD_REG_SET containing all the hard registers that are invalidated 30818334Speter by a CALL_INSN. */ 30918334Speter 31018334Speterstatic HARD_REG_SET regs_invalidated_by_call; 31118334Speter 31218334Speter/* Two vectors of ints: 31318334Speter one containing max_reg -1's; the other max_reg + 500 (an approximation 31418334Speter for max_qty) elements where element i contains i. 31518334Speter These are used to initialize various other vectors fast. */ 31618334Speter 31718334Speterstatic int *all_minus_one; 31818334Speterstatic int *consec_ints; 31918334Speter 32018334Speter/* CUID of insn that starts the basic block currently being cse-processed. */ 32118334Speter 32218334Speterstatic int cse_basic_block_start; 32318334Speter 32418334Speter/* CUID of insn that ends the basic block currently being cse-processed. */ 32518334Speter 32618334Speterstatic int cse_basic_block_end; 32718334Speter 32818334Speter/* Vector mapping INSN_UIDs to cuids. 32918334Speter The cuids are like uids but increase monotonically always. 33018334Speter We use them to see whether a reg is used outside a given basic block. */ 33118334Speter 33218334Speterstatic int *uid_cuid; 33318334Speter 33418334Speter/* Highest UID in UID_CUID. */ 33518334Speterstatic int max_uid; 33618334Speter 33718334Speter/* Get the cuid of an insn. */ 33818334Speter 33918334Speter#define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)]) 34018334Speter 34118334Speter/* Nonzero if cse has altered conditional jump insns 34218334Speter in such a way that jump optimization should be redone. */ 34318334Speter 34418334Speterstatic int cse_jumps_altered; 34518334Speter 34618334Speter/* Nonzero if we put a LABEL_REF into the hash table. Since we may have put 34718334Speter it into an INSN without a REG_LABEL, we have to rerun jump after CSE 34818334Speter to put in the note. */ 34918334Speterstatic int recorded_label_ref; 35018334Speter 35118334Speter/* canon_hash stores 1 in do_not_record 35218334Speter if it notices a reference to CC0, PC, or some other volatile 35318334Speter subexpression. */ 35418334Speter 35518334Speterstatic int do_not_record; 35618334Speter 35718334Speter#ifdef LOAD_EXTEND_OP 35818334Speter 35918334Speter/* Scratch rtl used when looking for load-extended copy of a MEM. */ 36018334Speterstatic rtx memory_extend_rtx; 36118334Speter#endif 36218334Speter 36318334Speter/* canon_hash stores 1 in hash_arg_in_memory 36418334Speter if it notices a reference to memory within the expression being hashed. */ 36518334Speter 36618334Speterstatic int hash_arg_in_memory; 36718334Speter 36818334Speter/* canon_hash stores 1 in hash_arg_in_struct 36918334Speter if it notices a reference to memory that's part of a structure. */ 37018334Speter 37118334Speterstatic int hash_arg_in_struct; 37218334Speter 37318334Speter/* The hash table contains buckets which are chains of `struct table_elt's, 37418334Speter each recording one expression's information. 37518334Speter That expression is in the `exp' field. 37618334Speter 37718334Speter Those elements with the same hash code are chained in both directions 37818334Speter through the `next_same_hash' and `prev_same_hash' fields. 37918334Speter 38018334Speter Each set of expressions with equivalent values 38118334Speter are on a two-way chain through the `next_same_value' 38218334Speter and `prev_same_value' fields, and all point with 38318334Speter the `first_same_value' field at the first element in 38418334Speter that chain. The chain is in order of increasing cost. 38518334Speter Each element's cost value is in its `cost' field. 38618334Speter 38718334Speter The `in_memory' field is nonzero for elements that 38818334Speter involve any reference to memory. These elements are removed 38918334Speter whenever a write is done to an unidentified location in memory. 39018334Speter To be safe, we assume that a memory address is unidentified unless 39118334Speter the address is either a symbol constant or a constant plus 39218334Speter the frame pointer or argument pointer. 39318334Speter 39418334Speter The `in_struct' field is nonzero for elements that 39518334Speter involve any reference to memory inside a structure or array. 39618334Speter 39718334Speter The `related_value' field is used to connect related expressions 39818334Speter (that differ by adding an integer). 39918334Speter The related expressions are chained in a circular fashion. 40018334Speter `related_value' is zero for expressions for which this 40118334Speter chain is not useful. 40218334Speter 40318334Speter The `cost' field stores the cost of this element's expression. 40418334Speter 40518334Speter The `is_const' flag is set if the element is a constant (including 40618334Speter a fixed address). 40718334Speter 40818334Speter The `flag' field is used as a temporary during some search routines. 40918334Speter 41018334Speter The `mode' field is usually the same as GET_MODE (`exp'), but 41118334Speter if `exp' is a CONST_INT and has no machine mode then the `mode' 41218334Speter field is the mode it was being used as. Each constant is 41318334Speter recorded separately for each mode it is used with. */ 41418334Speter 41518334Speter 41618334Speterstruct table_elt 41718334Speter{ 41818334Speter rtx exp; 41918334Speter struct table_elt *next_same_hash; 42018334Speter struct table_elt *prev_same_hash; 42118334Speter struct table_elt *next_same_value; 42218334Speter struct table_elt *prev_same_value; 42318334Speter struct table_elt *first_same_value; 42418334Speter struct table_elt *related_value; 42518334Speter int cost; 42618334Speter enum machine_mode mode; 42718334Speter char in_memory; 42818334Speter char in_struct; 42918334Speter char is_const; 43018334Speter char flag; 43118334Speter}; 43218334Speter 43318334Speter/* We don't want a lot of buckets, because we rarely have very many 43418334Speter things stored in the hash table, and a lot of buckets slows 43518334Speter down a lot of loops that happen frequently. */ 43618334Speter#define NBUCKETS 31 43718334Speter 43818334Speter/* Compute hash code of X in mode M. Special-case case where X is a pseudo 43918334Speter register (hard registers may require `do_not_record' to be set). */ 44018334Speter 44118334Speter#define HASH(X, M) \ 44218334Speter (GET_CODE (X) == REG && REGNO (X) >= FIRST_PSEUDO_REGISTER \ 44318334Speter ? (((unsigned) REG << 7) + (unsigned) reg_qty[REGNO (X)]) % NBUCKETS \ 44418334Speter : canon_hash (X, M) % NBUCKETS) 44518334Speter 44618334Speter/* Determine whether register number N is considered a fixed register for CSE. 44718334Speter It is desirable to replace other regs with fixed regs, to reduce need for 44818334Speter non-fixed hard regs. 44918334Speter A reg wins if it is either the frame pointer or designated as fixed, 45018334Speter but not if it is an overlapping register. */ 45118334Speter#ifdef OVERLAPPING_REGNO_P 45218334Speter#define FIXED_REGNO_P(N) \ 45318334Speter (((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \ 45418334Speter || fixed_regs[N] || global_regs[N]) \ 45518334Speter && ! OVERLAPPING_REGNO_P ((N))) 45618334Speter#else 45718334Speter#define FIXED_REGNO_P(N) \ 45818334Speter ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \ 45918334Speter || fixed_regs[N] || global_regs[N]) 46018334Speter#endif 46118334Speter 46218334Speter/* Compute cost of X, as stored in the `cost' field of a table_elt. Fixed 46318334Speter hard registers and pointers into the frame are the cheapest with a cost 46418334Speter of 0. Next come pseudos with a cost of one and other hard registers with 46518334Speter a cost of 2. Aside from these special cases, call `rtx_cost'. */ 46618334Speter 46718334Speter#define CHEAP_REGNO(N) \ 46818334Speter ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \ 46918334Speter || (N) == STACK_POINTER_REGNUM || (N) == ARG_POINTER_REGNUM \ 47018334Speter || ((N) >= FIRST_VIRTUAL_REGISTER && (N) <= LAST_VIRTUAL_REGISTER) \ 47118334Speter || ((N) < FIRST_PSEUDO_REGISTER \ 47218334Speter && FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS)) 47318334Speter 47418334Speter/* A register is cheap if it is a user variable assigned to the register 47518334Speter or if its register number always corresponds to a cheap register. */ 47618334Speter 47718334Speter#define CHEAP_REG(N) \ 47818334Speter ((REG_USERVAR_P (N) && REGNO (N) < FIRST_PSEUDO_REGISTER) \ 47918334Speter || CHEAP_REGNO (REGNO (N))) 48018334Speter 48118334Speter#define COST(X) \ 48218334Speter (GET_CODE (X) == REG \ 48318334Speter ? (CHEAP_REG (X) ? 0 \ 48418334Speter : REGNO (X) >= FIRST_PSEUDO_REGISTER ? 1 \ 48518334Speter : 2) \ 48618334Speter : rtx_cost (X, SET) * 2) 48718334Speter 48818334Speter/* Determine if the quantity number for register X represents a valid index 48918334Speter into the `qty_...' variables. */ 49018334Speter 49118334Speter#define REGNO_QTY_VALID_P(N) (reg_qty[N] != (N)) 49218334Speter 49318334Speterstatic struct table_elt *table[NBUCKETS]; 49418334Speter 49518334Speter/* Chain of `struct table_elt's made so far for this function 49618334Speter but currently removed from the table. */ 49718334Speter 49818334Speterstatic struct table_elt *free_element_chain; 49918334Speter 50018334Speter/* Number of `struct table_elt' structures made so far for this function. */ 50118334Speter 50218334Speterstatic int n_elements_made; 50318334Speter 50418334Speter/* Maximum value `n_elements_made' has had so far in this compilation 50518334Speter for functions previously processed. */ 50618334Speter 50718334Speterstatic int max_elements_made; 50818334Speter 50918334Speter/* Surviving equivalence class when two equivalence classes are merged 51018334Speter by recording the effects of a jump in the last insn. Zero if the 51118334Speter last insn was not a conditional jump. */ 51218334Speter 51318334Speterstatic struct table_elt *last_jump_equiv_class; 51418334Speter 51518334Speter/* Set to the cost of a constant pool reference if one was found for a 51618334Speter symbolic constant. If this was found, it means we should try to 51718334Speter convert constants into constant pool entries if they don't fit in 51818334Speter the insn. */ 51918334Speter 52018334Speterstatic int constant_pool_entries_cost; 52118334Speter 52218334Speter/* Bits describing what kind of values in memory must be invalidated 52318334Speter for a particular instruction. If all three bits are zero, 52418334Speter no memory refs need to be invalidated. Each bit is more powerful 52518334Speter than the preceding ones, and if a bit is set then the preceding 52618334Speter bits are also set. 52718334Speter 52818334Speter Here is how the bits are set: 52918334Speter Pushing onto the stack invalidates only the stack pointer, 53018334Speter writing at a fixed address invalidates only variable addresses, 53118334Speter writing in a structure element at variable address 53218334Speter invalidates all but scalar variables, 53318334Speter and writing in anything else at variable address invalidates everything. */ 53418334Speter 53518334Speterstruct write_data 53618334Speter{ 53718334Speter int sp : 1; /* Invalidate stack pointer. */ 53818334Speter int var : 1; /* Invalidate variable addresses. */ 53918334Speter int nonscalar : 1; /* Invalidate all but scalar variables. */ 54018334Speter int all : 1; /* Invalidate all memory refs. */ 54118334Speter}; 54218334Speter 54318334Speter/* Define maximum length of a branch path. */ 54418334Speter 54518334Speter#define PATHLENGTH 10 54618334Speter 54718334Speter/* This data describes a block that will be processed by cse_basic_block. */ 54818334Speter 54918334Speterstruct cse_basic_block_data { 55018334Speter /* Lowest CUID value of insns in block. */ 55118334Speter int low_cuid; 55218334Speter /* Highest CUID value of insns in block. */ 55318334Speter int high_cuid; 55418334Speter /* Total number of SETs in block. */ 55518334Speter int nsets; 55618334Speter /* Last insn in the block. */ 55718334Speter rtx last; 55818334Speter /* Size of current branch path, if any. */ 55918334Speter int path_size; 56018334Speter /* Current branch path, indicating which branches will be taken. */ 56118334Speter struct branch_path { 56218334Speter /* The branch insn. */ 56318334Speter rtx branch; 56418334Speter /* Whether it should be taken or not. AROUND is the same as taken 56518334Speter except that it is used when the destination label is not preceded 56618334Speter by a BARRIER. */ 56718334Speter enum taken {TAKEN, NOT_TAKEN, AROUND} status; 56818334Speter } path[PATHLENGTH]; 56918334Speter}; 57018334Speter 57118334Speter/* Nonzero if X has the form (PLUS frame-pointer integer). We check for 57218334Speter virtual regs here because the simplify_*_operation routines are called 57318334Speter by integrate.c, which is called before virtual register instantiation. */ 57418334Speter 57518334Speter#define FIXED_BASE_PLUS_P(X) \ 57618334Speter ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx \ 57718334Speter || (X) == arg_pointer_rtx \ 57818334Speter || (X) == virtual_stack_vars_rtx \ 57918334Speter || (X) == virtual_incoming_args_rtx \ 58018334Speter || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \ 58118334Speter && (XEXP (X, 0) == frame_pointer_rtx \ 58218334Speter || XEXP (X, 0) == hard_frame_pointer_rtx \ 58318334Speter || XEXP (X, 0) == arg_pointer_rtx \ 58418334Speter || XEXP (X, 0) == virtual_stack_vars_rtx \ 58518334Speter || XEXP (X, 0) == virtual_incoming_args_rtx))) 58618334Speter 58718334Speter/* Similar, but also allows reference to the stack pointer. 58818334Speter 58918334Speter This used to include FIXED_BASE_PLUS_P, however, we can't assume that 59018334Speter arg_pointer_rtx by itself is nonzero, because on at least one machine, 59118334Speter the i960, the arg pointer is zero when it is unused. */ 59218334Speter 59318334Speter#define NONZERO_BASE_PLUS_P(X) \ 59418334Speter ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx \ 59518334Speter || (X) == virtual_stack_vars_rtx \ 59618334Speter || (X) == virtual_incoming_args_rtx \ 59718334Speter || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \ 59818334Speter && (XEXP (X, 0) == frame_pointer_rtx \ 59918334Speter || XEXP (X, 0) == hard_frame_pointer_rtx \ 60018334Speter || XEXP (X, 0) == arg_pointer_rtx \ 60118334Speter || XEXP (X, 0) == virtual_stack_vars_rtx \ 60218334Speter || XEXP (X, 0) == virtual_incoming_args_rtx)) \ 60318334Speter || (X) == stack_pointer_rtx \ 60418334Speter || (X) == virtual_stack_dynamic_rtx \ 60518334Speter || (X) == virtual_outgoing_args_rtx \ 60618334Speter || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \ 60718334Speter && (XEXP (X, 0) == stack_pointer_rtx \ 60818334Speter || XEXP (X, 0) == virtual_stack_dynamic_rtx \ 60918334Speter || XEXP (X, 0) == virtual_outgoing_args_rtx))) 61018334Speter 61118334Speterstatic void new_basic_block PROTO((void)); 61218334Speterstatic void make_new_qty PROTO((int)); 61318334Speterstatic void make_regs_eqv PROTO((int, int)); 61418334Speterstatic void delete_reg_equiv PROTO((int)); 61518334Speterstatic int mention_regs PROTO((rtx)); 61618334Speterstatic int insert_regs PROTO((rtx, struct table_elt *, int)); 61718334Speterstatic void free_element PROTO((struct table_elt *)); 61818334Speterstatic void remove_from_table PROTO((struct table_elt *, unsigned)); 61918334Speterstatic struct table_elt *get_element PROTO((void)); 62018334Speterstatic struct table_elt *lookup PROTO((rtx, unsigned, enum machine_mode)), 62118334Speter *lookup_for_remove PROTO((rtx, unsigned, enum machine_mode)); 62218334Speterstatic rtx lookup_as_function PROTO((rtx, enum rtx_code)); 62318334Speterstatic struct table_elt *insert PROTO((rtx, struct table_elt *, unsigned, 62418334Speter enum machine_mode)); 62518334Speterstatic void merge_equiv_classes PROTO((struct table_elt *, 62618334Speter struct table_elt *)); 62718334Speterstatic void invalidate PROTO((rtx, enum machine_mode)); 62818334Speterstatic void remove_invalid_refs PROTO((int)); 62918334Speterstatic void rehash_using_reg PROTO((rtx)); 63018334Speterstatic void invalidate_memory PROTO((struct write_data *)); 63118334Speterstatic void invalidate_for_call PROTO((void)); 63218334Speterstatic rtx use_related_value PROTO((rtx, struct table_elt *)); 63318334Speterstatic unsigned canon_hash PROTO((rtx, enum machine_mode)); 63418334Speterstatic unsigned safe_hash PROTO((rtx, enum machine_mode)); 63518334Speterstatic int exp_equiv_p PROTO((rtx, rtx, int, int)); 63618334Speterstatic void set_nonvarying_address_components PROTO((rtx, int, rtx *, 63718334Speter HOST_WIDE_INT *, 63818334Speter HOST_WIDE_INT *)); 63918334Speterstatic int refers_to_p PROTO((rtx, rtx)); 64018334Speterstatic int refers_to_mem_p PROTO((rtx, rtx, HOST_WIDE_INT, 64118334Speter HOST_WIDE_INT)); 64218334Speterstatic int cse_rtx_addr_varies_p PROTO((rtx)); 64318334Speterstatic rtx canon_reg PROTO((rtx, rtx)); 64418334Speterstatic void find_best_addr PROTO((rtx, rtx *)); 64518334Speterstatic enum rtx_code find_comparison_args PROTO((enum rtx_code, rtx *, rtx *, 64618334Speter enum machine_mode *, 64718334Speter enum machine_mode *)); 64818334Speterstatic rtx cse_gen_binary PROTO((enum rtx_code, enum machine_mode, 64918334Speter rtx, rtx)); 65018334Speterstatic rtx simplify_plus_minus PROTO((enum rtx_code, enum machine_mode, 65118334Speter rtx, rtx)); 65218334Speterstatic rtx fold_rtx PROTO((rtx, rtx)); 65318334Speterstatic rtx equiv_constant PROTO((rtx)); 65418334Speterstatic void record_jump_equiv PROTO((rtx, int)); 65518334Speterstatic void record_jump_cond PROTO((enum rtx_code, enum machine_mode, 65618334Speter rtx, rtx, int)); 65718334Speterstatic void cse_insn PROTO((rtx, int)); 65818334Speterstatic void note_mem_written PROTO((rtx, struct write_data *)); 65918334Speterstatic void invalidate_from_clobbers PROTO((struct write_data *, rtx)); 66018334Speterstatic rtx cse_process_notes PROTO((rtx, rtx)); 66118334Speterstatic void cse_around_loop PROTO((rtx)); 66218334Speterstatic void invalidate_skipped_set PROTO((rtx, rtx)); 66318334Speterstatic void invalidate_skipped_block PROTO((rtx)); 66418334Speterstatic void cse_check_loop_start PROTO((rtx, rtx)); 66518334Speterstatic void cse_set_around_loop PROTO((rtx, rtx, rtx)); 66618334Speterstatic rtx cse_basic_block PROTO((rtx, rtx, struct branch_path *, int)); 66718334Speterstatic void count_reg_usage PROTO((rtx, int *, rtx, int)); 66818334Speter 66918334Speterextern int rtx_equal_function_value_matters; 67018334Speter 67118334Speter/* Return an estimate of the cost of computing rtx X. 67218334Speter One use is in cse, to decide which expression to keep in the hash table. 67318334Speter Another is in rtl generation, to pick the cheapest way to multiply. 67418334Speter Other uses like the latter are expected in the future. */ 67518334Speter 67618334Speter/* Return the right cost to give to an operation 67718334Speter to make the cost of the corresponding register-to-register instruction 67818334Speter N times that of a fast register-to-register instruction. */ 67918334Speter 68018334Speter#define COSTS_N_INSNS(N) ((N) * 4 - 2) 68118334Speter 68218334Speterint 68318334Speterrtx_cost (x, outer_code) 68418334Speter rtx x; 68518334Speter enum rtx_code outer_code; 68618334Speter{ 68718334Speter register int i, j; 68818334Speter register enum rtx_code code; 68918334Speter register char *fmt; 69018334Speter register int total; 69118334Speter 69218334Speter if (x == 0) 69318334Speter return 0; 69418334Speter 69518334Speter /* Compute the default costs of certain things. 69618334Speter Note that RTX_COSTS can override the defaults. */ 69718334Speter 69818334Speter code = GET_CODE (x); 69918334Speter switch (code) 70018334Speter { 70118334Speter case MULT: 70218334Speter /* Count multiplication by 2**n as a shift, 70318334Speter because if we are considering it, we would output it as a shift. */ 70418334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 70518334Speter && exact_log2 (INTVAL (XEXP (x, 1))) >= 0) 70618334Speter total = 2; 70718334Speter else 70818334Speter total = COSTS_N_INSNS (5); 70918334Speter break; 71018334Speter case DIV: 71118334Speter case UDIV: 71218334Speter case MOD: 71318334Speter case UMOD: 71418334Speter total = COSTS_N_INSNS (7); 71518334Speter break; 71618334Speter case USE: 71718334Speter /* Used in loop.c and combine.c as a marker. */ 71818334Speter total = 0; 71918334Speter break; 72018334Speter case ASM_OPERANDS: 72118334Speter /* We don't want these to be used in substitutions because 72218334Speter we have no way of validating the resulting insn. So assign 72318334Speter anything containing an ASM_OPERANDS a very high cost. */ 72418334Speter total = 1000; 72518334Speter break; 72618334Speter default: 72718334Speter total = 2; 72818334Speter } 72918334Speter 73018334Speter switch (code) 73118334Speter { 73218334Speter case REG: 73318334Speter return ! CHEAP_REG (x); 73418334Speter 73518334Speter case SUBREG: 73618334Speter /* If we can't tie these modes, make this expensive. The larger 73718334Speter the mode, the more expensive it is. */ 73818334Speter if (! MODES_TIEABLE_P (GET_MODE (x), GET_MODE (SUBREG_REG (x)))) 73918334Speter return COSTS_N_INSNS (2 74018334Speter + GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD); 74118334Speter return 2; 74218334Speter#ifdef RTX_COSTS 74318334Speter RTX_COSTS (x, code, outer_code); 74418334Speter#endif 74518334Speter CONST_COSTS (x, code, outer_code); 74618334Speter } 74718334Speter 74818334Speter /* Sum the costs of the sub-rtx's, plus cost of this operation, 74918334Speter which is already in total. */ 75018334Speter 75118334Speter fmt = GET_RTX_FORMAT (code); 75218334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 75318334Speter if (fmt[i] == 'e') 75418334Speter total += rtx_cost (XEXP (x, i), code); 75518334Speter else if (fmt[i] == 'E') 75618334Speter for (j = 0; j < XVECLEN (x, i); j++) 75718334Speter total += rtx_cost (XVECEXP (x, i, j), code); 75818334Speter 75918334Speter return total; 76018334Speter} 76118334Speter 76218334Speter/* Clear the hash table and initialize each register with its own quantity, 76318334Speter for a new basic block. */ 76418334Speter 76518334Speterstatic void 76618334Speternew_basic_block () 76718334Speter{ 76818334Speter register int i; 76918334Speter 77018334Speter next_qty = max_reg; 77118334Speter 77218334Speter bzero ((char *) reg_tick, max_reg * sizeof (int)); 77318334Speter 77418334Speter bcopy ((char *) all_minus_one, (char *) reg_in_table, 77518334Speter max_reg * sizeof (int)); 77618334Speter bcopy ((char *) consec_ints, (char *) reg_qty, max_reg * sizeof (int)); 77718334Speter CLEAR_HARD_REG_SET (hard_regs_in_table); 77818334Speter 77918334Speter /* The per-quantity values used to be initialized here, but it is 78018334Speter much faster to initialize each as it is made in `make_new_qty'. */ 78118334Speter 78218334Speter for (i = 0; i < NBUCKETS; i++) 78318334Speter { 78418334Speter register struct table_elt *this, *next; 78518334Speter for (this = table[i]; this; this = next) 78618334Speter { 78718334Speter next = this->next_same_hash; 78818334Speter free_element (this); 78918334Speter } 79018334Speter } 79118334Speter 79218334Speter bzero ((char *) table, sizeof table); 79318334Speter 79418334Speter prev_insn = 0; 79518334Speter 79618334Speter#ifdef HAVE_cc0 79718334Speter prev_insn_cc0 = 0; 79818334Speter#endif 79918334Speter} 80018334Speter 80118334Speter/* Say that register REG contains a quantity not in any register before 80218334Speter and initialize that quantity. */ 80318334Speter 80418334Speterstatic void 80518334Spetermake_new_qty (reg) 80618334Speter register int reg; 80718334Speter{ 80818334Speter register int q; 80918334Speter 81018334Speter if (next_qty >= max_qty) 81118334Speter abort (); 81218334Speter 81318334Speter q = reg_qty[reg] = next_qty++; 81418334Speter qty_first_reg[q] = reg; 81518334Speter qty_last_reg[q] = reg; 81618334Speter qty_const[q] = qty_const_insn[q] = 0; 81718334Speter qty_comparison_code[q] = UNKNOWN; 81818334Speter 81918334Speter reg_next_eqv[reg] = reg_prev_eqv[reg] = -1; 82018334Speter} 82118334Speter 82218334Speter/* Make reg NEW equivalent to reg OLD. 82318334Speter OLD is not changing; NEW is. */ 82418334Speter 82518334Speterstatic void 82618334Spetermake_regs_eqv (new, old) 82718334Speter register int new, old; 82818334Speter{ 82918334Speter register int lastr, firstr; 83018334Speter register int q = reg_qty[old]; 83118334Speter 83218334Speter /* Nothing should become eqv until it has a "non-invalid" qty number. */ 83318334Speter if (! REGNO_QTY_VALID_P (old)) 83418334Speter abort (); 83518334Speter 83618334Speter reg_qty[new] = q; 83718334Speter firstr = qty_first_reg[q]; 83818334Speter lastr = qty_last_reg[q]; 83918334Speter 84018334Speter /* Prefer fixed hard registers to anything. Prefer pseudo regs to other 84118334Speter hard regs. Among pseudos, if NEW will live longer than any other reg 84218334Speter of the same qty, and that is beyond the current basic block, 84318334Speter make it the new canonical replacement for this qty. */ 84418334Speter if (! (firstr < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (firstr)) 84518334Speter /* Certain fixed registers might be of the class NO_REGS. This means 84618334Speter that not only can they not be allocated by the compiler, but 84718334Speter they cannot be used in substitutions or canonicalizations 84818334Speter either. */ 84918334Speter && (new >= FIRST_PSEUDO_REGISTER || REGNO_REG_CLASS (new) != NO_REGS) 85018334Speter && ((new < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (new)) 85118334Speter || (new >= FIRST_PSEUDO_REGISTER 85218334Speter && (firstr < FIRST_PSEUDO_REGISTER 85318334Speter || ((uid_cuid[regno_last_uid[new]] > cse_basic_block_end 85418334Speter || (uid_cuid[regno_first_uid[new]] 85518334Speter < cse_basic_block_start)) 85618334Speter && (uid_cuid[regno_last_uid[new]] 85718334Speter > uid_cuid[regno_last_uid[firstr]])))))) 85818334Speter { 85918334Speter reg_prev_eqv[firstr] = new; 86018334Speter reg_next_eqv[new] = firstr; 86118334Speter reg_prev_eqv[new] = -1; 86218334Speter qty_first_reg[q] = new; 86318334Speter } 86418334Speter else 86518334Speter { 86618334Speter /* If NEW is a hard reg (known to be non-fixed), insert at end. 86718334Speter Otherwise, insert before any non-fixed hard regs that are at the 86818334Speter end. Registers of class NO_REGS cannot be used as an 86918334Speter equivalent for anything. */ 87018334Speter while (lastr < FIRST_PSEUDO_REGISTER && reg_prev_eqv[lastr] >= 0 87118334Speter && (REGNO_REG_CLASS (lastr) == NO_REGS || ! FIXED_REGNO_P (lastr)) 87218334Speter && new >= FIRST_PSEUDO_REGISTER) 87318334Speter lastr = reg_prev_eqv[lastr]; 87418334Speter reg_next_eqv[new] = reg_next_eqv[lastr]; 87518334Speter if (reg_next_eqv[lastr] >= 0) 87618334Speter reg_prev_eqv[reg_next_eqv[lastr]] = new; 87718334Speter else 87818334Speter qty_last_reg[q] = new; 87918334Speter reg_next_eqv[lastr] = new; 88018334Speter reg_prev_eqv[new] = lastr; 88118334Speter } 88218334Speter} 88318334Speter 88418334Speter/* Remove REG from its equivalence class. */ 88518334Speter 88618334Speterstatic void 88718334Speterdelete_reg_equiv (reg) 88818334Speter register int reg; 88918334Speter{ 89018334Speter register int q = reg_qty[reg]; 89118334Speter register int p, n; 89218334Speter 89318334Speter /* If invalid, do nothing. */ 89418334Speter if (q == reg) 89518334Speter return; 89618334Speter 89718334Speter p = reg_prev_eqv[reg]; 89818334Speter n = reg_next_eqv[reg]; 89918334Speter 90018334Speter if (n != -1) 90118334Speter reg_prev_eqv[n] = p; 90218334Speter else 90318334Speter qty_last_reg[q] = p; 90418334Speter if (p != -1) 90518334Speter reg_next_eqv[p] = n; 90618334Speter else 90718334Speter qty_first_reg[q] = n; 90818334Speter 90918334Speter reg_qty[reg] = reg; 91018334Speter} 91118334Speter 91218334Speter/* Remove any invalid expressions from the hash table 91318334Speter that refer to any of the registers contained in expression X. 91418334Speter 91518334Speter Make sure that newly inserted references to those registers 91618334Speter as subexpressions will be considered valid. 91718334Speter 91818334Speter mention_regs is not called when a register itself 91918334Speter is being stored in the table. 92018334Speter 92118334Speter Return 1 if we have done something that may have changed the hash code 92218334Speter of X. */ 92318334Speter 92418334Speterstatic int 92518334Spetermention_regs (x) 92618334Speter rtx x; 92718334Speter{ 92818334Speter register enum rtx_code code; 92918334Speter register int i, j; 93018334Speter register char *fmt; 93118334Speter register int changed = 0; 93218334Speter 93318334Speter if (x == 0) 93418334Speter return 0; 93518334Speter 93618334Speter code = GET_CODE (x); 93718334Speter if (code == REG) 93818334Speter { 93918334Speter register int regno = REGNO (x); 94018334Speter register int endregno 94118334Speter = regno + (regno >= FIRST_PSEUDO_REGISTER ? 1 94218334Speter : HARD_REGNO_NREGS (regno, GET_MODE (x))); 94318334Speter int i; 94418334Speter 94518334Speter for (i = regno; i < endregno; i++) 94618334Speter { 94718334Speter if (reg_in_table[i] >= 0 && reg_in_table[i] != reg_tick[i]) 94818334Speter remove_invalid_refs (i); 94918334Speter 95018334Speter reg_in_table[i] = reg_tick[i]; 95118334Speter } 95218334Speter 95318334Speter return 0; 95418334Speter } 95518334Speter 95618334Speter /* If X is a comparison or a COMPARE and either operand is a register 95718334Speter that does not have a quantity, give it one. This is so that a later 95818334Speter call to record_jump_equiv won't cause X to be assigned a different 95918334Speter hash code and not found in the table after that call. 96018334Speter 96118334Speter It is not necessary to do this here, since rehash_using_reg can 96218334Speter fix up the table later, but doing this here eliminates the need to 96318334Speter call that expensive function in the most common case where the only 96418334Speter use of the register is in the comparison. */ 96518334Speter 96618334Speter if (code == COMPARE || GET_RTX_CLASS (code) == '<') 96718334Speter { 96818334Speter if (GET_CODE (XEXP (x, 0)) == REG 96918334Speter && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 0)))) 97018334Speter if (insert_regs (XEXP (x, 0), NULL_PTR, 0)) 97118334Speter { 97218334Speter rehash_using_reg (XEXP (x, 0)); 97318334Speter changed = 1; 97418334Speter } 97518334Speter 97618334Speter if (GET_CODE (XEXP (x, 1)) == REG 97718334Speter && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 1)))) 97818334Speter if (insert_regs (XEXP (x, 1), NULL_PTR, 0)) 97918334Speter { 98018334Speter rehash_using_reg (XEXP (x, 1)); 98118334Speter changed = 1; 98218334Speter } 98318334Speter } 98418334Speter 98518334Speter fmt = GET_RTX_FORMAT (code); 98618334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 98718334Speter if (fmt[i] == 'e') 98818334Speter changed |= mention_regs (XEXP (x, i)); 98918334Speter else if (fmt[i] == 'E') 99018334Speter for (j = 0; j < XVECLEN (x, i); j++) 99118334Speter changed |= mention_regs (XVECEXP (x, i, j)); 99218334Speter 99318334Speter return changed; 99418334Speter} 99518334Speter 99618334Speter/* Update the register quantities for inserting X into the hash table 99718334Speter with a value equivalent to CLASSP. 99818334Speter (If the class does not contain a REG, it is irrelevant.) 99918334Speter If MODIFIED is nonzero, X is a destination; it is being modified. 100018334Speter Note that delete_reg_equiv should be called on a register 100118334Speter before insert_regs is done on that register with MODIFIED != 0. 100218334Speter 100318334Speter Nonzero value means that elements of reg_qty have changed 100418334Speter so X's hash code may be different. */ 100518334Speter 100618334Speterstatic int 100718334Speterinsert_regs (x, classp, modified) 100818334Speter rtx x; 100918334Speter struct table_elt *classp; 101018334Speter int modified; 101118334Speter{ 101218334Speter if (GET_CODE (x) == REG) 101318334Speter { 101418334Speter register int regno = REGNO (x); 101518334Speter 101618334Speter /* If REGNO is in the equivalence table already but is of the 101718334Speter wrong mode for that equivalence, don't do anything here. */ 101818334Speter 101918334Speter if (REGNO_QTY_VALID_P (regno) 102018334Speter && qty_mode[reg_qty[regno]] != GET_MODE (x)) 102118334Speter return 0; 102218334Speter 102318334Speter if (modified || ! REGNO_QTY_VALID_P (regno)) 102418334Speter { 102518334Speter if (classp) 102618334Speter for (classp = classp->first_same_value; 102718334Speter classp != 0; 102818334Speter classp = classp->next_same_value) 102918334Speter if (GET_CODE (classp->exp) == REG 103018334Speter && GET_MODE (classp->exp) == GET_MODE (x)) 103118334Speter { 103218334Speter make_regs_eqv (regno, REGNO (classp->exp)); 103318334Speter return 1; 103418334Speter } 103518334Speter 103618334Speter make_new_qty (regno); 103718334Speter qty_mode[reg_qty[regno]] = GET_MODE (x); 103818334Speter return 1; 103918334Speter } 104018334Speter 104118334Speter return 0; 104218334Speter } 104318334Speter 104418334Speter /* If X is a SUBREG, we will likely be inserting the inner register in the 104518334Speter table. If that register doesn't have an assigned quantity number at 104618334Speter this point but does later, the insertion that we will be doing now will 104718334Speter not be accessible because its hash code will have changed. So assign 104818334Speter a quantity number now. */ 104918334Speter 105018334Speter else if (GET_CODE (x) == SUBREG && GET_CODE (SUBREG_REG (x)) == REG 105118334Speter && ! REGNO_QTY_VALID_P (REGNO (SUBREG_REG (x)))) 105218334Speter { 105318334Speter insert_regs (SUBREG_REG (x), NULL_PTR, 0); 105418334Speter mention_regs (SUBREG_REG (x)); 105518334Speter return 1; 105618334Speter } 105718334Speter else 105818334Speter return mention_regs (x); 105918334Speter} 106018334Speter 106118334Speter/* Look in or update the hash table. */ 106218334Speter 106318334Speter/* Put the element ELT on the list of free elements. */ 106418334Speter 106518334Speterstatic void 106618334Speterfree_element (elt) 106718334Speter struct table_elt *elt; 106818334Speter{ 106918334Speter elt->next_same_hash = free_element_chain; 107018334Speter free_element_chain = elt; 107118334Speter} 107218334Speter 107318334Speter/* Return an element that is free for use. */ 107418334Speter 107518334Speterstatic struct table_elt * 107618334Speterget_element () 107718334Speter{ 107818334Speter struct table_elt *elt = free_element_chain; 107918334Speter if (elt) 108018334Speter { 108118334Speter free_element_chain = elt->next_same_hash; 108218334Speter return elt; 108318334Speter } 108418334Speter n_elements_made++; 108518334Speter return (struct table_elt *) oballoc (sizeof (struct table_elt)); 108618334Speter} 108718334Speter 108818334Speter/* Remove table element ELT from use in the table. 108918334Speter HASH is its hash code, made using the HASH macro. 109018334Speter It's an argument because often that is known in advance 109118334Speter and we save much time not recomputing it. */ 109218334Speter 109318334Speterstatic void 109418334Speterremove_from_table (elt, hash) 109518334Speter register struct table_elt *elt; 109618334Speter unsigned hash; 109718334Speter{ 109818334Speter if (elt == 0) 109918334Speter return; 110018334Speter 110118334Speter /* Mark this element as removed. See cse_insn. */ 110218334Speter elt->first_same_value = 0; 110318334Speter 110418334Speter /* Remove the table element from its equivalence class. */ 110518334Speter 110618334Speter { 110718334Speter register struct table_elt *prev = elt->prev_same_value; 110818334Speter register struct table_elt *next = elt->next_same_value; 110918334Speter 111018334Speter if (next) next->prev_same_value = prev; 111118334Speter 111218334Speter if (prev) 111318334Speter prev->next_same_value = next; 111418334Speter else 111518334Speter { 111618334Speter register struct table_elt *newfirst = next; 111718334Speter while (next) 111818334Speter { 111918334Speter next->first_same_value = newfirst; 112018334Speter next = next->next_same_value; 112118334Speter } 112218334Speter } 112318334Speter } 112418334Speter 112518334Speter /* Remove the table element from its hash bucket. */ 112618334Speter 112718334Speter { 112818334Speter register struct table_elt *prev = elt->prev_same_hash; 112918334Speter register struct table_elt *next = elt->next_same_hash; 113018334Speter 113118334Speter if (next) next->prev_same_hash = prev; 113218334Speter 113318334Speter if (prev) 113418334Speter prev->next_same_hash = next; 113518334Speter else if (table[hash] == elt) 113618334Speter table[hash] = next; 113718334Speter else 113818334Speter { 113918334Speter /* This entry is not in the proper hash bucket. This can happen 114018334Speter when two classes were merged by `merge_equiv_classes'. Search 114118334Speter for the hash bucket that it heads. This happens only very 114218334Speter rarely, so the cost is acceptable. */ 114318334Speter for (hash = 0; hash < NBUCKETS; hash++) 114418334Speter if (table[hash] == elt) 114518334Speter table[hash] = next; 114618334Speter } 114718334Speter } 114818334Speter 114918334Speter /* Remove the table element from its related-value circular chain. */ 115018334Speter 115118334Speter if (elt->related_value != 0 && elt->related_value != elt) 115218334Speter { 115318334Speter register struct table_elt *p = elt->related_value; 115418334Speter while (p->related_value != elt) 115518334Speter p = p->related_value; 115618334Speter p->related_value = elt->related_value; 115718334Speter if (p->related_value == p) 115818334Speter p->related_value = 0; 115918334Speter } 116018334Speter 116118334Speter free_element (elt); 116218334Speter} 116318334Speter 116418334Speter/* Look up X in the hash table and return its table element, 116518334Speter or 0 if X is not in the table. 116618334Speter 116718334Speter MODE is the machine-mode of X, or if X is an integer constant 116818334Speter with VOIDmode then MODE is the mode with which X will be used. 116918334Speter 117018334Speter Here we are satisfied to find an expression whose tree structure 117118334Speter looks like X. */ 117218334Speter 117318334Speterstatic struct table_elt * 117418334Speterlookup (x, hash, mode) 117518334Speter rtx x; 117618334Speter unsigned hash; 117718334Speter enum machine_mode mode; 117818334Speter{ 117918334Speter register struct table_elt *p; 118018334Speter 118118334Speter for (p = table[hash]; p; p = p->next_same_hash) 118218334Speter if (mode == p->mode && ((x == p->exp && GET_CODE (x) == REG) 118318334Speter || exp_equiv_p (x, p->exp, GET_CODE (x) != REG, 0))) 118418334Speter return p; 118518334Speter 118618334Speter return 0; 118718334Speter} 118818334Speter 118918334Speter/* Like `lookup' but don't care whether the table element uses invalid regs. 119018334Speter Also ignore discrepancies in the machine mode of a register. */ 119118334Speter 119218334Speterstatic struct table_elt * 119318334Speterlookup_for_remove (x, hash, mode) 119418334Speter rtx x; 119518334Speter unsigned hash; 119618334Speter enum machine_mode mode; 119718334Speter{ 119818334Speter register struct table_elt *p; 119918334Speter 120018334Speter if (GET_CODE (x) == REG) 120118334Speter { 120218334Speter int regno = REGNO (x); 120318334Speter /* Don't check the machine mode when comparing registers; 120418334Speter invalidating (REG:SI 0) also invalidates (REG:DF 0). */ 120518334Speter for (p = table[hash]; p; p = p->next_same_hash) 120618334Speter if (GET_CODE (p->exp) == REG 120718334Speter && REGNO (p->exp) == regno) 120818334Speter return p; 120918334Speter } 121018334Speter else 121118334Speter { 121218334Speter for (p = table[hash]; p; p = p->next_same_hash) 121318334Speter if (mode == p->mode && (x == p->exp || exp_equiv_p (x, p->exp, 0, 0))) 121418334Speter return p; 121518334Speter } 121618334Speter 121718334Speter return 0; 121818334Speter} 121918334Speter 122018334Speter/* Look for an expression equivalent to X and with code CODE. 122118334Speter If one is found, return that expression. */ 122218334Speter 122318334Speterstatic rtx 122418334Speterlookup_as_function (x, code) 122518334Speter rtx x; 122618334Speter enum rtx_code code; 122718334Speter{ 122818334Speter register struct table_elt *p = lookup (x, safe_hash (x, VOIDmode) % NBUCKETS, 122918334Speter GET_MODE (x)); 123018334Speter if (p == 0) 123118334Speter return 0; 123218334Speter 123318334Speter for (p = p->first_same_value; p; p = p->next_same_value) 123418334Speter { 123518334Speter if (GET_CODE (p->exp) == code 123618334Speter /* Make sure this is a valid entry in the table. */ 123718334Speter && exp_equiv_p (p->exp, p->exp, 1, 0)) 123818334Speter return p->exp; 123918334Speter } 124018334Speter 124118334Speter return 0; 124218334Speter} 124318334Speter 124418334Speter/* Insert X in the hash table, assuming HASH is its hash code 124518334Speter and CLASSP is an element of the class it should go in 124618334Speter (or 0 if a new class should be made). 124718334Speter It is inserted at the proper position to keep the class in 124818334Speter the order cheapest first. 124918334Speter 125018334Speter MODE is the machine-mode of X, or if X is an integer constant 125118334Speter with VOIDmode then MODE is the mode with which X will be used. 125218334Speter 125318334Speter For elements of equal cheapness, the most recent one 125418334Speter goes in front, except that the first element in the list 125518334Speter remains first unless a cheaper element is added. The order of 125618334Speter pseudo-registers does not matter, as canon_reg will be called to 125718334Speter find the cheapest when a register is retrieved from the table. 125818334Speter 125918334Speter The in_memory field in the hash table element is set to 0. 126018334Speter The caller must set it nonzero if appropriate. 126118334Speter 126218334Speter You should call insert_regs (X, CLASSP, MODIFY) before calling here, 126318334Speter and if insert_regs returns a nonzero value 126418334Speter you must then recompute its hash code before calling here. 126518334Speter 126618334Speter If necessary, update table showing constant values of quantities. */ 126718334Speter 126818334Speter#define CHEAPER(X,Y) ((X)->cost < (Y)->cost) 126918334Speter 127018334Speterstatic struct table_elt * 127118334Speterinsert (x, classp, hash, mode) 127218334Speter register rtx x; 127318334Speter register struct table_elt *classp; 127418334Speter unsigned hash; 127518334Speter enum machine_mode mode; 127618334Speter{ 127718334Speter register struct table_elt *elt; 127818334Speter 127918334Speter /* If X is a register and we haven't made a quantity for it, 128018334Speter something is wrong. */ 128118334Speter if (GET_CODE (x) == REG && ! REGNO_QTY_VALID_P (REGNO (x))) 128218334Speter abort (); 128318334Speter 128418334Speter /* If X is a hard register, show it is being put in the table. */ 128518334Speter if (GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER) 128618334Speter { 128718334Speter int regno = REGNO (x); 128818334Speter int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x)); 128918334Speter int i; 129018334Speter 129118334Speter for (i = regno; i < endregno; i++) 129218334Speter SET_HARD_REG_BIT (hard_regs_in_table, i); 129318334Speter } 129418334Speter 129518334Speter /* If X is a label, show we recorded it. */ 129618334Speter if (GET_CODE (x) == LABEL_REF 129718334Speter || (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS 129818334Speter && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)) 129918334Speter recorded_label_ref = 1; 130018334Speter 130118334Speter /* Put an element for X into the right hash bucket. */ 130218334Speter 130318334Speter elt = get_element (); 130418334Speter elt->exp = x; 130518334Speter elt->cost = COST (x); 130618334Speter elt->next_same_value = 0; 130718334Speter elt->prev_same_value = 0; 130818334Speter elt->next_same_hash = table[hash]; 130918334Speter elt->prev_same_hash = 0; 131018334Speter elt->related_value = 0; 131118334Speter elt->in_memory = 0; 131218334Speter elt->mode = mode; 131318334Speter elt->is_const = (CONSTANT_P (x) 131418334Speter /* GNU C++ takes advantage of this for `this' 131518334Speter (and other const values). */ 131618334Speter || (RTX_UNCHANGING_P (x) 131718334Speter && GET_CODE (x) == REG 131818334Speter && REGNO (x) >= FIRST_PSEUDO_REGISTER) 131918334Speter || FIXED_BASE_PLUS_P (x)); 132018334Speter 132118334Speter if (table[hash]) 132218334Speter table[hash]->prev_same_hash = elt; 132318334Speter table[hash] = elt; 132418334Speter 132518334Speter /* Put it into the proper value-class. */ 132618334Speter if (classp) 132718334Speter { 132818334Speter classp = classp->first_same_value; 132918334Speter if (CHEAPER (elt, classp)) 133018334Speter /* Insert at the head of the class */ 133118334Speter { 133218334Speter register struct table_elt *p; 133318334Speter elt->next_same_value = classp; 133418334Speter classp->prev_same_value = elt; 133518334Speter elt->first_same_value = elt; 133618334Speter 133718334Speter for (p = classp; p; p = p->next_same_value) 133818334Speter p->first_same_value = elt; 133918334Speter } 134018334Speter else 134118334Speter { 134218334Speter /* Insert not at head of the class. */ 134318334Speter /* Put it after the last element cheaper than X. */ 134418334Speter register struct table_elt *p, *next; 134518334Speter for (p = classp; (next = p->next_same_value) && CHEAPER (next, elt); 134618334Speter p = next); 134718334Speter /* Put it after P and before NEXT. */ 134818334Speter elt->next_same_value = next; 134918334Speter if (next) 135018334Speter next->prev_same_value = elt; 135118334Speter elt->prev_same_value = p; 135218334Speter p->next_same_value = elt; 135318334Speter elt->first_same_value = classp; 135418334Speter } 135518334Speter } 135618334Speter else 135718334Speter elt->first_same_value = elt; 135818334Speter 135918334Speter /* If this is a constant being set equivalent to a register or a register 136018334Speter being set equivalent to a constant, note the constant equivalence. 136118334Speter 136218334Speter If this is a constant, it cannot be equivalent to a different constant, 136318334Speter and a constant is the only thing that can be cheaper than a register. So 136418334Speter we know the register is the head of the class (before the constant was 136518334Speter inserted). 136618334Speter 136718334Speter If this is a register that is not already known equivalent to a 136818334Speter constant, we must check the entire class. 136918334Speter 137018334Speter If this is a register that is already known equivalent to an insn, 137118334Speter update `qty_const_insn' to show that `this_insn' is the latest 137218334Speter insn making that quantity equivalent to the constant. */ 137318334Speter 137418334Speter if (elt->is_const && classp && GET_CODE (classp->exp) == REG 137518334Speter && GET_CODE (x) != REG) 137618334Speter { 137718334Speter qty_const[reg_qty[REGNO (classp->exp)]] 137818334Speter = gen_lowpart_if_possible (qty_mode[reg_qty[REGNO (classp->exp)]], x); 137918334Speter qty_const_insn[reg_qty[REGNO (classp->exp)]] = this_insn; 138018334Speter } 138118334Speter 138218334Speter else if (GET_CODE (x) == REG && classp && ! qty_const[reg_qty[REGNO (x)]] 138318334Speter && ! elt->is_const) 138418334Speter { 138518334Speter register struct table_elt *p; 138618334Speter 138718334Speter for (p = classp; p != 0; p = p->next_same_value) 138818334Speter { 138918334Speter if (p->is_const && GET_CODE (p->exp) != REG) 139018334Speter { 139118334Speter qty_const[reg_qty[REGNO (x)]] 139218334Speter = gen_lowpart_if_possible (GET_MODE (x), p->exp); 139318334Speter qty_const_insn[reg_qty[REGNO (x)]] = this_insn; 139418334Speter break; 139518334Speter } 139618334Speter } 139718334Speter } 139818334Speter 139918334Speter else if (GET_CODE (x) == REG && qty_const[reg_qty[REGNO (x)]] 140018334Speter && GET_MODE (x) == qty_mode[reg_qty[REGNO (x)]]) 140118334Speter qty_const_insn[reg_qty[REGNO (x)]] = this_insn; 140218334Speter 140318334Speter /* If this is a constant with symbolic value, 140418334Speter and it has a term with an explicit integer value, 140518334Speter link it up with related expressions. */ 140618334Speter if (GET_CODE (x) == CONST) 140718334Speter { 140818334Speter rtx subexp = get_related_value (x); 140918334Speter unsigned subhash; 141018334Speter struct table_elt *subelt, *subelt_prev; 141118334Speter 141218334Speter if (subexp != 0) 141318334Speter { 141418334Speter /* Get the integer-free subexpression in the hash table. */ 141518334Speter subhash = safe_hash (subexp, mode) % NBUCKETS; 141618334Speter subelt = lookup (subexp, subhash, mode); 141718334Speter if (subelt == 0) 141818334Speter subelt = insert (subexp, NULL_PTR, subhash, mode); 141918334Speter /* Initialize SUBELT's circular chain if it has none. */ 142018334Speter if (subelt->related_value == 0) 142118334Speter subelt->related_value = subelt; 142218334Speter /* Find the element in the circular chain that precedes SUBELT. */ 142318334Speter subelt_prev = subelt; 142418334Speter while (subelt_prev->related_value != subelt) 142518334Speter subelt_prev = subelt_prev->related_value; 142618334Speter /* Put new ELT into SUBELT's circular chain just before SUBELT. 142718334Speter This way the element that follows SUBELT is the oldest one. */ 142818334Speter elt->related_value = subelt_prev->related_value; 142918334Speter subelt_prev->related_value = elt; 143018334Speter } 143118334Speter } 143218334Speter 143318334Speter return elt; 143418334Speter} 143518334Speter 143618334Speter/* Given two equivalence classes, CLASS1 and CLASS2, put all the entries from 143718334Speter CLASS2 into CLASS1. This is done when we have reached an insn which makes 143818334Speter the two classes equivalent. 143918334Speter 144018334Speter CLASS1 will be the surviving class; CLASS2 should not be used after this 144118334Speter call. 144218334Speter 144318334Speter Any invalid entries in CLASS2 will not be copied. */ 144418334Speter 144518334Speterstatic void 144618334Spetermerge_equiv_classes (class1, class2) 144718334Speter struct table_elt *class1, *class2; 144818334Speter{ 144918334Speter struct table_elt *elt, *next, *new; 145018334Speter 145118334Speter /* Ensure we start with the head of the classes. */ 145218334Speter class1 = class1->first_same_value; 145318334Speter class2 = class2->first_same_value; 145418334Speter 145518334Speter /* If they were already equal, forget it. */ 145618334Speter if (class1 == class2) 145718334Speter return; 145818334Speter 145918334Speter for (elt = class2; elt; elt = next) 146018334Speter { 146118334Speter unsigned hash; 146218334Speter rtx exp = elt->exp; 146318334Speter enum machine_mode mode = elt->mode; 146418334Speter 146518334Speter next = elt->next_same_value; 146618334Speter 146718334Speter /* Remove old entry, make a new one in CLASS1's class. 146818334Speter Don't do this for invalid entries as we cannot find their 146918334Speter hash code (it also isn't necessary). */ 147018334Speter if (GET_CODE (exp) == REG || exp_equiv_p (exp, exp, 1, 0)) 147118334Speter { 147218334Speter hash_arg_in_memory = 0; 147318334Speter hash_arg_in_struct = 0; 147418334Speter hash = HASH (exp, mode); 147518334Speter 147618334Speter if (GET_CODE (exp) == REG) 147718334Speter delete_reg_equiv (REGNO (exp)); 147818334Speter 147918334Speter remove_from_table (elt, hash); 148018334Speter 148118334Speter if (insert_regs (exp, class1, 0)) 148218334Speter { 148318334Speter rehash_using_reg (exp); 148418334Speter hash = HASH (exp, mode); 148518334Speter } 148618334Speter new = insert (exp, class1, hash, mode); 148718334Speter new->in_memory = hash_arg_in_memory; 148818334Speter new->in_struct = hash_arg_in_struct; 148918334Speter } 149018334Speter } 149118334Speter} 149218334Speter 149318334Speter/* Remove from the hash table, or mark as invalid, 149418334Speter all expressions whose values could be altered by storing in X. 149518334Speter X is a register, a subreg, or a memory reference with nonvarying address 149618334Speter (because, when a memory reference with a varying address is stored in, 149718334Speter all memory references are removed by invalidate_memory 149818334Speter so specific invalidation is superfluous). 149918334Speter FULL_MODE, if not VOIDmode, indicates that this much should be invalidated 150018334Speter instead of just the amount indicated by the mode of X. This is only used 150118334Speter for bitfield stores into memory. 150218334Speter 150318334Speter A nonvarying address may be just a register or just 150418334Speter a symbol reference, or it may be either of those plus 150518334Speter a numeric offset. */ 150618334Speter 150718334Speterstatic void 150818334Speterinvalidate (x, full_mode) 150918334Speter rtx x; 151018334Speter enum machine_mode full_mode; 151118334Speter{ 151218334Speter register int i; 151318334Speter register struct table_elt *p; 151418334Speter rtx base; 151518334Speter HOST_WIDE_INT start, end; 151618334Speter 151718334Speter /* If X is a register, dependencies on its contents 151818334Speter are recorded through the qty number mechanism. 151918334Speter Just change the qty number of the register, 152018334Speter mark it as invalid for expressions that refer to it, 152118334Speter and remove it itself. */ 152218334Speter 152318334Speter if (GET_CODE (x) == REG) 152418334Speter { 152518334Speter register int regno = REGNO (x); 152618334Speter register unsigned hash = HASH (x, GET_MODE (x)); 152718334Speter 152818334Speter /* Remove REGNO from any quantity list it might be on and indicate 152918334Speter that it's value might have changed. If it is a pseudo, remove its 153018334Speter entry from the hash table. 153118334Speter 153218334Speter For a hard register, we do the first two actions above for any 153318334Speter additional hard registers corresponding to X. Then, if any of these 153418334Speter registers are in the table, we must remove any REG entries that 153518334Speter overlap these registers. */ 153618334Speter 153718334Speter delete_reg_equiv (regno); 153818334Speter reg_tick[regno]++; 153918334Speter 154018334Speter if (regno >= FIRST_PSEUDO_REGISTER) 154118334Speter { 154218334Speter /* Because a register can be referenced in more than one mode, 154318334Speter we might have to remove more than one table entry. */ 154418334Speter 154518334Speter struct table_elt *elt; 154618334Speter 154718334Speter while (elt = lookup_for_remove (x, hash, GET_MODE (x))) 154818334Speter remove_from_table (elt, hash); 154918334Speter } 155018334Speter else 155118334Speter { 155218334Speter HOST_WIDE_INT in_table 155318334Speter = TEST_HARD_REG_BIT (hard_regs_in_table, regno); 155418334Speter int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x)); 155518334Speter int tregno, tendregno; 155618334Speter register struct table_elt *p, *next; 155718334Speter 155818334Speter CLEAR_HARD_REG_BIT (hard_regs_in_table, regno); 155918334Speter 156018334Speter for (i = regno + 1; i < endregno; i++) 156118334Speter { 156218334Speter in_table |= TEST_HARD_REG_BIT (hard_regs_in_table, i); 156318334Speter CLEAR_HARD_REG_BIT (hard_regs_in_table, i); 156418334Speter delete_reg_equiv (i); 156518334Speter reg_tick[i]++; 156618334Speter } 156718334Speter 156818334Speter if (in_table) 156918334Speter for (hash = 0; hash < NBUCKETS; hash++) 157018334Speter for (p = table[hash]; p; p = next) 157118334Speter { 157218334Speter next = p->next_same_hash; 157318334Speter 157418334Speter if (GET_CODE (p->exp) != REG 157518334Speter || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER) 157618334Speter continue; 157718334Speter 157818334Speter tregno = REGNO (p->exp); 157918334Speter tendregno 158018334Speter = tregno + HARD_REGNO_NREGS (tregno, GET_MODE (p->exp)); 158118334Speter if (tendregno > regno && tregno < endregno) 158218334Speter remove_from_table (p, hash); 158318334Speter } 158418334Speter } 158518334Speter 158618334Speter return; 158718334Speter } 158818334Speter 158918334Speter if (GET_CODE (x) == SUBREG) 159018334Speter { 159118334Speter if (GET_CODE (SUBREG_REG (x)) != REG) 159218334Speter abort (); 159318334Speter invalidate (SUBREG_REG (x), VOIDmode); 159418334Speter return; 159518334Speter } 159618334Speter 159718334Speter /* X is not a register; it must be a memory reference with 159818334Speter a nonvarying address. Remove all hash table elements 159918334Speter that refer to overlapping pieces of memory. */ 160018334Speter 160118334Speter if (GET_CODE (x) != MEM) 160218334Speter abort (); 160318334Speter 160418334Speter if (full_mode == VOIDmode) 160518334Speter full_mode = GET_MODE (x); 160618334Speter 160718334Speter set_nonvarying_address_components (XEXP (x, 0), GET_MODE_SIZE (full_mode), 160818334Speter &base, &start, &end); 160918334Speter 161018334Speter for (i = 0; i < NBUCKETS; i++) 161118334Speter { 161218334Speter register struct table_elt *next; 161318334Speter for (p = table[i]; p; p = next) 161418334Speter { 161518334Speter next = p->next_same_hash; 161618334Speter if (refers_to_mem_p (p->exp, base, start, end)) 161718334Speter remove_from_table (p, i); 161818334Speter } 161918334Speter } 162018334Speter} 162118334Speter 162218334Speter/* Remove all expressions that refer to register REGNO, 162318334Speter since they are already invalid, and we are about to 162418334Speter mark that register valid again and don't want the old 162518334Speter expressions to reappear as valid. */ 162618334Speter 162718334Speterstatic void 162818334Speterremove_invalid_refs (regno) 162918334Speter int regno; 163018334Speter{ 163118334Speter register int i; 163218334Speter register struct table_elt *p, *next; 163318334Speter 163418334Speter for (i = 0; i < NBUCKETS; i++) 163518334Speter for (p = table[i]; p; p = next) 163618334Speter { 163718334Speter next = p->next_same_hash; 163818334Speter if (GET_CODE (p->exp) != REG 163918334Speter && refers_to_regno_p (regno, regno + 1, p->exp, NULL_PTR)) 164018334Speter remove_from_table (p, i); 164118334Speter } 164218334Speter} 164318334Speter 164418334Speter/* Recompute the hash codes of any valid entries in the hash table that 164518334Speter reference X, if X is a register, or SUBREG_REG (X) if X is a SUBREG. 164618334Speter 164718334Speter This is called when we make a jump equivalence. */ 164818334Speter 164918334Speterstatic void 165018334Speterrehash_using_reg (x) 165118334Speter rtx x; 165218334Speter{ 165318334Speter int i; 165418334Speter struct table_elt *p, *next; 165518334Speter unsigned hash; 165618334Speter 165718334Speter if (GET_CODE (x) == SUBREG) 165818334Speter x = SUBREG_REG (x); 165918334Speter 166018334Speter /* If X is not a register or if the register is known not to be in any 166118334Speter valid entries in the table, we have no work to do. */ 166218334Speter 166318334Speter if (GET_CODE (x) != REG 166418334Speter || reg_in_table[REGNO (x)] < 0 166518334Speter || reg_in_table[REGNO (x)] != reg_tick[REGNO (x)]) 166618334Speter return; 166718334Speter 166818334Speter /* Scan all hash chains looking for valid entries that mention X. 166918334Speter If we find one and it is in the wrong hash chain, move it. We can skip 167018334Speter objects that are registers, since they are handled specially. */ 167118334Speter 167218334Speter for (i = 0; i < NBUCKETS; i++) 167318334Speter for (p = table[i]; p; p = next) 167418334Speter { 167518334Speter next = p->next_same_hash; 167618334Speter if (GET_CODE (p->exp) != REG && reg_mentioned_p (x, p->exp) 167718334Speter && exp_equiv_p (p->exp, p->exp, 1, 0) 167818334Speter && i != (hash = safe_hash (p->exp, p->mode) % NBUCKETS)) 167918334Speter { 168018334Speter if (p->next_same_hash) 168118334Speter p->next_same_hash->prev_same_hash = p->prev_same_hash; 168218334Speter 168318334Speter if (p->prev_same_hash) 168418334Speter p->prev_same_hash->next_same_hash = p->next_same_hash; 168518334Speter else 168618334Speter table[i] = p->next_same_hash; 168718334Speter 168818334Speter p->next_same_hash = table[hash]; 168918334Speter p->prev_same_hash = 0; 169018334Speter if (table[hash]) 169118334Speter table[hash]->prev_same_hash = p; 169218334Speter table[hash] = p; 169318334Speter } 169418334Speter } 169518334Speter} 169618334Speter 169718334Speter/* Remove from the hash table all expressions that reference memory, 169818334Speter or some of them as specified by *WRITES. */ 169918334Speter 170018334Speterstatic void 170118334Speterinvalidate_memory (writes) 170218334Speter struct write_data *writes; 170318334Speter{ 170418334Speter register int i; 170518334Speter register struct table_elt *p, *next; 170618334Speter int all = writes->all; 170718334Speter int nonscalar = writes->nonscalar; 170818334Speter 170918334Speter for (i = 0; i < NBUCKETS; i++) 171018334Speter for (p = table[i]; p; p = next) 171118334Speter { 171218334Speter next = p->next_same_hash; 171318334Speter if (p->in_memory 171418334Speter && (all 171518334Speter || (nonscalar && p->in_struct) 171618334Speter || cse_rtx_addr_varies_p (p->exp))) 171718334Speter remove_from_table (p, i); 171818334Speter } 171918334Speter} 172018334Speter 172118334Speter/* Remove from the hash table any expression that is a call-clobbered 172218334Speter register. Also update their TICK values. */ 172318334Speter 172418334Speterstatic void 172518334Speterinvalidate_for_call () 172618334Speter{ 172718334Speter int regno, endregno; 172818334Speter int i; 172918334Speter unsigned hash; 173018334Speter struct table_elt *p, *next; 173118334Speter int in_table = 0; 173218334Speter 173318334Speter /* Go through all the hard registers. For each that is clobbered in 173418334Speter a CALL_INSN, remove the register from quantity chains and update 173518334Speter reg_tick if defined. Also see if any of these registers is currently 173618334Speter in the table. */ 173718334Speter 173818334Speter for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 173918334Speter if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)) 174018334Speter { 174118334Speter delete_reg_equiv (regno); 174218334Speter if (reg_tick[regno] >= 0) 174318334Speter reg_tick[regno]++; 174418334Speter 174518334Speter in_table |= (TEST_HARD_REG_BIT (hard_regs_in_table, regno) != 0); 174618334Speter } 174718334Speter 174818334Speter /* In the case where we have no call-clobbered hard registers in the 174918334Speter table, we are done. Otherwise, scan the table and remove any 175018334Speter entry that overlaps a call-clobbered register. */ 175118334Speter 175218334Speter if (in_table) 175318334Speter for (hash = 0; hash < NBUCKETS; hash++) 175418334Speter for (p = table[hash]; p; p = next) 175518334Speter { 175618334Speter next = p->next_same_hash; 175718334Speter 175818334Speter if (GET_CODE (p->exp) != REG 175918334Speter || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER) 176018334Speter continue; 176118334Speter 176218334Speter regno = REGNO (p->exp); 176318334Speter endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (p->exp)); 176418334Speter 176518334Speter for (i = regno; i < endregno; i++) 176618334Speter if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)) 176718334Speter { 176818334Speter remove_from_table (p, hash); 176918334Speter break; 177018334Speter } 177118334Speter } 177218334Speter} 177318334Speter 177418334Speter/* Given an expression X of type CONST, 177518334Speter and ELT which is its table entry (or 0 if it 177618334Speter is not in the hash table), 177718334Speter return an alternate expression for X as a register plus integer. 177818334Speter If none can be found, return 0. */ 177918334Speter 178018334Speterstatic rtx 178118334Speteruse_related_value (x, elt) 178218334Speter rtx x; 178318334Speter struct table_elt *elt; 178418334Speter{ 178518334Speter register struct table_elt *relt = 0; 178618334Speter register struct table_elt *p, *q; 178718334Speter HOST_WIDE_INT offset; 178818334Speter 178918334Speter /* First, is there anything related known? 179018334Speter If we have a table element, we can tell from that. 179118334Speter Otherwise, must look it up. */ 179218334Speter 179318334Speter if (elt != 0 && elt->related_value != 0) 179418334Speter relt = elt; 179518334Speter else if (elt == 0 && GET_CODE (x) == CONST) 179618334Speter { 179718334Speter rtx subexp = get_related_value (x); 179818334Speter if (subexp != 0) 179918334Speter relt = lookup (subexp, 180018334Speter safe_hash (subexp, GET_MODE (subexp)) % NBUCKETS, 180118334Speter GET_MODE (subexp)); 180218334Speter } 180318334Speter 180418334Speter if (relt == 0) 180518334Speter return 0; 180618334Speter 180718334Speter /* Search all related table entries for one that has an 180818334Speter equivalent register. */ 180918334Speter 181018334Speter p = relt; 181118334Speter while (1) 181218334Speter { 181318334Speter /* This loop is strange in that it is executed in two different cases. 181418334Speter The first is when X is already in the table. Then it is searching 181518334Speter the RELATED_VALUE list of X's class (RELT). The second case is when 181618334Speter X is not in the table. Then RELT points to a class for the related 181718334Speter value. 181818334Speter 181918334Speter Ensure that, whatever case we are in, that we ignore classes that have 182018334Speter the same value as X. */ 182118334Speter 182218334Speter if (rtx_equal_p (x, p->exp)) 182318334Speter q = 0; 182418334Speter else 182518334Speter for (q = p->first_same_value; q; q = q->next_same_value) 182618334Speter if (GET_CODE (q->exp) == REG) 182718334Speter break; 182818334Speter 182918334Speter if (q) 183018334Speter break; 183118334Speter 183218334Speter p = p->related_value; 183318334Speter 183418334Speter /* We went all the way around, so there is nothing to be found. 183518334Speter Alternatively, perhaps RELT was in the table for some other reason 183618334Speter and it has no related values recorded. */ 183718334Speter if (p == relt || p == 0) 183818334Speter break; 183918334Speter } 184018334Speter 184118334Speter if (q == 0) 184218334Speter return 0; 184318334Speter 184418334Speter offset = (get_integer_term (x) - get_integer_term (p->exp)); 184518334Speter /* Note: OFFSET may be 0 if P->xexp and X are related by commutativity. */ 184618334Speter return plus_constant (q->exp, offset); 184718334Speter} 184818334Speter 184918334Speter/* Hash an rtx. We are careful to make sure the value is never negative. 185018334Speter Equivalent registers hash identically. 185118334Speter MODE is used in hashing for CONST_INTs only; 185218334Speter otherwise the mode of X is used. 185318334Speter 185418334Speter Store 1 in do_not_record if any subexpression is volatile. 185518334Speter 185618334Speter Store 1 in hash_arg_in_memory if X contains a MEM rtx 185718334Speter which does not have the RTX_UNCHANGING_P bit set. 185818334Speter In this case, also store 1 in hash_arg_in_struct 185918334Speter if there is a MEM rtx which has the MEM_IN_STRUCT_P bit set. 186018334Speter 186118334Speter Note that cse_insn knows that the hash code of a MEM expression 186218334Speter is just (int) MEM plus the hash code of the address. */ 186318334Speter 186418334Speterstatic unsigned 186518334Spetercanon_hash (x, mode) 186618334Speter rtx x; 186718334Speter enum machine_mode mode; 186818334Speter{ 186918334Speter register int i, j; 187018334Speter register unsigned hash = 0; 187118334Speter register enum rtx_code code; 187218334Speter register char *fmt; 187318334Speter 187418334Speter /* repeat is used to turn tail-recursion into iteration. */ 187518334Speter repeat: 187618334Speter if (x == 0) 187718334Speter return hash; 187818334Speter 187918334Speter code = GET_CODE (x); 188018334Speter switch (code) 188118334Speter { 188218334Speter case REG: 188318334Speter { 188418334Speter register int regno = REGNO (x); 188518334Speter 188618334Speter /* On some machines, we can't record any non-fixed hard register, 188718334Speter because extending its life will cause reload problems. We 188818334Speter consider ap, fp, and sp to be fixed for this purpose. 188918334Speter On all machines, we can't record any global registers. */ 189018334Speter 189118334Speter if (regno < FIRST_PSEUDO_REGISTER 189218334Speter && (global_regs[regno] 189318334Speter#ifdef SMALL_REGISTER_CLASSES 189418334Speter || (! fixed_regs[regno] 189518334Speter && regno != FRAME_POINTER_REGNUM 189618334Speter && regno != HARD_FRAME_POINTER_REGNUM 189718334Speter && regno != ARG_POINTER_REGNUM 189818334Speter && regno != STACK_POINTER_REGNUM) 189918334Speter#endif 190018334Speter )) 190118334Speter { 190218334Speter do_not_record = 1; 190318334Speter return 0; 190418334Speter } 190518334Speter hash += ((unsigned) REG << 7) + (unsigned) reg_qty[regno]; 190618334Speter return hash; 190718334Speter } 190818334Speter 190918334Speter case CONST_INT: 191018334Speter { 191118334Speter unsigned HOST_WIDE_INT tem = INTVAL (x); 191218334Speter hash += ((unsigned) CONST_INT << 7) + (unsigned) mode + tem; 191318334Speter return hash; 191418334Speter } 191518334Speter 191618334Speter case CONST_DOUBLE: 191718334Speter /* This is like the general case, except that it only counts 191818334Speter the integers representing the constant. */ 191918334Speter hash += (unsigned) code + (unsigned) GET_MODE (x); 192018334Speter if (GET_MODE (x) != VOIDmode) 192118334Speter for (i = 2; i < GET_RTX_LENGTH (CONST_DOUBLE); i++) 192218334Speter { 192318334Speter unsigned tem = XINT (x, i); 192418334Speter hash += tem; 192518334Speter } 192618334Speter else 192718334Speter hash += ((unsigned) CONST_DOUBLE_LOW (x) 192818334Speter + (unsigned) CONST_DOUBLE_HIGH (x)); 192918334Speter return hash; 193018334Speter 193118334Speter /* Assume there is only one rtx object for any given label. */ 193218334Speter case LABEL_REF: 193318334Speter hash 193418334Speter += ((unsigned) LABEL_REF << 7) + (unsigned HOST_WIDE_INT) XEXP (x, 0); 193518334Speter return hash; 193618334Speter 193718334Speter case SYMBOL_REF: 193818334Speter hash 193918334Speter += ((unsigned) SYMBOL_REF << 7) + (unsigned HOST_WIDE_INT) XSTR (x, 0); 194018334Speter return hash; 194118334Speter 194218334Speter case MEM: 194318334Speter if (MEM_VOLATILE_P (x)) 194418334Speter { 194518334Speter do_not_record = 1; 194618334Speter return 0; 194718334Speter } 194818334Speter if (! RTX_UNCHANGING_P (x)) 194918334Speter { 195018334Speter hash_arg_in_memory = 1; 195118334Speter if (MEM_IN_STRUCT_P (x)) hash_arg_in_struct = 1; 195218334Speter } 195318334Speter /* Now that we have already found this special case, 195418334Speter might as well speed it up as much as possible. */ 195518334Speter hash += (unsigned) MEM; 195618334Speter x = XEXP (x, 0); 195718334Speter goto repeat; 195818334Speter 195918334Speter case PRE_DEC: 196018334Speter case PRE_INC: 196118334Speter case POST_DEC: 196218334Speter case POST_INC: 196318334Speter case PC: 196418334Speter case CC0: 196518334Speter case CALL: 196618334Speter case UNSPEC_VOLATILE: 196718334Speter do_not_record = 1; 196818334Speter return 0; 196918334Speter 197018334Speter case ASM_OPERANDS: 197118334Speter if (MEM_VOLATILE_P (x)) 197218334Speter { 197318334Speter do_not_record = 1; 197418334Speter return 0; 197518334Speter } 197618334Speter } 197718334Speter 197818334Speter i = GET_RTX_LENGTH (code) - 1; 197918334Speter hash += (unsigned) code + (unsigned) GET_MODE (x); 198018334Speter fmt = GET_RTX_FORMAT (code); 198118334Speter for (; i >= 0; i--) 198218334Speter { 198318334Speter if (fmt[i] == 'e') 198418334Speter { 198518334Speter rtx tem = XEXP (x, i); 198618334Speter 198718334Speter /* If we are about to do the last recursive call 198818334Speter needed at this level, change it into iteration. 198918334Speter This function is called enough to be worth it. */ 199018334Speter if (i == 0) 199118334Speter { 199218334Speter x = tem; 199318334Speter goto repeat; 199418334Speter } 199518334Speter hash += canon_hash (tem, 0); 199618334Speter } 199718334Speter else if (fmt[i] == 'E') 199818334Speter for (j = 0; j < XVECLEN (x, i); j++) 199918334Speter hash += canon_hash (XVECEXP (x, i, j), 0); 200018334Speter else if (fmt[i] == 's') 200118334Speter { 200218334Speter register unsigned char *p = (unsigned char *) XSTR (x, i); 200318334Speter if (p) 200418334Speter while (*p) 200518334Speter hash += *p++; 200618334Speter } 200718334Speter else if (fmt[i] == 'i') 200818334Speter { 200918334Speter register unsigned tem = XINT (x, i); 201018334Speter hash += tem; 201118334Speter } 201218334Speter else 201318334Speter abort (); 201418334Speter } 201518334Speter return hash; 201618334Speter} 201718334Speter 201818334Speter/* Like canon_hash but with no side effects. */ 201918334Speter 202018334Speterstatic unsigned 202118334Spetersafe_hash (x, mode) 202218334Speter rtx x; 202318334Speter enum machine_mode mode; 202418334Speter{ 202518334Speter int save_do_not_record = do_not_record; 202618334Speter int save_hash_arg_in_memory = hash_arg_in_memory; 202718334Speter int save_hash_arg_in_struct = hash_arg_in_struct; 202818334Speter unsigned hash = canon_hash (x, mode); 202918334Speter hash_arg_in_memory = save_hash_arg_in_memory; 203018334Speter hash_arg_in_struct = save_hash_arg_in_struct; 203118334Speter do_not_record = save_do_not_record; 203218334Speter return hash; 203318334Speter} 203418334Speter 203518334Speter/* Return 1 iff X and Y would canonicalize into the same thing, 203618334Speter without actually constructing the canonicalization of either one. 203718334Speter If VALIDATE is nonzero, 203818334Speter we assume X is an expression being processed from the rtl 203918334Speter and Y was found in the hash table. We check register refs 204018334Speter in Y for being marked as valid. 204118334Speter 204218334Speter If EQUAL_VALUES is nonzero, we allow a register to match a constant value 204318334Speter that is known to be in the register. Ordinarily, we don't allow them 204418334Speter to match, because letting them match would cause unpredictable results 204518334Speter in all the places that search a hash table chain for an equivalent 204618334Speter for a given value. A possible equivalent that has different structure 204718334Speter has its hash code computed from different data. Whether the hash code 204818334Speter is the same as that of the the given value is pure luck. */ 204918334Speter 205018334Speterstatic int 205118334Speterexp_equiv_p (x, y, validate, equal_values) 205218334Speter rtx x, y; 205318334Speter int validate; 205418334Speter int equal_values; 205518334Speter{ 205618334Speter register int i, j; 205718334Speter register enum rtx_code code; 205818334Speter register char *fmt; 205918334Speter 206018334Speter /* Note: it is incorrect to assume an expression is equivalent to itself 206118334Speter if VALIDATE is nonzero. */ 206218334Speter if (x == y && !validate) 206318334Speter return 1; 206418334Speter if (x == 0 || y == 0) 206518334Speter return x == y; 206618334Speter 206718334Speter code = GET_CODE (x); 206818334Speter if (code != GET_CODE (y)) 206918334Speter { 207018334Speter if (!equal_values) 207118334Speter return 0; 207218334Speter 207318334Speter /* If X is a constant and Y is a register or vice versa, they may be 207418334Speter equivalent. We only have to validate if Y is a register. */ 207518334Speter if (CONSTANT_P (x) && GET_CODE (y) == REG 207618334Speter && REGNO_QTY_VALID_P (REGNO (y)) 207718334Speter && GET_MODE (y) == qty_mode[reg_qty[REGNO (y)]] 207818334Speter && rtx_equal_p (x, qty_const[reg_qty[REGNO (y)]]) 207918334Speter && (! validate || reg_in_table[REGNO (y)] == reg_tick[REGNO (y)])) 208018334Speter return 1; 208118334Speter 208218334Speter if (CONSTANT_P (y) && code == REG 208318334Speter && REGNO_QTY_VALID_P (REGNO (x)) 208418334Speter && GET_MODE (x) == qty_mode[reg_qty[REGNO (x)]] 208518334Speter && rtx_equal_p (y, qty_const[reg_qty[REGNO (x)]])) 208618334Speter return 1; 208718334Speter 208818334Speter return 0; 208918334Speter } 209018334Speter 209118334Speter /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */ 209218334Speter if (GET_MODE (x) != GET_MODE (y)) 209318334Speter return 0; 209418334Speter 209518334Speter switch (code) 209618334Speter { 209718334Speter case PC: 209818334Speter case CC0: 209918334Speter return x == y; 210018334Speter 210118334Speter case CONST_INT: 210218334Speter return INTVAL (x) == INTVAL (y); 210318334Speter 210418334Speter case LABEL_REF: 210518334Speter return XEXP (x, 0) == XEXP (y, 0); 210618334Speter 210718334Speter case SYMBOL_REF: 210818334Speter return XSTR (x, 0) == XSTR (y, 0); 210918334Speter 211018334Speter case REG: 211118334Speter { 211218334Speter int regno = REGNO (y); 211318334Speter int endregno 211418334Speter = regno + (regno >= FIRST_PSEUDO_REGISTER ? 1 211518334Speter : HARD_REGNO_NREGS (regno, GET_MODE (y))); 211618334Speter int i; 211718334Speter 211818334Speter /* If the quantities are not the same, the expressions are not 211918334Speter equivalent. If there are and we are not to validate, they 212018334Speter are equivalent. Otherwise, ensure all regs are up-to-date. */ 212118334Speter 212218334Speter if (reg_qty[REGNO (x)] != reg_qty[regno]) 212318334Speter return 0; 212418334Speter 212518334Speter if (! validate) 212618334Speter return 1; 212718334Speter 212818334Speter for (i = regno; i < endregno; i++) 212918334Speter if (reg_in_table[i] != reg_tick[i]) 213018334Speter return 0; 213118334Speter 213218334Speter return 1; 213318334Speter } 213418334Speter 213518334Speter /* For commutative operations, check both orders. */ 213618334Speter case PLUS: 213718334Speter case MULT: 213818334Speter case AND: 213918334Speter case IOR: 214018334Speter case XOR: 214118334Speter case NE: 214218334Speter case EQ: 214318334Speter return ((exp_equiv_p (XEXP (x, 0), XEXP (y, 0), validate, equal_values) 214418334Speter && exp_equiv_p (XEXP (x, 1), XEXP (y, 1), 214518334Speter validate, equal_values)) 214618334Speter || (exp_equiv_p (XEXP (x, 0), XEXP (y, 1), 214718334Speter validate, equal_values) 214818334Speter && exp_equiv_p (XEXP (x, 1), XEXP (y, 0), 214918334Speter validate, equal_values))); 215018334Speter } 215118334Speter 215218334Speter /* Compare the elements. If any pair of corresponding elements 215318334Speter fail to match, return 0 for the whole things. */ 215418334Speter 215518334Speter fmt = GET_RTX_FORMAT (code); 215618334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 215718334Speter { 215818334Speter switch (fmt[i]) 215918334Speter { 216018334Speter case 'e': 216118334Speter if (! exp_equiv_p (XEXP (x, i), XEXP (y, i), validate, equal_values)) 216218334Speter return 0; 216318334Speter break; 216418334Speter 216518334Speter case 'E': 216618334Speter if (XVECLEN (x, i) != XVECLEN (y, i)) 216718334Speter return 0; 216818334Speter for (j = 0; j < XVECLEN (x, i); j++) 216918334Speter if (! exp_equiv_p (XVECEXP (x, i, j), XVECEXP (y, i, j), 217018334Speter validate, equal_values)) 217118334Speter return 0; 217218334Speter break; 217318334Speter 217418334Speter case 's': 217518334Speter if (strcmp (XSTR (x, i), XSTR (y, i))) 217618334Speter return 0; 217718334Speter break; 217818334Speter 217918334Speter case 'i': 218018334Speter if (XINT (x, i) != XINT (y, i)) 218118334Speter return 0; 218218334Speter break; 218318334Speter 218418334Speter case 'w': 218518334Speter if (XWINT (x, i) != XWINT (y, i)) 218618334Speter return 0; 218718334Speter break; 218818334Speter 218918334Speter case '0': 219018334Speter break; 219118334Speter 219218334Speter default: 219318334Speter abort (); 219418334Speter } 219518334Speter } 219618334Speter 219718334Speter return 1; 219818334Speter} 219918334Speter 220018334Speter/* Return 1 iff any subexpression of X matches Y. 220118334Speter Here we do not require that X or Y be valid (for registers referred to) 220218334Speter for being in the hash table. */ 220318334Speter 220418334Speterstatic int 220518334Speterrefers_to_p (x, y) 220618334Speter rtx x, y; 220718334Speter{ 220818334Speter register int i; 220918334Speter register enum rtx_code code; 221018334Speter register char *fmt; 221118334Speter 221218334Speter repeat: 221318334Speter if (x == y) 221418334Speter return 1; 221518334Speter if (x == 0 || y == 0) 221618334Speter return 0; 221718334Speter 221818334Speter code = GET_CODE (x); 221918334Speter /* If X as a whole has the same code as Y, they may match. 222018334Speter If so, return 1. */ 222118334Speter if (code == GET_CODE (y)) 222218334Speter { 222318334Speter if (exp_equiv_p (x, y, 0, 1)) 222418334Speter return 1; 222518334Speter } 222618334Speter 222718334Speter /* X does not match, so try its subexpressions. */ 222818334Speter 222918334Speter fmt = GET_RTX_FORMAT (code); 223018334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 223118334Speter if (fmt[i] == 'e') 223218334Speter { 223318334Speter if (i == 0) 223418334Speter { 223518334Speter x = XEXP (x, 0); 223618334Speter goto repeat; 223718334Speter } 223818334Speter else 223918334Speter if (refers_to_p (XEXP (x, i), y)) 224018334Speter return 1; 224118334Speter } 224218334Speter else if (fmt[i] == 'E') 224318334Speter { 224418334Speter int j; 224518334Speter for (j = 0; j < XVECLEN (x, i); j++) 224618334Speter if (refers_to_p (XVECEXP (x, i, j), y)) 224718334Speter return 1; 224818334Speter } 224918334Speter 225018334Speter return 0; 225118334Speter} 225218334Speter 225318334Speter/* Given ADDR and SIZE (a memory address, and the size of the memory reference), 225418334Speter set PBASE, PSTART, and PEND which correspond to the base of the address, 225518334Speter the starting offset, and ending offset respectively. 225618334Speter 225718334Speter ADDR is known to be a nonvarying address. */ 225818334Speter 225918334Speter/* ??? Despite what the comments say, this function is in fact frequently 226018334Speter passed varying addresses. This does not appear to cause any problems. */ 226118334Speter 226218334Speterstatic void 226318334Speterset_nonvarying_address_components (addr, size, pbase, pstart, pend) 226418334Speter rtx addr; 226518334Speter int size; 226618334Speter rtx *pbase; 226718334Speter HOST_WIDE_INT *pstart, *pend; 226818334Speter{ 226918334Speter rtx base; 227018334Speter HOST_WIDE_INT start, end; 227118334Speter 227218334Speter base = addr; 227318334Speter start = 0; 227418334Speter end = 0; 227518334Speter 227618334Speter /* Registers with nonvarying addresses usually have constant equivalents; 227718334Speter but the frame pointer register is also possible. */ 227818334Speter if (GET_CODE (base) == REG 227918334Speter && qty_const != 0 228018334Speter && REGNO_QTY_VALID_P (REGNO (base)) 228118334Speter && qty_mode[reg_qty[REGNO (base)]] == GET_MODE (base) 228218334Speter && qty_const[reg_qty[REGNO (base)]] != 0) 228318334Speter base = qty_const[reg_qty[REGNO (base)]]; 228418334Speter else if (GET_CODE (base) == PLUS 228518334Speter && GET_CODE (XEXP (base, 1)) == CONST_INT 228618334Speter && GET_CODE (XEXP (base, 0)) == REG 228718334Speter && qty_const != 0 228818334Speter && REGNO_QTY_VALID_P (REGNO (XEXP (base, 0))) 228918334Speter && (qty_mode[reg_qty[REGNO (XEXP (base, 0))]] 229018334Speter == GET_MODE (XEXP (base, 0))) 229118334Speter && qty_const[reg_qty[REGNO (XEXP (base, 0))]]) 229218334Speter { 229318334Speter start = INTVAL (XEXP (base, 1)); 229418334Speter base = qty_const[reg_qty[REGNO (XEXP (base, 0))]]; 229518334Speter } 229618334Speter /* This can happen as the result of virtual register instantiation, 229718334Speter if the initial offset is too large to be a valid address. */ 229818334Speter else if (GET_CODE (base) == PLUS 229918334Speter && GET_CODE (XEXP (base, 0)) == REG 230018334Speter && GET_CODE (XEXP (base, 1)) == REG 230118334Speter && qty_const != 0 230218334Speter && REGNO_QTY_VALID_P (REGNO (XEXP (base, 0))) 230318334Speter && (qty_mode[reg_qty[REGNO (XEXP (base, 0))]] 230418334Speter == GET_MODE (XEXP (base, 0))) 230518334Speter && qty_const[reg_qty[REGNO (XEXP (base, 0))]] 230618334Speter && REGNO_QTY_VALID_P (REGNO (XEXP (base, 1))) 230718334Speter && (qty_mode[reg_qty[REGNO (XEXP (base, 1))]] 230818334Speter == GET_MODE (XEXP (base, 1))) 230918334Speter && qty_const[reg_qty[REGNO (XEXP (base, 1))]]) 231018334Speter { 231118334Speter rtx tem = qty_const[reg_qty[REGNO (XEXP (base, 1))]]; 231218334Speter base = qty_const[reg_qty[REGNO (XEXP (base, 0))]]; 231318334Speter 231418334Speter /* One of the two values must be a constant. */ 231518334Speter if (GET_CODE (base) != CONST_INT) 231618334Speter { 231718334Speter if (GET_CODE (tem) != CONST_INT) 231818334Speter abort (); 231918334Speter start = INTVAL (tem); 232018334Speter } 232118334Speter else 232218334Speter { 232318334Speter start = INTVAL (base); 232418334Speter base = tem; 232518334Speter } 232618334Speter } 232718334Speter 232818334Speter /* Handle everything that we can find inside an address that has been 232918334Speter viewed as constant. */ 233018334Speter 233118334Speter while (1) 233218334Speter { 233318334Speter /* If no part of this switch does a "continue", the code outside 233418334Speter will exit this loop. */ 233518334Speter 233618334Speter switch (GET_CODE (base)) 233718334Speter { 233818334Speter case LO_SUM: 233918334Speter /* By definition, operand1 of a LO_SUM is the associated constant 234018334Speter address. Use the associated constant address as the base 234118334Speter instead. */ 234218334Speter base = XEXP (base, 1); 234318334Speter continue; 234418334Speter 234518334Speter case CONST: 234618334Speter /* Strip off CONST. */ 234718334Speter base = XEXP (base, 0); 234818334Speter continue; 234918334Speter 235018334Speter case PLUS: 235118334Speter if (GET_CODE (XEXP (base, 1)) == CONST_INT) 235218334Speter { 235318334Speter start += INTVAL (XEXP (base, 1)); 235418334Speter base = XEXP (base, 0); 235518334Speter continue; 235618334Speter } 235718334Speter break; 235818334Speter 235918334Speter case AND: 236018334Speter /* Handle the case of an AND which is the negative of a power of 236118334Speter two. This is used to represent unaligned memory operations. */ 236218334Speter if (GET_CODE (XEXP (base, 1)) == CONST_INT 236318334Speter && exact_log2 (- INTVAL (XEXP (base, 1))) > 0) 236418334Speter { 236518334Speter set_nonvarying_address_components (XEXP (base, 0), size, 236618334Speter pbase, pstart, pend); 236718334Speter 236818334Speter /* Assume the worst misalignment. START is affected, but not 236918334Speter END, so compensate but adjusting SIZE. Don't lose any 237018334Speter constant we already had. */ 237118334Speter 237218334Speter size = *pend - *pstart - INTVAL (XEXP (base, 1)) - 1; 237318334Speter start += *pstart + INTVAL (XEXP (base, 1)) + 1; 237418334Speter end += *pend; 237518334Speter base = *pbase; 237618334Speter } 237718334Speter break; 237818334Speter } 237918334Speter 238018334Speter break; 238118334Speter } 238218334Speter 238318334Speter if (GET_CODE (base) == CONST_INT) 238418334Speter { 238518334Speter start += INTVAL (base); 238618334Speter base = const0_rtx; 238718334Speter } 238818334Speter 238918334Speter end = start + size; 239018334Speter 239118334Speter /* Set the return values. */ 239218334Speter *pbase = base; 239318334Speter *pstart = start; 239418334Speter *pend = end; 239518334Speter} 239618334Speter 239718334Speter/* Return 1 iff any subexpression of X refers to memory 239818334Speter at an address of BASE plus some offset 239918334Speter such that any of the bytes' offsets fall between START (inclusive) 240018334Speter and END (exclusive). 240118334Speter 240218334Speter The value is undefined if X is a varying address (as determined by 240318334Speter cse_rtx_addr_varies_p). This function is not used in such cases. 240418334Speter 240518334Speter When used in the cse pass, `qty_const' is nonzero, and it is used 240618334Speter to treat an address that is a register with a known constant value 240718334Speter as if it were that constant value. 240818334Speter In the loop pass, `qty_const' is zero, so this is not done. */ 240918334Speter 241018334Speterstatic int 241118334Speterrefers_to_mem_p (x, base, start, end) 241218334Speter rtx x, base; 241318334Speter HOST_WIDE_INT start, end; 241418334Speter{ 241518334Speter register HOST_WIDE_INT i; 241618334Speter register enum rtx_code code; 241718334Speter register char *fmt; 241818334Speter 241918334Speter repeat: 242018334Speter if (x == 0) 242118334Speter return 0; 242218334Speter 242318334Speter code = GET_CODE (x); 242418334Speter if (code == MEM) 242518334Speter { 242618334Speter register rtx addr = XEXP (x, 0); /* Get the address. */ 242718334Speter rtx mybase; 242818334Speter HOST_WIDE_INT mystart, myend; 242918334Speter 243018334Speter set_nonvarying_address_components (addr, GET_MODE_SIZE (GET_MODE (x)), 243118334Speter &mybase, &mystart, &myend); 243218334Speter 243318334Speter 243418334Speter /* refers_to_mem_p is never called with varying addresses. 243518334Speter If the base addresses are not equal, there is no chance 243618334Speter of the memory addresses conflicting. */ 243718334Speter if (! rtx_equal_p (mybase, base)) 243818334Speter return 0; 243918334Speter 244018334Speter return myend > start && mystart < end; 244118334Speter } 244218334Speter 244318334Speter /* X does not match, so try its subexpressions. */ 244418334Speter 244518334Speter fmt = GET_RTX_FORMAT (code); 244618334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 244718334Speter if (fmt[i] == 'e') 244818334Speter { 244918334Speter if (i == 0) 245018334Speter { 245118334Speter x = XEXP (x, 0); 245218334Speter goto repeat; 245318334Speter } 245418334Speter else 245518334Speter if (refers_to_mem_p (XEXP (x, i), base, start, end)) 245618334Speter return 1; 245718334Speter } 245818334Speter else if (fmt[i] == 'E') 245918334Speter { 246018334Speter int j; 246118334Speter for (j = 0; j < XVECLEN (x, i); j++) 246218334Speter if (refers_to_mem_p (XVECEXP (x, i, j), base, start, end)) 246318334Speter return 1; 246418334Speter } 246518334Speter 246618334Speter return 0; 246718334Speter} 246818334Speter 246918334Speter/* Nonzero if X refers to memory at a varying address; 247018334Speter except that a register which has at the moment a known constant value 247118334Speter isn't considered variable. */ 247218334Speter 247318334Speterstatic int 247418334Spetercse_rtx_addr_varies_p (x) 247518334Speter rtx x; 247618334Speter{ 247718334Speter /* We need not check for X and the equivalence class being of the same 247818334Speter mode because if X is equivalent to a constant in some mode, it 247918334Speter doesn't vary in any mode. */ 248018334Speter 248118334Speter if (GET_CODE (x) == MEM 248218334Speter && GET_CODE (XEXP (x, 0)) == REG 248318334Speter && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))) 248418334Speter && GET_MODE (XEXP (x, 0)) == qty_mode[reg_qty[REGNO (XEXP (x, 0))]] 248518334Speter && qty_const[reg_qty[REGNO (XEXP (x, 0))]] != 0) 248618334Speter return 0; 248718334Speter 248818334Speter if (GET_CODE (x) == MEM 248918334Speter && GET_CODE (XEXP (x, 0)) == PLUS 249018334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 249118334Speter && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG 249218334Speter && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 0))) 249318334Speter && (GET_MODE (XEXP (XEXP (x, 0), 0)) 249418334Speter == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]]) 249518334Speter && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]]) 249618334Speter return 0; 249718334Speter 249818334Speter /* This can happen as the result of virtual register instantiation, if 249918334Speter the initial constant is too large to be a valid address. This gives 250018334Speter us a three instruction sequence, load large offset into a register, 250118334Speter load fp minus a constant into a register, then a MEM which is the 250218334Speter sum of the two `constant' registers. */ 250318334Speter if (GET_CODE (x) == MEM 250418334Speter && GET_CODE (XEXP (x, 0)) == PLUS 250518334Speter && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG 250618334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == REG 250718334Speter && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 0))) 250818334Speter && (GET_MODE (XEXP (XEXP (x, 0), 0)) 250918334Speter == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]]) 251018334Speter && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]] 251118334Speter && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 1))) 251218334Speter && (GET_MODE (XEXP (XEXP (x, 0), 1)) 251318334Speter == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 1))]]) 251418334Speter && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 1))]]) 251518334Speter return 0; 251618334Speter 251718334Speter return rtx_addr_varies_p (x); 251818334Speter} 251918334Speter 252018334Speter/* Canonicalize an expression: 252118334Speter replace each register reference inside it 252218334Speter with the "oldest" equivalent register. 252318334Speter 252418334Speter If INSN is non-zero and we are replacing a pseudo with a hard register 252518334Speter or vice versa, validate_change is used to ensure that INSN remains valid 252618334Speter after we make our substitution. The calls are made with IN_GROUP non-zero 252718334Speter so apply_change_group must be called upon the outermost return from this 252818334Speter function (unless INSN is zero). The result of apply_change_group can 252918334Speter generally be discarded since the changes we are making are optional. */ 253018334Speter 253118334Speterstatic rtx 253218334Spetercanon_reg (x, insn) 253318334Speter rtx x; 253418334Speter rtx insn; 253518334Speter{ 253618334Speter register int i; 253718334Speter register enum rtx_code code; 253818334Speter register char *fmt; 253918334Speter 254018334Speter if (x == 0) 254118334Speter return x; 254218334Speter 254318334Speter code = GET_CODE (x); 254418334Speter switch (code) 254518334Speter { 254618334Speter case PC: 254718334Speter case CC0: 254818334Speter case CONST: 254918334Speter case CONST_INT: 255018334Speter case CONST_DOUBLE: 255118334Speter case SYMBOL_REF: 255218334Speter case LABEL_REF: 255318334Speter case ADDR_VEC: 255418334Speter case ADDR_DIFF_VEC: 255518334Speter return x; 255618334Speter 255718334Speter case REG: 255818334Speter { 255918334Speter register int first; 256018334Speter 256118334Speter /* Never replace a hard reg, because hard regs can appear 256218334Speter in more than one machine mode, and we must preserve the mode 256318334Speter of each occurrence. Also, some hard regs appear in 256418334Speter MEMs that are shared and mustn't be altered. Don't try to 256518334Speter replace any reg that maps to a reg of class NO_REGS. */ 256618334Speter if (REGNO (x) < FIRST_PSEUDO_REGISTER 256718334Speter || ! REGNO_QTY_VALID_P (REGNO (x))) 256818334Speter return x; 256918334Speter 257018334Speter first = qty_first_reg[reg_qty[REGNO (x)]]; 257118334Speter return (first >= FIRST_PSEUDO_REGISTER ? regno_reg_rtx[first] 257218334Speter : REGNO_REG_CLASS (first) == NO_REGS ? x 257318334Speter : gen_rtx (REG, qty_mode[reg_qty[REGNO (x)]], first)); 257418334Speter } 257518334Speter } 257618334Speter 257718334Speter fmt = GET_RTX_FORMAT (code); 257818334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 257918334Speter { 258018334Speter register int j; 258118334Speter 258218334Speter if (fmt[i] == 'e') 258318334Speter { 258418334Speter rtx new = canon_reg (XEXP (x, i), insn); 258518334Speter 258618334Speter /* If replacing pseudo with hard reg or vice versa, ensure the 258718334Speter insn remains valid. Likewise if the insn has MATCH_DUPs. */ 258818334Speter if (insn != 0 && new != 0 258918334Speter && GET_CODE (new) == REG && GET_CODE (XEXP (x, i)) == REG 259018334Speter && (((REGNO (new) < FIRST_PSEUDO_REGISTER) 259118334Speter != (REGNO (XEXP (x, i)) < FIRST_PSEUDO_REGISTER)) 259218334Speter || insn_n_dups[recog_memoized (insn)] > 0)) 259318334Speter validate_change (insn, &XEXP (x, i), new, 1); 259418334Speter else 259518334Speter XEXP (x, i) = new; 259618334Speter } 259718334Speter else if (fmt[i] == 'E') 259818334Speter for (j = 0; j < XVECLEN (x, i); j++) 259918334Speter XVECEXP (x, i, j) = canon_reg (XVECEXP (x, i, j), insn); 260018334Speter } 260118334Speter 260218334Speter return x; 260318334Speter} 260418334Speter 260518334Speter/* LOC is a location with INSN that is an operand address (the contents of 260618334Speter a MEM). Find the best equivalent address to use that is valid for this 260718334Speter insn. 260818334Speter 260918334Speter On most CISC machines, complicated address modes are costly, and rtx_cost 261018334Speter is a good approximation for that cost. However, most RISC machines have 261118334Speter only a few (usually only one) memory reference formats. If an address is 261218334Speter valid at all, it is often just as cheap as any other address. Hence, for 261318334Speter RISC machines, we use the configuration macro `ADDRESS_COST' to compare the 261418334Speter costs of various addresses. For two addresses of equal cost, choose the one 261518334Speter with the highest `rtx_cost' value as that has the potential of eliminating 261618334Speter the most insns. For equal costs, we choose the first in the equivalence 261718334Speter class. Note that we ignore the fact that pseudo registers are cheaper 261818334Speter than hard registers here because we would also prefer the pseudo registers. 261918334Speter */ 262018334Speter 262118334Speterstatic void 262218334Speterfind_best_addr (insn, loc) 262318334Speter rtx insn; 262418334Speter rtx *loc; 262518334Speter{ 262618334Speter struct table_elt *elt, *p; 262718334Speter rtx addr = *loc; 262818334Speter int our_cost; 262918334Speter int found_better = 1; 263018334Speter int save_do_not_record = do_not_record; 263118334Speter int save_hash_arg_in_memory = hash_arg_in_memory; 263218334Speter int save_hash_arg_in_struct = hash_arg_in_struct; 263318334Speter int addr_volatile; 263418334Speter int regno; 263518334Speter unsigned hash; 263618334Speter 263718334Speter /* Do not try to replace constant addresses or addresses of local and 263818334Speter argument slots. These MEM expressions are made only once and inserted 263918334Speter in many instructions, as well as being used to control symbol table 264018334Speter output. It is not safe to clobber them. 264118334Speter 264218334Speter There are some uncommon cases where the address is already in a register 264318334Speter for some reason, but we cannot take advantage of that because we have 264418334Speter no easy way to unshare the MEM. In addition, looking up all stack 264518334Speter addresses is costly. */ 264618334Speter if ((GET_CODE (addr) == PLUS 264718334Speter && GET_CODE (XEXP (addr, 0)) == REG 264818334Speter && GET_CODE (XEXP (addr, 1)) == CONST_INT 264918334Speter && (regno = REGNO (XEXP (addr, 0)), 265018334Speter regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM 265118334Speter || regno == ARG_POINTER_REGNUM)) 265218334Speter || (GET_CODE (addr) == REG 265318334Speter && (regno = REGNO (addr), regno == FRAME_POINTER_REGNUM 265418334Speter || regno == HARD_FRAME_POINTER_REGNUM 265518334Speter || regno == ARG_POINTER_REGNUM)) 265618334Speter || CONSTANT_ADDRESS_P (addr)) 265718334Speter return; 265818334Speter 265918334Speter /* If this address is not simply a register, try to fold it. This will 266018334Speter sometimes simplify the expression. Many simplifications 266118334Speter will not be valid, but some, usually applying the associative rule, will 266218334Speter be valid and produce better code. */ 266318334Speter if (GET_CODE (addr) != REG 266418334Speter && validate_change (insn, loc, fold_rtx (addr, insn), 0)) 266518334Speter addr = *loc; 266618334Speter 266718334Speter /* If this address is not in the hash table, we can't look for equivalences 266818334Speter of the whole address. Also, ignore if volatile. */ 266918334Speter 267018334Speter do_not_record = 0; 267118334Speter hash = HASH (addr, Pmode); 267218334Speter addr_volatile = do_not_record; 267318334Speter do_not_record = save_do_not_record; 267418334Speter hash_arg_in_memory = save_hash_arg_in_memory; 267518334Speter hash_arg_in_struct = save_hash_arg_in_struct; 267618334Speter 267718334Speter if (addr_volatile) 267818334Speter return; 267918334Speter 268018334Speter elt = lookup (addr, hash, Pmode); 268118334Speter 268218334Speter#ifndef ADDRESS_COST 268318334Speter if (elt) 268418334Speter { 268518334Speter our_cost = elt->cost; 268618334Speter 268718334Speter /* Find the lowest cost below ours that works. */ 268818334Speter for (elt = elt->first_same_value; elt; elt = elt->next_same_value) 268918334Speter if (elt->cost < our_cost 269018334Speter && (GET_CODE (elt->exp) == REG 269118334Speter || exp_equiv_p (elt->exp, elt->exp, 1, 0)) 269218334Speter && validate_change (insn, loc, 269318334Speter canon_reg (copy_rtx (elt->exp), NULL_RTX), 0)) 269418334Speter return; 269518334Speter } 269618334Speter#else 269718334Speter 269818334Speter if (elt) 269918334Speter { 270018334Speter /* We need to find the best (under the criteria documented above) entry 270118334Speter in the class that is valid. We use the `flag' field to indicate 270218334Speter choices that were invalid and iterate until we can't find a better 270318334Speter one that hasn't already been tried. */ 270418334Speter 270518334Speter for (p = elt->first_same_value; p; p = p->next_same_value) 270618334Speter p->flag = 0; 270718334Speter 270818334Speter while (found_better) 270918334Speter { 271018334Speter int best_addr_cost = ADDRESS_COST (*loc); 271118334Speter int best_rtx_cost = (elt->cost + 1) >> 1; 271218334Speter struct table_elt *best_elt = elt; 271318334Speter 271418334Speter found_better = 0; 271518334Speter for (p = elt->first_same_value; p; p = p->next_same_value) 271618334Speter if (! p->flag 271718334Speter && (GET_CODE (p->exp) == REG 271818334Speter || exp_equiv_p (p->exp, p->exp, 1, 0)) 271918334Speter && (ADDRESS_COST (p->exp) < best_addr_cost 272018334Speter || (ADDRESS_COST (p->exp) == best_addr_cost 272118334Speter && (p->cost + 1) >> 1 > best_rtx_cost))) 272218334Speter { 272318334Speter found_better = 1; 272418334Speter best_addr_cost = ADDRESS_COST (p->exp); 272518334Speter best_rtx_cost = (p->cost + 1) >> 1; 272618334Speter best_elt = p; 272718334Speter } 272818334Speter 272918334Speter if (found_better) 273018334Speter { 273118334Speter if (validate_change (insn, loc, 273218334Speter canon_reg (copy_rtx (best_elt->exp), 273318334Speter NULL_RTX), 0)) 273418334Speter return; 273518334Speter else 273618334Speter best_elt->flag = 1; 273718334Speter } 273818334Speter } 273918334Speter } 274018334Speter 274118334Speter /* If the address is a binary operation with the first operand a register 274218334Speter and the second a constant, do the same as above, but looking for 274318334Speter equivalences of the register. Then try to simplify before checking for 274418334Speter the best address to use. This catches a few cases: First is when we 274518334Speter have REG+const and the register is another REG+const. We can often merge 274618334Speter the constants and eliminate one insn and one register. It may also be 274718334Speter that a machine has a cheap REG+REG+const. Finally, this improves the 274818334Speter code on the Alpha for unaligned byte stores. */ 274918334Speter 275018334Speter if (flag_expensive_optimizations 275118334Speter && (GET_RTX_CLASS (GET_CODE (*loc)) == '2' 275218334Speter || GET_RTX_CLASS (GET_CODE (*loc)) == 'c') 275318334Speter && GET_CODE (XEXP (*loc, 0)) == REG 275418334Speter && GET_CODE (XEXP (*loc, 1)) == CONST_INT) 275518334Speter { 275618334Speter rtx c = XEXP (*loc, 1); 275718334Speter 275818334Speter do_not_record = 0; 275918334Speter hash = HASH (XEXP (*loc, 0), Pmode); 276018334Speter do_not_record = save_do_not_record; 276118334Speter hash_arg_in_memory = save_hash_arg_in_memory; 276218334Speter hash_arg_in_struct = save_hash_arg_in_struct; 276318334Speter 276418334Speter elt = lookup (XEXP (*loc, 0), hash, Pmode); 276518334Speter if (elt == 0) 276618334Speter return; 276718334Speter 276818334Speter /* We need to find the best (under the criteria documented above) entry 276918334Speter in the class that is valid. We use the `flag' field to indicate 277018334Speter choices that were invalid and iterate until we can't find a better 277118334Speter one that hasn't already been tried. */ 277218334Speter 277318334Speter for (p = elt->first_same_value; p; p = p->next_same_value) 277418334Speter p->flag = 0; 277518334Speter 277618334Speter while (found_better) 277718334Speter { 277818334Speter int best_addr_cost = ADDRESS_COST (*loc); 277918334Speter int best_rtx_cost = (COST (*loc) + 1) >> 1; 278018334Speter struct table_elt *best_elt = elt; 278118334Speter rtx best_rtx = *loc; 278218334Speter int count; 278318334Speter 278418334Speter /* This is at worst case an O(n^2) algorithm, so limit our search 278518334Speter to the first 32 elements on the list. This avoids trouble 278618334Speter compiling code with very long basic blocks that can easily 278718334Speter call cse_gen_binary so many times that we run out of memory. */ 278818334Speter 278918334Speter found_better = 0; 279018334Speter for (p = elt->first_same_value, count = 0; 279118334Speter p && count < 32; 279218334Speter p = p->next_same_value, count++) 279318334Speter if (! p->flag 279418334Speter && (GET_CODE (p->exp) == REG 279518334Speter || exp_equiv_p (p->exp, p->exp, 1, 0))) 279618334Speter { 279718334Speter rtx new = cse_gen_binary (GET_CODE (*loc), Pmode, p->exp, c); 279818334Speter 279918334Speter if ((ADDRESS_COST (new) < best_addr_cost 280018334Speter || (ADDRESS_COST (new) == best_addr_cost 280118334Speter && (COST (new) + 1) >> 1 > best_rtx_cost))) 280218334Speter { 280318334Speter found_better = 1; 280418334Speter best_addr_cost = ADDRESS_COST (new); 280518334Speter best_rtx_cost = (COST (new) + 1) >> 1; 280618334Speter best_elt = p; 280718334Speter best_rtx = new; 280818334Speter } 280918334Speter } 281018334Speter 281118334Speter if (found_better) 281218334Speter { 281318334Speter if (validate_change (insn, loc, 281418334Speter canon_reg (copy_rtx (best_rtx), 281518334Speter NULL_RTX), 0)) 281618334Speter return; 281718334Speter else 281818334Speter best_elt->flag = 1; 281918334Speter } 282018334Speter } 282118334Speter } 282218334Speter#endif 282318334Speter} 282418334Speter 282518334Speter/* Given an operation (CODE, *PARG1, *PARG2), where code is a comparison 282618334Speter operation (EQ, NE, GT, etc.), follow it back through the hash table and 282718334Speter what values are being compared. 282818334Speter 282918334Speter *PARG1 and *PARG2 are updated to contain the rtx representing the values 283018334Speter actually being compared. For example, if *PARG1 was (cc0) and *PARG2 283118334Speter was (const_int 0), *PARG1 and *PARG2 will be set to the objects that were 283218334Speter compared to produce cc0. 283318334Speter 283418334Speter The return value is the comparison operator and is either the code of 283518334Speter A or the code corresponding to the inverse of the comparison. */ 283618334Speter 283718334Speterstatic enum rtx_code 283818334Speterfind_comparison_args (code, parg1, parg2, pmode1, pmode2) 283918334Speter enum rtx_code code; 284018334Speter rtx *parg1, *parg2; 284118334Speter enum machine_mode *pmode1, *pmode2; 284218334Speter{ 284318334Speter rtx arg1, arg2; 284418334Speter 284518334Speter arg1 = *parg1, arg2 = *parg2; 284618334Speter 284718334Speter /* If ARG2 is const0_rtx, see what ARG1 is equivalent to. */ 284818334Speter 284918334Speter while (arg2 == CONST0_RTX (GET_MODE (arg1))) 285018334Speter { 285118334Speter /* Set non-zero when we find something of interest. */ 285218334Speter rtx x = 0; 285318334Speter int reverse_code = 0; 285418334Speter struct table_elt *p = 0; 285518334Speter 285618334Speter /* If arg1 is a COMPARE, extract the comparison arguments from it. 285718334Speter On machines with CC0, this is the only case that can occur, since 285818334Speter fold_rtx will return the COMPARE or item being compared with zero 285918334Speter when given CC0. */ 286018334Speter 286118334Speter if (GET_CODE (arg1) == COMPARE && arg2 == const0_rtx) 286218334Speter x = arg1; 286318334Speter 286418334Speter /* If ARG1 is a comparison operator and CODE is testing for 286518334Speter STORE_FLAG_VALUE, get the inner arguments. */ 286618334Speter 286718334Speter else if (GET_RTX_CLASS (GET_CODE (arg1)) == '<') 286818334Speter { 286918334Speter if (code == NE 287018334Speter || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_INT 287118334Speter && code == LT && STORE_FLAG_VALUE == -1) 287218334Speter#ifdef FLOAT_STORE_FLAG_VALUE 287318334Speter || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_FLOAT 287418334Speter && FLOAT_STORE_FLAG_VALUE < 0) 287518334Speter#endif 287618334Speter ) 287718334Speter x = arg1; 287818334Speter else if (code == EQ 287918334Speter || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_INT 288018334Speter && code == GE && STORE_FLAG_VALUE == -1) 288118334Speter#ifdef FLOAT_STORE_FLAG_VALUE 288218334Speter || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_FLOAT 288318334Speter && FLOAT_STORE_FLAG_VALUE < 0) 288418334Speter#endif 288518334Speter ) 288618334Speter x = arg1, reverse_code = 1; 288718334Speter } 288818334Speter 288918334Speter /* ??? We could also check for 289018334Speter 289118334Speter (ne (and (eq (...) (const_int 1))) (const_int 0)) 289218334Speter 289318334Speter and related forms, but let's wait until we see them occurring. */ 289418334Speter 289518334Speter if (x == 0) 289618334Speter /* Look up ARG1 in the hash table and see if it has an equivalence 289718334Speter that lets us see what is being compared. */ 289818334Speter p = lookup (arg1, safe_hash (arg1, GET_MODE (arg1)) % NBUCKETS, 289918334Speter GET_MODE (arg1)); 290018334Speter if (p) p = p->first_same_value; 290118334Speter 290218334Speter for (; p; p = p->next_same_value) 290318334Speter { 290418334Speter enum machine_mode inner_mode = GET_MODE (p->exp); 290518334Speter 290618334Speter /* If the entry isn't valid, skip it. */ 290718334Speter if (! exp_equiv_p (p->exp, p->exp, 1, 0)) 290818334Speter continue; 290918334Speter 291018334Speter if (GET_CODE (p->exp) == COMPARE 291118334Speter /* Another possibility is that this machine has a compare insn 291218334Speter that includes the comparison code. In that case, ARG1 would 291318334Speter be equivalent to a comparison operation that would set ARG1 to 291418334Speter either STORE_FLAG_VALUE or zero. If this is an NE operation, 291518334Speter ORIG_CODE is the actual comparison being done; if it is an EQ, 291618334Speter we must reverse ORIG_CODE. On machine with a negative value 291718334Speter for STORE_FLAG_VALUE, also look at LT and GE operations. */ 291818334Speter || ((code == NE 291918334Speter || (code == LT 292018334Speter && GET_MODE_CLASS (inner_mode) == MODE_INT 292118334Speter && (GET_MODE_BITSIZE (inner_mode) 292218334Speter <= HOST_BITS_PER_WIDE_INT) 292318334Speter && (STORE_FLAG_VALUE 292418334Speter & ((HOST_WIDE_INT) 1 292518334Speter << (GET_MODE_BITSIZE (inner_mode) - 1)))) 292618334Speter#ifdef FLOAT_STORE_FLAG_VALUE 292718334Speter || (code == LT 292818334Speter && GET_MODE_CLASS (inner_mode) == MODE_FLOAT 292918334Speter && FLOAT_STORE_FLAG_VALUE < 0) 293018334Speter#endif 293118334Speter ) 293218334Speter && GET_RTX_CLASS (GET_CODE (p->exp)) == '<')) 293318334Speter { 293418334Speter x = p->exp; 293518334Speter break; 293618334Speter } 293718334Speter else if ((code == EQ 293818334Speter || (code == GE 293918334Speter && GET_MODE_CLASS (inner_mode) == MODE_INT 294018334Speter && (GET_MODE_BITSIZE (inner_mode) 294118334Speter <= HOST_BITS_PER_WIDE_INT) 294218334Speter && (STORE_FLAG_VALUE 294318334Speter & ((HOST_WIDE_INT) 1 294418334Speter << (GET_MODE_BITSIZE (inner_mode) - 1)))) 294518334Speter#ifdef FLOAT_STORE_FLAG_VALUE 294618334Speter || (code == GE 294718334Speter && GET_MODE_CLASS (inner_mode) == MODE_FLOAT 294818334Speter && FLOAT_STORE_FLAG_VALUE < 0) 294918334Speter#endif 295018334Speter ) 295118334Speter && GET_RTX_CLASS (GET_CODE (p->exp)) == '<') 295218334Speter { 295318334Speter reverse_code = 1; 295418334Speter x = p->exp; 295518334Speter break; 295618334Speter } 295718334Speter 295818334Speter /* If this is fp + constant, the equivalent is a better operand since 295918334Speter it may let us predict the value of the comparison. */ 296018334Speter else if (NONZERO_BASE_PLUS_P (p->exp)) 296118334Speter { 296218334Speter arg1 = p->exp; 296318334Speter continue; 296418334Speter } 296518334Speter } 296618334Speter 296718334Speter /* If we didn't find a useful equivalence for ARG1, we are done. 296818334Speter Otherwise, set up for the next iteration. */ 296918334Speter if (x == 0) 297018334Speter break; 297118334Speter 297218334Speter arg1 = XEXP (x, 0), arg2 = XEXP (x, 1); 297318334Speter if (GET_RTX_CLASS (GET_CODE (x)) == '<') 297418334Speter code = GET_CODE (x); 297518334Speter 297618334Speter if (reverse_code) 297718334Speter code = reverse_condition (code); 297818334Speter } 297918334Speter 298018334Speter /* Return our results. Return the modes from before fold_rtx 298118334Speter because fold_rtx might produce const_int, and then it's too late. */ 298218334Speter *pmode1 = GET_MODE (arg1), *pmode2 = GET_MODE (arg2); 298318334Speter *parg1 = fold_rtx (arg1, 0), *parg2 = fold_rtx (arg2, 0); 298418334Speter 298518334Speter return code; 298618334Speter} 298718334Speter 298818334Speter/* Try to simplify a unary operation CODE whose output mode is to be 298918334Speter MODE with input operand OP whose mode was originally OP_MODE. 299018334Speter Return zero if no simplification can be made. */ 299118334Speter 299218334Speterrtx 299318334Spetersimplify_unary_operation (code, mode, op, op_mode) 299418334Speter enum rtx_code code; 299518334Speter enum machine_mode mode; 299618334Speter rtx op; 299718334Speter enum machine_mode op_mode; 299818334Speter{ 299918334Speter register int width = GET_MODE_BITSIZE (mode); 300018334Speter 300118334Speter /* The order of these tests is critical so that, for example, we don't 300218334Speter check the wrong mode (input vs. output) for a conversion operation, 300318334Speter such as FIX. At some point, this should be simplified. */ 300418334Speter 300518334Speter#if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC) 300618334Speter 300718334Speter if (code == FLOAT && GET_MODE (op) == VOIDmode 300818334Speter && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT)) 300918334Speter { 301018334Speter HOST_WIDE_INT hv, lv; 301118334Speter REAL_VALUE_TYPE d; 301218334Speter 301318334Speter if (GET_CODE (op) == CONST_INT) 301418334Speter lv = INTVAL (op), hv = INTVAL (op) < 0 ? -1 : 0; 301518334Speter else 301618334Speter lv = CONST_DOUBLE_LOW (op), hv = CONST_DOUBLE_HIGH (op); 301718334Speter 301818334Speter#ifdef REAL_ARITHMETIC 301918334Speter REAL_VALUE_FROM_INT (d, lv, hv); 302018334Speter#else 302118334Speter if (hv < 0) 302218334Speter { 302318334Speter d = (double) (~ hv); 302418334Speter d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)) 302518334Speter * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))); 302618334Speter d += (double) (unsigned HOST_WIDE_INT) (~ lv); 302718334Speter d = (- d - 1.0); 302818334Speter } 302918334Speter else 303018334Speter { 303118334Speter d = (double) hv; 303218334Speter d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)) 303318334Speter * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))); 303418334Speter d += (double) (unsigned HOST_WIDE_INT) lv; 303518334Speter } 303618334Speter#endif /* REAL_ARITHMETIC */ 303718334Speter d = real_value_truncate (mode, d); 303818334Speter return CONST_DOUBLE_FROM_REAL_VALUE (d, mode); 303918334Speter } 304018334Speter else if (code == UNSIGNED_FLOAT && GET_MODE (op) == VOIDmode 304118334Speter && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT)) 304218334Speter { 304318334Speter HOST_WIDE_INT hv, lv; 304418334Speter REAL_VALUE_TYPE d; 304518334Speter 304618334Speter if (GET_CODE (op) == CONST_INT) 304718334Speter lv = INTVAL (op), hv = INTVAL (op) < 0 ? -1 : 0; 304818334Speter else 304918334Speter lv = CONST_DOUBLE_LOW (op), hv = CONST_DOUBLE_HIGH (op); 305018334Speter 305118334Speter if (op_mode == VOIDmode) 305218334Speter { 305318334Speter /* We don't know how to interpret negative-looking numbers in 305418334Speter this case, so don't try to fold those. */ 305518334Speter if (hv < 0) 305618334Speter return 0; 305718334Speter } 305818334Speter else if (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT * 2) 305918334Speter ; 306018334Speter else 306118334Speter hv = 0, lv &= GET_MODE_MASK (op_mode); 306218334Speter 306318334Speter#ifdef REAL_ARITHMETIC 306418334Speter REAL_VALUE_FROM_UNSIGNED_INT (d, lv, hv); 306518334Speter#else 306618334Speter 306718334Speter d = (double) (unsigned HOST_WIDE_INT) hv; 306818334Speter d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)) 306918334Speter * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))); 307018334Speter d += (double) (unsigned HOST_WIDE_INT) lv; 307118334Speter#endif /* REAL_ARITHMETIC */ 307218334Speter d = real_value_truncate (mode, d); 307318334Speter return CONST_DOUBLE_FROM_REAL_VALUE (d, mode); 307418334Speter } 307518334Speter#endif 307618334Speter 307718334Speter if (GET_CODE (op) == CONST_INT 307818334Speter && width <= HOST_BITS_PER_WIDE_INT && width > 0) 307918334Speter { 308018334Speter register HOST_WIDE_INT arg0 = INTVAL (op); 308118334Speter register HOST_WIDE_INT val; 308218334Speter 308318334Speter switch (code) 308418334Speter { 308518334Speter case NOT: 308618334Speter val = ~ arg0; 308718334Speter break; 308818334Speter 308918334Speter case NEG: 309018334Speter val = - arg0; 309118334Speter break; 309218334Speter 309318334Speter case ABS: 309418334Speter val = (arg0 >= 0 ? arg0 : - arg0); 309518334Speter break; 309618334Speter 309718334Speter case FFS: 309818334Speter /* Don't use ffs here. Instead, get low order bit and then its 309918334Speter number. If arg0 is zero, this will return 0, as desired. */ 310018334Speter arg0 &= GET_MODE_MASK (mode); 310118334Speter val = exact_log2 (arg0 & (- arg0)) + 1; 310218334Speter break; 310318334Speter 310418334Speter case TRUNCATE: 310518334Speter val = arg0; 310618334Speter break; 310718334Speter 310818334Speter case ZERO_EXTEND: 310918334Speter if (op_mode == VOIDmode) 311018334Speter op_mode = mode; 311118334Speter if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT) 311218334Speter { 311318334Speter /* If we were really extending the mode, 311418334Speter we would have to distinguish between zero-extension 311518334Speter and sign-extension. */ 311618334Speter if (width != GET_MODE_BITSIZE (op_mode)) 311718334Speter abort (); 311818334Speter val = arg0; 311918334Speter } 312018334Speter else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT) 312118334Speter val = arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode)); 312218334Speter else 312318334Speter return 0; 312418334Speter break; 312518334Speter 312618334Speter case SIGN_EXTEND: 312718334Speter if (op_mode == VOIDmode) 312818334Speter op_mode = mode; 312918334Speter if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT) 313018334Speter { 313118334Speter /* If we were really extending the mode, 313218334Speter we would have to distinguish between zero-extension 313318334Speter and sign-extension. */ 313418334Speter if (width != GET_MODE_BITSIZE (op_mode)) 313518334Speter abort (); 313618334Speter val = arg0; 313718334Speter } 313818334Speter else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT) 313918334Speter { 314018334Speter val 314118334Speter = arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode)); 314218334Speter if (val 314318334Speter & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (op_mode) - 1))) 314418334Speter val -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode); 314518334Speter } 314618334Speter else 314718334Speter return 0; 314818334Speter break; 314918334Speter 315018334Speter case SQRT: 315118334Speter return 0; 315218334Speter 315318334Speter default: 315418334Speter abort (); 315518334Speter } 315618334Speter 315718334Speter /* Clear the bits that don't belong in our mode, 315818334Speter unless they and our sign bit are all one. 315918334Speter So we get either a reasonable negative value or a reasonable 316018334Speter unsigned value for this mode. */ 316118334Speter if (width < HOST_BITS_PER_WIDE_INT 316218334Speter && ((val & ((HOST_WIDE_INT) (-1) << (width - 1))) 316318334Speter != ((HOST_WIDE_INT) (-1) << (width - 1)))) 316418334Speter val &= ((HOST_WIDE_INT) 1 << width) - 1; 316518334Speter 316618334Speter return GEN_INT (val); 316718334Speter } 316818334Speter 316918334Speter /* We can do some operations on integer CONST_DOUBLEs. Also allow 317018334Speter for a DImode operation on a CONST_INT. */ 317118334Speter else if (GET_MODE (op) == VOIDmode && width <= HOST_BITS_PER_INT * 2 317218334Speter && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT)) 317318334Speter { 317418334Speter HOST_WIDE_INT l1, h1, lv, hv; 317518334Speter 317618334Speter if (GET_CODE (op) == CONST_DOUBLE) 317718334Speter l1 = CONST_DOUBLE_LOW (op), h1 = CONST_DOUBLE_HIGH (op); 317818334Speter else 317918334Speter l1 = INTVAL (op), h1 = l1 < 0 ? -1 : 0; 318018334Speter 318118334Speter switch (code) 318218334Speter { 318318334Speter case NOT: 318418334Speter lv = ~ l1; 318518334Speter hv = ~ h1; 318618334Speter break; 318718334Speter 318818334Speter case NEG: 318918334Speter neg_double (l1, h1, &lv, &hv); 319018334Speter break; 319118334Speter 319218334Speter case ABS: 319318334Speter if (h1 < 0) 319418334Speter neg_double (l1, h1, &lv, &hv); 319518334Speter else 319618334Speter lv = l1, hv = h1; 319718334Speter break; 319818334Speter 319918334Speter case FFS: 320018334Speter hv = 0; 320118334Speter if (l1 == 0) 320218334Speter lv = HOST_BITS_PER_WIDE_INT + exact_log2 (h1 & (-h1)) + 1; 320318334Speter else 320418334Speter lv = exact_log2 (l1 & (-l1)) + 1; 320518334Speter break; 320618334Speter 320718334Speter case TRUNCATE: 320818334Speter /* This is just a change-of-mode, so do nothing. */ 320918334Speter lv = l1, hv = h1; 321018334Speter break; 321118334Speter 321218334Speter case ZERO_EXTEND: 321318334Speter if (op_mode == VOIDmode 321418334Speter || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT) 321518334Speter return 0; 321618334Speter 321718334Speter hv = 0; 321818334Speter lv = l1 & GET_MODE_MASK (op_mode); 321918334Speter break; 322018334Speter 322118334Speter case SIGN_EXTEND: 322218334Speter if (op_mode == VOIDmode 322318334Speter || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT) 322418334Speter return 0; 322518334Speter else 322618334Speter { 322718334Speter lv = l1 & GET_MODE_MASK (op_mode); 322818334Speter if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT 322918334Speter && (lv & ((HOST_WIDE_INT) 1 323018334Speter << (GET_MODE_BITSIZE (op_mode) - 1))) != 0) 323118334Speter lv -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode); 323218334Speter 323318334Speter hv = (lv < 0) ? ~ (HOST_WIDE_INT) 0 : 0; 323418334Speter } 323518334Speter break; 323618334Speter 323718334Speter case SQRT: 323818334Speter return 0; 323918334Speter 324018334Speter default: 324118334Speter return 0; 324218334Speter } 324318334Speter 324418334Speter return immed_double_const (lv, hv, mode); 324518334Speter } 324618334Speter 324718334Speter#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC) 324818334Speter else if (GET_CODE (op) == CONST_DOUBLE 324918334Speter && GET_MODE_CLASS (mode) == MODE_FLOAT) 325018334Speter { 325118334Speter REAL_VALUE_TYPE d; 325218334Speter jmp_buf handler; 325318334Speter rtx x; 325418334Speter 325518334Speter if (setjmp (handler)) 325618334Speter /* There used to be a warning here, but that is inadvisable. 325718334Speter People may want to cause traps, and the natural way 325818334Speter to do it should not get a warning. */ 325918334Speter return 0; 326018334Speter 326118334Speter set_float_handler (handler); 326218334Speter 326318334Speter REAL_VALUE_FROM_CONST_DOUBLE (d, op); 326418334Speter 326518334Speter switch (code) 326618334Speter { 326718334Speter case NEG: 326818334Speter d = REAL_VALUE_NEGATE (d); 326918334Speter break; 327018334Speter 327118334Speter case ABS: 327218334Speter if (REAL_VALUE_NEGATIVE (d)) 327318334Speter d = REAL_VALUE_NEGATE (d); 327418334Speter break; 327518334Speter 327618334Speter case FLOAT_TRUNCATE: 327718334Speter d = real_value_truncate (mode, d); 327818334Speter break; 327918334Speter 328018334Speter case FLOAT_EXTEND: 328118334Speter /* All this does is change the mode. */ 328218334Speter break; 328318334Speter 328418334Speter case FIX: 328518334Speter d = REAL_VALUE_RNDZINT (d); 328618334Speter break; 328718334Speter 328818334Speter case UNSIGNED_FIX: 328918334Speter d = REAL_VALUE_UNSIGNED_RNDZINT (d); 329018334Speter break; 329118334Speter 329218334Speter case SQRT: 329318334Speter return 0; 329418334Speter 329518334Speter default: 329618334Speter abort (); 329718334Speter } 329818334Speter 329918334Speter x = CONST_DOUBLE_FROM_REAL_VALUE (d, mode); 330018334Speter set_float_handler (NULL_PTR); 330118334Speter return x; 330218334Speter } 330318334Speter 330418334Speter else if (GET_CODE (op) == CONST_DOUBLE 330518334Speter && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT 330618334Speter && GET_MODE_CLASS (mode) == MODE_INT 330718334Speter && width <= HOST_BITS_PER_WIDE_INT && width > 0) 330818334Speter { 330918334Speter REAL_VALUE_TYPE d; 331018334Speter jmp_buf handler; 331118334Speter HOST_WIDE_INT val; 331218334Speter 331318334Speter if (setjmp (handler)) 331418334Speter return 0; 331518334Speter 331618334Speter set_float_handler (handler); 331718334Speter 331818334Speter REAL_VALUE_FROM_CONST_DOUBLE (d, op); 331918334Speter 332018334Speter switch (code) 332118334Speter { 332218334Speter case FIX: 332318334Speter val = REAL_VALUE_FIX (d); 332418334Speter break; 332518334Speter 332618334Speter case UNSIGNED_FIX: 332718334Speter val = REAL_VALUE_UNSIGNED_FIX (d); 332818334Speter break; 332918334Speter 333018334Speter default: 333118334Speter abort (); 333218334Speter } 333318334Speter 333418334Speter set_float_handler (NULL_PTR); 333518334Speter 333618334Speter /* Clear the bits that don't belong in our mode, 333718334Speter unless they and our sign bit are all one. 333818334Speter So we get either a reasonable negative value or a reasonable 333918334Speter unsigned value for this mode. */ 334018334Speter if (width < HOST_BITS_PER_WIDE_INT 334118334Speter && ((val & ((HOST_WIDE_INT) (-1) << (width - 1))) 334218334Speter != ((HOST_WIDE_INT) (-1) << (width - 1)))) 334318334Speter val &= ((HOST_WIDE_INT) 1 << width) - 1; 334418334Speter 334518334Speter /* If this would be an entire word for the target, but is not for 334618334Speter the host, then sign-extend on the host so that the number will look 334718334Speter the same way on the host that it would on the target. 334818334Speter 334918334Speter For example, when building a 64 bit alpha hosted 32 bit sparc 335018334Speter targeted compiler, then we want the 32 bit unsigned value -1 to be 335118334Speter represented as a 64 bit value -1, and not as 0x00000000ffffffff. 335218334Speter The later confuses the sparc backend. */ 335318334Speter 335418334Speter if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width 335518334Speter && (val & ((HOST_WIDE_INT) 1 << (width - 1)))) 335618334Speter val |= ((HOST_WIDE_INT) (-1) << width); 335718334Speter 335818334Speter return GEN_INT (val); 335918334Speter } 336018334Speter#endif 336118334Speter /* This was formerly used only for non-IEEE float. 336218334Speter eggert@twinsun.com says it is safe for IEEE also. */ 336318334Speter else 336418334Speter { 336518334Speter /* There are some simplifications we can do even if the operands 336618334Speter aren't constant. */ 336718334Speter switch (code) 336818334Speter { 336918334Speter case NEG: 337018334Speter case NOT: 337118334Speter /* (not (not X)) == X, similarly for NEG. */ 337218334Speter if (GET_CODE (op) == code) 337318334Speter return XEXP (op, 0); 337418334Speter break; 337518334Speter 337618334Speter case SIGN_EXTEND: 337718334Speter /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2)))) 337818334Speter becomes just the MINUS if its mode is MODE. This allows 337918334Speter folding switch statements on machines using casesi (such as 338018334Speter the Vax). */ 338118334Speter if (GET_CODE (op) == TRUNCATE 338218334Speter && GET_MODE (XEXP (op, 0)) == mode 338318334Speter && GET_CODE (XEXP (op, 0)) == MINUS 338418334Speter && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF 338518334Speter && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF) 338618334Speter return XEXP (op, 0); 338718334Speter 338818334Speter#ifdef POINTERS_EXTEND_UNSIGNED 338918334Speter if (! POINTERS_EXTEND_UNSIGNED 339018334Speter && mode == Pmode && GET_MODE (op) == ptr_mode 339118334Speter && CONSTANT_P (op)) 339218334Speter return convert_memory_address (Pmode, op); 339318334Speter#endif 339418334Speter break; 339518334Speter 339618334Speter#ifdef POINTERS_EXTEND_UNSIGNED 339718334Speter case ZERO_EXTEND: 339818334Speter if (POINTERS_EXTEND_UNSIGNED 339918334Speter && mode == Pmode && GET_MODE (op) == ptr_mode 340018334Speter && CONSTANT_P (op)) 340118334Speter return convert_memory_address (Pmode, op); 340218334Speter break; 340318334Speter#endif 340418334Speter } 340518334Speter 340618334Speter return 0; 340718334Speter } 340818334Speter} 340918334Speter 341018334Speter/* Simplify a binary operation CODE with result mode MODE, operating on OP0 341118334Speter and OP1. Return 0 if no simplification is possible. 341218334Speter 341318334Speter Don't use this for relational operations such as EQ or LT. 341418334Speter Use simplify_relational_operation instead. */ 341518334Speter 341618334Speterrtx 341718334Spetersimplify_binary_operation (code, mode, op0, op1) 341818334Speter enum rtx_code code; 341918334Speter enum machine_mode mode; 342018334Speter rtx op0, op1; 342118334Speter{ 342218334Speter register HOST_WIDE_INT arg0, arg1, arg0s, arg1s; 342318334Speter HOST_WIDE_INT val; 342418334Speter int width = GET_MODE_BITSIZE (mode); 342518334Speter rtx tem; 342618334Speter 342718334Speter /* Relational operations don't work here. We must know the mode 342818334Speter of the operands in order to do the comparison correctly. 342918334Speter Assuming a full word can give incorrect results. 343018334Speter Consider comparing 128 with -128 in QImode. */ 343118334Speter 343218334Speter if (GET_RTX_CLASS (code) == '<') 343318334Speter abort (); 343418334Speter 343518334Speter#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC) 343618334Speter if (GET_MODE_CLASS (mode) == MODE_FLOAT 343718334Speter && GET_CODE (op0) == CONST_DOUBLE && GET_CODE (op1) == CONST_DOUBLE 343818334Speter && mode == GET_MODE (op0) && mode == GET_MODE (op1)) 343918334Speter { 344018334Speter REAL_VALUE_TYPE f0, f1, value; 344118334Speter jmp_buf handler; 344218334Speter 344318334Speter if (setjmp (handler)) 344418334Speter return 0; 344518334Speter 344618334Speter set_float_handler (handler); 344718334Speter 344818334Speter REAL_VALUE_FROM_CONST_DOUBLE (f0, op0); 344918334Speter REAL_VALUE_FROM_CONST_DOUBLE (f1, op1); 345018334Speter f0 = real_value_truncate (mode, f0); 345118334Speter f1 = real_value_truncate (mode, f1); 345218334Speter 345318334Speter#ifdef REAL_ARITHMETIC 345418334Speter REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1); 345518334Speter#else 345618334Speter switch (code) 345718334Speter { 345818334Speter case PLUS: 345918334Speter value = f0 + f1; 346018334Speter break; 346118334Speter case MINUS: 346218334Speter value = f0 - f1; 346318334Speter break; 346418334Speter case MULT: 346518334Speter value = f0 * f1; 346618334Speter break; 346718334Speter case DIV: 346818334Speter#ifndef REAL_INFINITY 346918334Speter if (f1 == 0) 347018334Speter return 0; 347118334Speter#endif 347218334Speter value = f0 / f1; 347318334Speter break; 347418334Speter case SMIN: 347518334Speter value = MIN (f0, f1); 347618334Speter break; 347718334Speter case SMAX: 347818334Speter value = MAX (f0, f1); 347918334Speter break; 348018334Speter default: 348118334Speter abort (); 348218334Speter } 348318334Speter#endif 348418334Speter 348518334Speter value = real_value_truncate (mode, value); 348618334Speter set_float_handler (NULL_PTR); 348718334Speter return CONST_DOUBLE_FROM_REAL_VALUE (value, mode); 348818334Speter } 348918334Speter#endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */ 349018334Speter 349118334Speter /* We can fold some multi-word operations. */ 349218334Speter if (GET_MODE_CLASS (mode) == MODE_INT 349318334Speter && width == HOST_BITS_PER_WIDE_INT * 2 349418334Speter && (GET_CODE (op0) == CONST_DOUBLE || GET_CODE (op0) == CONST_INT) 349518334Speter && (GET_CODE (op1) == CONST_DOUBLE || GET_CODE (op1) == CONST_INT)) 349618334Speter { 349718334Speter HOST_WIDE_INT l1, l2, h1, h2, lv, hv; 349818334Speter 349918334Speter if (GET_CODE (op0) == CONST_DOUBLE) 350018334Speter l1 = CONST_DOUBLE_LOW (op0), h1 = CONST_DOUBLE_HIGH (op0); 350118334Speter else 350218334Speter l1 = INTVAL (op0), h1 = l1 < 0 ? -1 : 0; 350318334Speter 350418334Speter if (GET_CODE (op1) == CONST_DOUBLE) 350518334Speter l2 = CONST_DOUBLE_LOW (op1), h2 = CONST_DOUBLE_HIGH (op1); 350618334Speter else 350718334Speter l2 = INTVAL (op1), h2 = l2 < 0 ? -1 : 0; 350818334Speter 350918334Speter switch (code) 351018334Speter { 351118334Speter case MINUS: 351218334Speter /* A - B == A + (-B). */ 351318334Speter neg_double (l2, h2, &lv, &hv); 351418334Speter l2 = lv, h2 = hv; 351518334Speter 351618334Speter /* .. fall through ... */ 351718334Speter 351818334Speter case PLUS: 351918334Speter add_double (l1, h1, l2, h2, &lv, &hv); 352018334Speter break; 352118334Speter 352218334Speter case MULT: 352318334Speter mul_double (l1, h1, l2, h2, &lv, &hv); 352418334Speter break; 352518334Speter 352618334Speter case DIV: case MOD: case UDIV: case UMOD: 352718334Speter /* We'd need to include tree.h to do this and it doesn't seem worth 352818334Speter it. */ 352918334Speter return 0; 353018334Speter 353118334Speter case AND: 353218334Speter lv = l1 & l2, hv = h1 & h2; 353318334Speter break; 353418334Speter 353518334Speter case IOR: 353618334Speter lv = l1 | l2, hv = h1 | h2; 353718334Speter break; 353818334Speter 353918334Speter case XOR: 354018334Speter lv = l1 ^ l2, hv = h1 ^ h2; 354118334Speter break; 354218334Speter 354318334Speter case SMIN: 354418334Speter if (h1 < h2 354518334Speter || (h1 == h2 354618334Speter && ((unsigned HOST_WIDE_INT) l1 354718334Speter < (unsigned HOST_WIDE_INT) l2))) 354818334Speter lv = l1, hv = h1; 354918334Speter else 355018334Speter lv = l2, hv = h2; 355118334Speter break; 355218334Speter 355318334Speter case SMAX: 355418334Speter if (h1 > h2 355518334Speter || (h1 == h2 355618334Speter && ((unsigned HOST_WIDE_INT) l1 355718334Speter > (unsigned HOST_WIDE_INT) l2))) 355818334Speter lv = l1, hv = h1; 355918334Speter else 356018334Speter lv = l2, hv = h2; 356118334Speter break; 356218334Speter 356318334Speter case UMIN: 356418334Speter if ((unsigned HOST_WIDE_INT) h1 < (unsigned HOST_WIDE_INT) h2 356518334Speter || (h1 == h2 356618334Speter && ((unsigned HOST_WIDE_INT) l1 356718334Speter < (unsigned HOST_WIDE_INT) l2))) 356818334Speter lv = l1, hv = h1; 356918334Speter else 357018334Speter lv = l2, hv = h2; 357118334Speter break; 357218334Speter 357318334Speter case UMAX: 357418334Speter if ((unsigned HOST_WIDE_INT) h1 > (unsigned HOST_WIDE_INT) h2 357518334Speter || (h1 == h2 357618334Speter && ((unsigned HOST_WIDE_INT) l1 357718334Speter > (unsigned HOST_WIDE_INT) l2))) 357818334Speter lv = l1, hv = h1; 357918334Speter else 358018334Speter lv = l2, hv = h2; 358118334Speter break; 358218334Speter 358318334Speter case LSHIFTRT: case ASHIFTRT: 358418334Speter case ASHIFT: 358518334Speter case ROTATE: case ROTATERT: 358618334Speter#ifdef SHIFT_COUNT_TRUNCATED 358718334Speter if (SHIFT_COUNT_TRUNCATED) 358818334Speter l2 &= (GET_MODE_BITSIZE (mode) - 1), h2 = 0; 358918334Speter#endif 359018334Speter 359118334Speter if (h2 != 0 || l2 < 0 || l2 >= GET_MODE_BITSIZE (mode)) 359218334Speter return 0; 359318334Speter 359418334Speter if (code == LSHIFTRT || code == ASHIFTRT) 359518334Speter rshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv, 359618334Speter code == ASHIFTRT); 359718334Speter else if (code == ASHIFT) 359818334Speter lshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv, 1); 359918334Speter else if (code == ROTATE) 360018334Speter lrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv); 360118334Speter else /* code == ROTATERT */ 360218334Speter rrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv); 360318334Speter break; 360418334Speter 360518334Speter default: 360618334Speter return 0; 360718334Speter } 360818334Speter 360918334Speter return immed_double_const (lv, hv, mode); 361018334Speter } 361118334Speter 361218334Speter if (GET_CODE (op0) != CONST_INT || GET_CODE (op1) != CONST_INT 361318334Speter || width > HOST_BITS_PER_WIDE_INT || width == 0) 361418334Speter { 361518334Speter /* Even if we can't compute a constant result, 361618334Speter there are some cases worth simplifying. */ 361718334Speter 361818334Speter switch (code) 361918334Speter { 362018334Speter case PLUS: 362118334Speter /* In IEEE floating point, x+0 is not the same as x. Similarly 362218334Speter for the other optimizations below. */ 362318334Speter if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT 362418334Speter && FLOAT_MODE_P (mode) && ! flag_fast_math) 362518334Speter break; 362618334Speter 362718334Speter if (op1 == CONST0_RTX (mode)) 362818334Speter return op0; 362918334Speter 363018334Speter /* ((-a) + b) -> (b - a) and similarly for (a + (-b)) */ 363118334Speter if (GET_CODE (op0) == NEG) 363218334Speter return cse_gen_binary (MINUS, mode, op1, XEXP (op0, 0)); 363318334Speter else if (GET_CODE (op1) == NEG) 363418334Speter return cse_gen_binary (MINUS, mode, op0, XEXP (op1, 0)); 363518334Speter 363618334Speter /* Handle both-operands-constant cases. We can only add 363718334Speter CONST_INTs to constants since the sum of relocatable symbols 363818334Speter can't be handled by most assemblers. Don't add CONST_INT 363918334Speter to CONST_INT since overflow won't be computed properly if wider 364018334Speter than HOST_BITS_PER_WIDE_INT. */ 364118334Speter 364218334Speter if (CONSTANT_P (op0) && GET_MODE (op0) != VOIDmode 364318334Speter && GET_CODE (op1) == CONST_INT) 364418334Speter return plus_constant (op0, INTVAL (op1)); 364518334Speter else if (CONSTANT_P (op1) && GET_MODE (op1) != VOIDmode 364618334Speter && GET_CODE (op0) == CONST_INT) 364718334Speter return plus_constant (op1, INTVAL (op0)); 364818334Speter 364918334Speter /* See if this is something like X * C - X or vice versa or 365018334Speter if the multiplication is written as a shift. If so, we can 365118334Speter distribute and make a new multiply, shift, or maybe just 365218334Speter have X (if C is 2 in the example above). But don't make 365318334Speter real multiply if we didn't have one before. */ 365418334Speter 365518334Speter if (! FLOAT_MODE_P (mode)) 365618334Speter { 365718334Speter HOST_WIDE_INT coeff0 = 1, coeff1 = 1; 365818334Speter rtx lhs = op0, rhs = op1; 365918334Speter int had_mult = 0; 366018334Speter 366118334Speter if (GET_CODE (lhs) == NEG) 366218334Speter coeff0 = -1, lhs = XEXP (lhs, 0); 366318334Speter else if (GET_CODE (lhs) == MULT 366418334Speter && GET_CODE (XEXP (lhs, 1)) == CONST_INT) 366518334Speter { 366618334Speter coeff0 = INTVAL (XEXP (lhs, 1)), lhs = XEXP (lhs, 0); 366718334Speter had_mult = 1; 366818334Speter } 366918334Speter else if (GET_CODE (lhs) == ASHIFT 367018334Speter && GET_CODE (XEXP (lhs, 1)) == CONST_INT 367118334Speter && INTVAL (XEXP (lhs, 1)) >= 0 367218334Speter && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT) 367318334Speter { 367418334Speter coeff0 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1)); 367518334Speter lhs = XEXP (lhs, 0); 367618334Speter } 367718334Speter 367818334Speter if (GET_CODE (rhs) == NEG) 367918334Speter coeff1 = -1, rhs = XEXP (rhs, 0); 368018334Speter else if (GET_CODE (rhs) == MULT 368118334Speter && GET_CODE (XEXP (rhs, 1)) == CONST_INT) 368218334Speter { 368318334Speter coeff1 = INTVAL (XEXP (rhs, 1)), rhs = XEXP (rhs, 0); 368418334Speter had_mult = 1; 368518334Speter } 368618334Speter else if (GET_CODE (rhs) == ASHIFT 368718334Speter && GET_CODE (XEXP (rhs, 1)) == CONST_INT 368818334Speter && INTVAL (XEXP (rhs, 1)) >= 0 368918334Speter && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT) 369018334Speter { 369118334Speter coeff1 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1)); 369218334Speter rhs = XEXP (rhs, 0); 369318334Speter } 369418334Speter 369518334Speter if (rtx_equal_p (lhs, rhs)) 369618334Speter { 369718334Speter tem = cse_gen_binary (MULT, mode, lhs, 369818334Speter GEN_INT (coeff0 + coeff1)); 369918334Speter return (GET_CODE (tem) == MULT && ! had_mult) ? 0 : tem; 370018334Speter } 370118334Speter } 370218334Speter 370318334Speter /* If one of the operands is a PLUS or a MINUS, see if we can 370418334Speter simplify this by the associative law. 370518334Speter Don't use the associative law for floating point. 370618334Speter The inaccuracy makes it nonassociative, 370718334Speter and subtle programs can break if operations are associated. */ 370818334Speter 370918334Speter if (INTEGRAL_MODE_P (mode) 371018334Speter && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS 371118334Speter || GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS) 371218334Speter && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0) 371318334Speter return tem; 371418334Speter break; 371518334Speter 371618334Speter case COMPARE: 371718334Speter#ifdef HAVE_cc0 371818334Speter /* Convert (compare FOO (const_int 0)) to FOO unless we aren't 371918334Speter using cc0, in which case we want to leave it as a COMPARE 372018334Speter so we can distinguish it from a register-register-copy. 372118334Speter 372218334Speter In IEEE floating point, x-0 is not the same as x. */ 372318334Speter 372418334Speter if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT 372518334Speter || ! FLOAT_MODE_P (mode) || flag_fast_math) 372618334Speter && op1 == CONST0_RTX (mode)) 372718334Speter return op0; 372818334Speter#else 372918334Speter /* Do nothing here. */ 373018334Speter#endif 373118334Speter break; 373218334Speter 373318334Speter case MINUS: 373418334Speter /* None of these optimizations can be done for IEEE 373518334Speter floating point. */ 373618334Speter if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT 373718334Speter && FLOAT_MODE_P (mode) && ! flag_fast_math) 373818334Speter break; 373918334Speter 374018334Speter /* We can't assume x-x is 0 even with non-IEEE floating point, 374118334Speter but since it is zero except in very strange circumstances, we 374218334Speter will treat it as zero with -ffast-math. */ 374318334Speter if (rtx_equal_p (op0, op1) 374418334Speter && ! side_effects_p (op0) 374518334Speter && (! FLOAT_MODE_P (mode) || flag_fast_math)) 374618334Speter return CONST0_RTX (mode); 374718334Speter 374818334Speter /* Change subtraction from zero into negation. */ 374918334Speter if (op0 == CONST0_RTX (mode)) 375018334Speter return gen_rtx (NEG, mode, op1); 375118334Speter 375218334Speter /* (-1 - a) is ~a. */ 375318334Speter if (op0 == constm1_rtx) 375418334Speter return gen_rtx (NOT, mode, op1); 375518334Speter 375618334Speter /* Subtracting 0 has no effect. */ 375718334Speter if (op1 == CONST0_RTX (mode)) 375818334Speter return op0; 375918334Speter 376018334Speter /* See if this is something like X * C - X or vice versa or 376118334Speter if the multiplication is written as a shift. If so, we can 376218334Speter distribute and make a new multiply, shift, or maybe just 376318334Speter have X (if C is 2 in the example above). But don't make 376418334Speter real multiply if we didn't have one before. */ 376518334Speter 376618334Speter if (! FLOAT_MODE_P (mode)) 376718334Speter { 376818334Speter HOST_WIDE_INT coeff0 = 1, coeff1 = 1; 376918334Speter rtx lhs = op0, rhs = op1; 377018334Speter int had_mult = 0; 377118334Speter 377218334Speter if (GET_CODE (lhs) == NEG) 377318334Speter coeff0 = -1, lhs = XEXP (lhs, 0); 377418334Speter else if (GET_CODE (lhs) == MULT 377518334Speter && GET_CODE (XEXP (lhs, 1)) == CONST_INT) 377618334Speter { 377718334Speter coeff0 = INTVAL (XEXP (lhs, 1)), lhs = XEXP (lhs, 0); 377818334Speter had_mult = 1; 377918334Speter } 378018334Speter else if (GET_CODE (lhs) == ASHIFT 378118334Speter && GET_CODE (XEXP (lhs, 1)) == CONST_INT 378218334Speter && INTVAL (XEXP (lhs, 1)) >= 0 378318334Speter && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT) 378418334Speter { 378518334Speter coeff0 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1)); 378618334Speter lhs = XEXP (lhs, 0); 378718334Speter } 378818334Speter 378918334Speter if (GET_CODE (rhs) == NEG) 379018334Speter coeff1 = - 1, rhs = XEXP (rhs, 0); 379118334Speter else if (GET_CODE (rhs) == MULT 379218334Speter && GET_CODE (XEXP (rhs, 1)) == CONST_INT) 379318334Speter { 379418334Speter coeff1 = INTVAL (XEXP (rhs, 1)), rhs = XEXP (rhs, 0); 379518334Speter had_mult = 1; 379618334Speter } 379718334Speter else if (GET_CODE (rhs) == ASHIFT 379818334Speter && GET_CODE (XEXP (rhs, 1)) == CONST_INT 379918334Speter && INTVAL (XEXP (rhs, 1)) >= 0 380018334Speter && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT) 380118334Speter { 380218334Speter coeff1 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1)); 380318334Speter rhs = XEXP (rhs, 0); 380418334Speter } 380518334Speter 380618334Speter if (rtx_equal_p (lhs, rhs)) 380718334Speter { 380818334Speter tem = cse_gen_binary (MULT, mode, lhs, 380918334Speter GEN_INT (coeff0 - coeff1)); 381018334Speter return (GET_CODE (tem) == MULT && ! had_mult) ? 0 : tem; 381118334Speter } 381218334Speter } 381318334Speter 381418334Speter /* (a - (-b)) -> (a + b). */ 381518334Speter if (GET_CODE (op1) == NEG) 381618334Speter return cse_gen_binary (PLUS, mode, op0, XEXP (op1, 0)); 381718334Speter 381818334Speter /* If one of the operands is a PLUS or a MINUS, see if we can 381918334Speter simplify this by the associative law. 382018334Speter Don't use the associative law for floating point. 382118334Speter The inaccuracy makes it nonassociative, 382218334Speter and subtle programs can break if operations are associated. */ 382318334Speter 382418334Speter if (INTEGRAL_MODE_P (mode) 382518334Speter && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS 382618334Speter || GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS) 382718334Speter && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0) 382818334Speter return tem; 382918334Speter 383018334Speter /* Don't let a relocatable value get a negative coeff. */ 383118334Speter if (GET_CODE (op1) == CONST_INT && GET_MODE (op0) != VOIDmode) 383218334Speter return plus_constant (op0, - INTVAL (op1)); 383318334Speter 383418334Speter /* (x - (x & y)) -> (x & ~y) */ 383518334Speter if (GET_CODE (op1) == AND) 383618334Speter { 383718334Speter if (rtx_equal_p (op0, XEXP (op1, 0))) 383818334Speter return cse_gen_binary (AND, mode, op0, gen_rtx (NOT, mode, XEXP (op1, 1))); 383918334Speter if (rtx_equal_p (op0, XEXP (op1, 1))) 384018334Speter return cse_gen_binary (AND, mode, op0, gen_rtx (NOT, mode, XEXP (op1, 0))); 384118334Speter } 384218334Speter break; 384318334Speter 384418334Speter case MULT: 384518334Speter if (op1 == constm1_rtx) 384618334Speter { 384718334Speter tem = simplify_unary_operation (NEG, mode, op0, mode); 384818334Speter 384918334Speter return tem ? tem : gen_rtx (NEG, mode, op0); 385018334Speter } 385118334Speter 385218334Speter /* In IEEE floating point, x*0 is not always 0. */ 385318334Speter if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT 385418334Speter || ! FLOAT_MODE_P (mode) || flag_fast_math) 385518334Speter && op1 == CONST0_RTX (mode) 385618334Speter && ! side_effects_p (op0)) 385718334Speter return op1; 385818334Speter 385918334Speter /* In IEEE floating point, x*1 is not equivalent to x for nans. 386018334Speter However, ANSI says we can drop signals, 386118334Speter so we can do this anyway. */ 386218334Speter if (op1 == CONST1_RTX (mode)) 386318334Speter return op0; 386418334Speter 386518334Speter /* Convert multiply by constant power of two into shift unless 386618334Speter we are still generating RTL. This test is a kludge. */ 386718334Speter if (GET_CODE (op1) == CONST_INT 386818334Speter && (val = exact_log2 (INTVAL (op1))) >= 0 386918334Speter && ! rtx_equal_function_value_matters) 387018334Speter return gen_rtx (ASHIFT, mode, op0, GEN_INT (val)); 387118334Speter 387218334Speter if (GET_CODE (op1) == CONST_DOUBLE 387318334Speter && GET_MODE_CLASS (GET_MODE (op1)) == MODE_FLOAT) 387418334Speter { 387518334Speter REAL_VALUE_TYPE d; 387618334Speter jmp_buf handler; 387718334Speter int op1is2, op1ism1; 387818334Speter 387918334Speter if (setjmp (handler)) 388018334Speter return 0; 388118334Speter 388218334Speter set_float_handler (handler); 388318334Speter REAL_VALUE_FROM_CONST_DOUBLE (d, op1); 388418334Speter op1is2 = REAL_VALUES_EQUAL (d, dconst2); 388518334Speter op1ism1 = REAL_VALUES_EQUAL (d, dconstm1); 388618334Speter set_float_handler (NULL_PTR); 388718334Speter 388818334Speter /* x*2 is x+x and x*(-1) is -x */ 388918334Speter if (op1is2 && GET_MODE (op0) == mode) 389018334Speter return gen_rtx (PLUS, mode, op0, copy_rtx (op0)); 389118334Speter 389218334Speter else if (op1ism1 && GET_MODE (op0) == mode) 389318334Speter return gen_rtx (NEG, mode, op0); 389418334Speter } 389518334Speter break; 389618334Speter 389718334Speter case IOR: 389818334Speter if (op1 == const0_rtx) 389918334Speter return op0; 390018334Speter if (GET_CODE (op1) == CONST_INT 390118334Speter && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode)) 390218334Speter return op1; 390318334Speter if (rtx_equal_p (op0, op1) && ! side_effects_p (op0)) 390418334Speter return op0; 390518334Speter /* A | (~A) -> -1 */ 390618334Speter if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1)) 390718334Speter || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0))) 390818334Speter && ! side_effects_p (op0) 390918334Speter && GET_MODE_CLASS (mode) != MODE_CC) 391018334Speter return constm1_rtx; 391118334Speter break; 391218334Speter 391318334Speter case XOR: 391418334Speter if (op1 == const0_rtx) 391518334Speter return op0; 391618334Speter if (GET_CODE (op1) == CONST_INT 391718334Speter && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode)) 391818334Speter return gen_rtx (NOT, mode, op0); 391918334Speter if (op0 == op1 && ! side_effects_p (op0) 392018334Speter && GET_MODE_CLASS (mode) != MODE_CC) 392118334Speter return const0_rtx; 392218334Speter break; 392318334Speter 392418334Speter case AND: 392518334Speter if (op1 == const0_rtx && ! side_effects_p (op0)) 392618334Speter return const0_rtx; 392718334Speter if (GET_CODE (op1) == CONST_INT 392818334Speter && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode)) 392918334Speter return op0; 393018334Speter if (op0 == op1 && ! side_effects_p (op0) 393118334Speter && GET_MODE_CLASS (mode) != MODE_CC) 393218334Speter return op0; 393318334Speter /* A & (~A) -> 0 */ 393418334Speter if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1)) 393518334Speter || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0))) 393618334Speter && ! side_effects_p (op0) 393718334Speter && GET_MODE_CLASS (mode) != MODE_CC) 393818334Speter return const0_rtx; 393918334Speter break; 394018334Speter 394118334Speter case UDIV: 394218334Speter /* Convert divide by power of two into shift (divide by 1 handled 394318334Speter below). */ 394418334Speter if (GET_CODE (op1) == CONST_INT 394518334Speter && (arg1 = exact_log2 (INTVAL (op1))) > 0) 394618334Speter return gen_rtx (LSHIFTRT, mode, op0, GEN_INT (arg1)); 394718334Speter 394818334Speter /* ... fall through ... */ 394918334Speter 395018334Speter case DIV: 395118334Speter if (op1 == CONST1_RTX (mode)) 395218334Speter return op0; 395318334Speter 395418334Speter /* In IEEE floating point, 0/x is not always 0. */ 395518334Speter if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT 395618334Speter || ! FLOAT_MODE_P (mode) || flag_fast_math) 395718334Speter && op0 == CONST0_RTX (mode) 395818334Speter && ! side_effects_p (op1)) 395918334Speter return op0; 396018334Speter 396118334Speter#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC) 396218334Speter /* Change division by a constant into multiplication. Only do 396318334Speter this with -ffast-math until an expert says it is safe in 396418334Speter general. */ 396518334Speter else if (GET_CODE (op1) == CONST_DOUBLE 396618334Speter && GET_MODE_CLASS (GET_MODE (op1)) == MODE_FLOAT 396718334Speter && op1 != CONST0_RTX (mode) 396818334Speter && flag_fast_math) 396918334Speter { 397018334Speter REAL_VALUE_TYPE d; 397118334Speter REAL_VALUE_FROM_CONST_DOUBLE (d, op1); 397218334Speter 397318334Speter if (! REAL_VALUES_EQUAL (d, dconst0)) 397418334Speter { 397518334Speter#if defined (REAL_ARITHMETIC) 397618334Speter REAL_ARITHMETIC (d, rtx_to_tree_code (DIV), dconst1, d); 397718334Speter return gen_rtx (MULT, mode, op0, 397818334Speter CONST_DOUBLE_FROM_REAL_VALUE (d, mode)); 397918334Speter#else 398018334Speter return gen_rtx (MULT, mode, op0, 398118334Speter CONST_DOUBLE_FROM_REAL_VALUE (1./d, mode)); 398218334Speter#endif 398318334Speter } 398418334Speter } 398518334Speter#endif 398618334Speter break; 398718334Speter 398818334Speter case UMOD: 398918334Speter /* Handle modulus by power of two (mod with 1 handled below). */ 399018334Speter if (GET_CODE (op1) == CONST_INT 399118334Speter && exact_log2 (INTVAL (op1)) > 0) 399218334Speter return gen_rtx (AND, mode, op0, GEN_INT (INTVAL (op1) - 1)); 399318334Speter 399418334Speter /* ... fall through ... */ 399518334Speter 399618334Speter case MOD: 399718334Speter if ((op0 == const0_rtx || op1 == const1_rtx) 399818334Speter && ! side_effects_p (op0) && ! side_effects_p (op1)) 399918334Speter return const0_rtx; 400018334Speter break; 400118334Speter 400218334Speter case ROTATERT: 400318334Speter case ROTATE: 400418334Speter /* Rotating ~0 always results in ~0. */ 400518334Speter if (GET_CODE (op0) == CONST_INT && width <= HOST_BITS_PER_WIDE_INT 400618334Speter && INTVAL (op0) == GET_MODE_MASK (mode) 400718334Speter && ! side_effects_p (op1)) 400818334Speter return op0; 400918334Speter 401018334Speter /* ... fall through ... */ 401118334Speter 401218334Speter case ASHIFT: 401318334Speter case ASHIFTRT: 401418334Speter case LSHIFTRT: 401518334Speter if (op1 == const0_rtx) 401618334Speter return op0; 401718334Speter if (op0 == const0_rtx && ! side_effects_p (op1)) 401818334Speter return op0; 401918334Speter break; 402018334Speter 402118334Speter case SMIN: 402218334Speter if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (op1) == CONST_INT 402318334Speter && INTVAL (op1) == (HOST_WIDE_INT) 1 << (width -1) 402418334Speter && ! side_effects_p (op0)) 402518334Speter return op1; 402618334Speter else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0)) 402718334Speter return op0; 402818334Speter break; 402918334Speter 403018334Speter case SMAX: 403118334Speter if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (op1) == CONST_INT 403218334Speter && (INTVAL (op1) 403318334Speter == (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode) >> 1) 403418334Speter && ! side_effects_p (op0)) 403518334Speter return op1; 403618334Speter else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0)) 403718334Speter return op0; 403818334Speter break; 403918334Speter 404018334Speter case UMIN: 404118334Speter if (op1 == const0_rtx && ! side_effects_p (op0)) 404218334Speter return op1; 404318334Speter else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0)) 404418334Speter return op0; 404518334Speter break; 404618334Speter 404718334Speter case UMAX: 404818334Speter if (op1 == constm1_rtx && ! side_effects_p (op0)) 404918334Speter return op1; 405018334Speter else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0)) 405118334Speter return op0; 405218334Speter break; 405318334Speter 405418334Speter default: 405518334Speter abort (); 405618334Speter } 405718334Speter 405818334Speter return 0; 405918334Speter } 406018334Speter 406118334Speter /* Get the integer argument values in two forms: 406218334Speter zero-extended in ARG0, ARG1 and sign-extended in ARG0S, ARG1S. */ 406318334Speter 406418334Speter arg0 = INTVAL (op0); 406518334Speter arg1 = INTVAL (op1); 406618334Speter 406718334Speter if (width < HOST_BITS_PER_WIDE_INT) 406818334Speter { 406918334Speter arg0 &= ((HOST_WIDE_INT) 1 << width) - 1; 407018334Speter arg1 &= ((HOST_WIDE_INT) 1 << width) - 1; 407118334Speter 407218334Speter arg0s = arg0; 407318334Speter if (arg0s & ((HOST_WIDE_INT) 1 << (width - 1))) 407418334Speter arg0s |= ((HOST_WIDE_INT) (-1) << width); 407518334Speter 407618334Speter arg1s = arg1; 407718334Speter if (arg1s & ((HOST_WIDE_INT) 1 << (width - 1))) 407818334Speter arg1s |= ((HOST_WIDE_INT) (-1) << width); 407918334Speter } 408018334Speter else 408118334Speter { 408218334Speter arg0s = arg0; 408318334Speter arg1s = arg1; 408418334Speter } 408518334Speter 408618334Speter /* Compute the value of the arithmetic. */ 408718334Speter 408818334Speter switch (code) 408918334Speter { 409018334Speter case PLUS: 409118334Speter val = arg0s + arg1s; 409218334Speter break; 409318334Speter 409418334Speter case MINUS: 409518334Speter val = arg0s - arg1s; 409618334Speter break; 409718334Speter 409818334Speter case MULT: 409918334Speter val = arg0s * arg1s; 410018334Speter break; 410118334Speter 410218334Speter case DIV: 410318334Speter if (arg1s == 0) 410418334Speter return 0; 410518334Speter val = arg0s / arg1s; 410618334Speter break; 410718334Speter 410818334Speter case MOD: 410918334Speter if (arg1s == 0) 411018334Speter return 0; 411118334Speter val = arg0s % arg1s; 411218334Speter break; 411318334Speter 411418334Speter case UDIV: 411518334Speter if (arg1 == 0) 411618334Speter return 0; 411718334Speter val = (unsigned HOST_WIDE_INT) arg0 / arg1; 411818334Speter break; 411918334Speter 412018334Speter case UMOD: 412118334Speter if (arg1 == 0) 412218334Speter return 0; 412318334Speter val = (unsigned HOST_WIDE_INT) arg0 % arg1; 412418334Speter break; 412518334Speter 412618334Speter case AND: 412718334Speter val = arg0 & arg1; 412818334Speter break; 412918334Speter 413018334Speter case IOR: 413118334Speter val = arg0 | arg1; 413218334Speter break; 413318334Speter 413418334Speter case XOR: 413518334Speter val = arg0 ^ arg1; 413618334Speter break; 413718334Speter 413818334Speter case LSHIFTRT: 413918334Speter /* If shift count is undefined, don't fold it; let the machine do 414018334Speter what it wants. But truncate it if the machine will do that. */ 414118334Speter if (arg1 < 0) 414218334Speter return 0; 414318334Speter 414418334Speter#ifdef SHIFT_COUNT_TRUNCATED 414518334Speter if (SHIFT_COUNT_TRUNCATED) 414618334Speter arg1 %= width; 414718334Speter#endif 414818334Speter 414918334Speter val = ((unsigned HOST_WIDE_INT) arg0) >> arg1; 415018334Speter break; 415118334Speter 415218334Speter case ASHIFT: 415318334Speter if (arg1 < 0) 415418334Speter return 0; 415518334Speter 415618334Speter#ifdef SHIFT_COUNT_TRUNCATED 415718334Speter if (SHIFT_COUNT_TRUNCATED) 415818334Speter arg1 %= width; 415918334Speter#endif 416018334Speter 416118334Speter val = ((unsigned HOST_WIDE_INT) arg0) << arg1; 416218334Speter break; 416318334Speter 416418334Speter case ASHIFTRT: 416518334Speter if (arg1 < 0) 416618334Speter return 0; 416718334Speter 416818334Speter#ifdef SHIFT_COUNT_TRUNCATED 416918334Speter if (SHIFT_COUNT_TRUNCATED) 417018334Speter arg1 %= width; 417118334Speter#endif 417218334Speter 417318334Speter val = arg0s >> arg1; 417418334Speter 417518334Speter /* Bootstrap compiler may not have sign extended the right shift. 417618334Speter Manually extend the sign to insure bootstrap cc matches gcc. */ 417718334Speter if (arg0s < 0 && arg1 > 0) 417818334Speter val |= ((HOST_WIDE_INT) -1) << (HOST_BITS_PER_WIDE_INT - arg1); 417918334Speter 418018334Speter break; 418118334Speter 418218334Speter case ROTATERT: 418318334Speter if (arg1 < 0) 418418334Speter return 0; 418518334Speter 418618334Speter arg1 %= width; 418718334Speter val = ((((unsigned HOST_WIDE_INT) arg0) << (width - arg1)) 418818334Speter | (((unsigned HOST_WIDE_INT) arg0) >> arg1)); 418918334Speter break; 419018334Speter 419118334Speter case ROTATE: 419218334Speter if (arg1 < 0) 419318334Speter return 0; 419418334Speter 419518334Speter arg1 %= width; 419618334Speter val = ((((unsigned HOST_WIDE_INT) arg0) << arg1) 419718334Speter | (((unsigned HOST_WIDE_INT) arg0) >> (width - arg1))); 419818334Speter break; 419918334Speter 420018334Speter case COMPARE: 420118334Speter /* Do nothing here. */ 420218334Speter return 0; 420318334Speter 420418334Speter case SMIN: 420518334Speter val = arg0s <= arg1s ? arg0s : arg1s; 420618334Speter break; 420718334Speter 420818334Speter case UMIN: 420918334Speter val = ((unsigned HOST_WIDE_INT) arg0 421018334Speter <= (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1); 421118334Speter break; 421218334Speter 421318334Speter case SMAX: 421418334Speter val = arg0s > arg1s ? arg0s : arg1s; 421518334Speter break; 421618334Speter 421718334Speter case UMAX: 421818334Speter val = ((unsigned HOST_WIDE_INT) arg0 421918334Speter > (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1); 422018334Speter break; 422118334Speter 422218334Speter default: 422318334Speter abort (); 422418334Speter } 422518334Speter 422618334Speter /* Clear the bits that don't belong in our mode, unless they and our sign 422718334Speter bit are all one. So we get either a reasonable negative value or a 422818334Speter reasonable unsigned value for this mode. */ 422918334Speter if (width < HOST_BITS_PER_WIDE_INT 423018334Speter && ((val & ((HOST_WIDE_INT) (-1) << (width - 1))) 423118334Speter != ((HOST_WIDE_INT) (-1) << (width - 1)))) 423218334Speter val &= ((HOST_WIDE_INT) 1 << width) - 1; 423318334Speter 423418334Speter /* If this would be an entire word for the target, but is not for 423518334Speter the host, then sign-extend on the host so that the number will look 423618334Speter the same way on the host that it would on the target. 423718334Speter 423818334Speter For example, when building a 64 bit alpha hosted 32 bit sparc 423918334Speter targeted compiler, then we want the 32 bit unsigned value -1 to be 424018334Speter represented as a 64 bit value -1, and not as 0x00000000ffffffff. 424118334Speter The later confuses the sparc backend. */ 424218334Speter 424318334Speter if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width 424418334Speter && (val & ((HOST_WIDE_INT) 1 << (width - 1)))) 424518334Speter val |= ((HOST_WIDE_INT) (-1) << width); 424618334Speter 424718334Speter return GEN_INT (val); 424818334Speter} 424918334Speter 425018334Speter/* Simplify a PLUS or MINUS, at least one of whose operands may be another 425118334Speter PLUS or MINUS. 425218334Speter 425318334Speter Rather than test for specific case, we do this by a brute-force method 425418334Speter and do all possible simplifications until no more changes occur. Then 425518334Speter we rebuild the operation. */ 425618334Speter 425718334Speterstatic rtx 425818334Spetersimplify_plus_minus (code, mode, op0, op1) 425918334Speter enum rtx_code code; 426018334Speter enum machine_mode mode; 426118334Speter rtx op0, op1; 426218334Speter{ 426318334Speter rtx ops[8]; 426418334Speter int negs[8]; 426518334Speter rtx result, tem; 426618334Speter int n_ops = 2, input_ops = 2, input_consts = 0, n_consts = 0; 426718334Speter int first = 1, negate = 0, changed; 426818334Speter int i, j; 426918334Speter 427018334Speter bzero ((char *) ops, sizeof ops); 427118334Speter 427218334Speter /* Set up the two operands and then expand them until nothing has been 427318334Speter changed. If we run out of room in our array, give up; this should 427418334Speter almost never happen. */ 427518334Speter 427618334Speter ops[0] = op0, ops[1] = op1, negs[0] = 0, negs[1] = (code == MINUS); 427718334Speter 427818334Speter changed = 1; 427918334Speter while (changed) 428018334Speter { 428118334Speter changed = 0; 428218334Speter 428318334Speter for (i = 0; i < n_ops; i++) 428418334Speter switch (GET_CODE (ops[i])) 428518334Speter { 428618334Speter case PLUS: 428718334Speter case MINUS: 428818334Speter if (n_ops == 7) 428918334Speter return 0; 429018334Speter 429118334Speter ops[n_ops] = XEXP (ops[i], 1); 429218334Speter negs[n_ops++] = GET_CODE (ops[i]) == MINUS ? !negs[i] : negs[i]; 429318334Speter ops[i] = XEXP (ops[i], 0); 429418334Speter input_ops++; 429518334Speter changed = 1; 429618334Speter break; 429718334Speter 429818334Speter case NEG: 429918334Speter ops[i] = XEXP (ops[i], 0); 430018334Speter negs[i] = ! negs[i]; 430118334Speter changed = 1; 430218334Speter break; 430318334Speter 430418334Speter case CONST: 430518334Speter ops[i] = XEXP (ops[i], 0); 430618334Speter input_consts++; 430718334Speter changed = 1; 430818334Speter break; 430918334Speter 431018334Speter case NOT: 431118334Speter /* ~a -> (-a - 1) */ 431218334Speter if (n_ops != 7) 431318334Speter { 431418334Speter ops[n_ops] = constm1_rtx; 431518334Speter negs[n_ops++] = negs[i]; 431618334Speter ops[i] = XEXP (ops[i], 0); 431718334Speter negs[i] = ! negs[i]; 431818334Speter changed = 1; 431918334Speter } 432018334Speter break; 432118334Speter 432218334Speter case CONST_INT: 432318334Speter if (negs[i]) 432418334Speter ops[i] = GEN_INT (- INTVAL (ops[i])), negs[i] = 0, changed = 1; 432518334Speter break; 432618334Speter } 432718334Speter } 432818334Speter 432918334Speter /* If we only have two operands, we can't do anything. */ 433018334Speter if (n_ops <= 2) 433118334Speter return 0; 433218334Speter 433318334Speter /* Now simplify each pair of operands until nothing changes. The first 433418334Speter time through just simplify constants against each other. */ 433518334Speter 433618334Speter changed = 1; 433718334Speter while (changed) 433818334Speter { 433918334Speter changed = first; 434018334Speter 434118334Speter for (i = 0; i < n_ops - 1; i++) 434218334Speter for (j = i + 1; j < n_ops; j++) 434318334Speter if (ops[i] != 0 && ops[j] != 0 434418334Speter && (! first || (CONSTANT_P (ops[i]) && CONSTANT_P (ops[j])))) 434518334Speter { 434618334Speter rtx lhs = ops[i], rhs = ops[j]; 434718334Speter enum rtx_code ncode = PLUS; 434818334Speter 434918334Speter if (negs[i] && ! negs[j]) 435018334Speter lhs = ops[j], rhs = ops[i], ncode = MINUS; 435118334Speter else if (! negs[i] && negs[j]) 435218334Speter ncode = MINUS; 435318334Speter 435418334Speter tem = simplify_binary_operation (ncode, mode, lhs, rhs); 435518334Speter if (tem) 435618334Speter { 435718334Speter ops[i] = tem, ops[j] = 0; 435818334Speter negs[i] = negs[i] && negs[j]; 435918334Speter if (GET_CODE (tem) == NEG) 436018334Speter ops[i] = XEXP (tem, 0), negs[i] = ! negs[i]; 436118334Speter 436218334Speter if (GET_CODE (ops[i]) == CONST_INT && negs[i]) 436318334Speter ops[i] = GEN_INT (- INTVAL (ops[i])), negs[i] = 0; 436418334Speter changed = 1; 436518334Speter } 436618334Speter } 436718334Speter 436818334Speter first = 0; 436918334Speter } 437018334Speter 437118334Speter /* Pack all the operands to the lower-numbered entries and give up if 437218334Speter we didn't reduce the number of operands we had. Make sure we 437318334Speter count a CONST as two operands. If we have the same number of 437418334Speter operands, but have made more CONSTs than we had, this is also 437518334Speter an improvement, so accept it. */ 437618334Speter 437718334Speter for (i = 0, j = 0; j < n_ops; j++) 437818334Speter if (ops[j] != 0) 437918334Speter { 438018334Speter ops[i] = ops[j], negs[i++] = negs[j]; 438118334Speter if (GET_CODE (ops[j]) == CONST) 438218334Speter n_consts++; 438318334Speter } 438418334Speter 438518334Speter if (i + n_consts > input_ops 438618334Speter || (i + n_consts == input_ops && n_consts <= input_consts)) 438718334Speter return 0; 438818334Speter 438918334Speter n_ops = i; 439018334Speter 439118334Speter /* If we have a CONST_INT, put it last. */ 439218334Speter for (i = 0; i < n_ops - 1; i++) 439318334Speter if (GET_CODE (ops[i]) == CONST_INT) 439418334Speter { 439518334Speter tem = ops[n_ops - 1], ops[n_ops - 1] = ops[i] , ops[i] = tem; 439618334Speter j = negs[n_ops - 1], negs[n_ops - 1] = negs[i], negs[i] = j; 439718334Speter } 439818334Speter 439918334Speter /* Put a non-negated operand first. If there aren't any, make all 440018334Speter operands positive and negate the whole thing later. */ 440118334Speter for (i = 0; i < n_ops && negs[i]; i++) 440218334Speter ; 440318334Speter 440418334Speter if (i == n_ops) 440518334Speter { 440618334Speter for (i = 0; i < n_ops; i++) 440718334Speter negs[i] = 0; 440818334Speter negate = 1; 440918334Speter } 441018334Speter else if (i != 0) 441118334Speter { 441218334Speter tem = ops[0], ops[0] = ops[i], ops[i] = tem; 441318334Speter j = negs[0], negs[0] = negs[i], negs[i] = j; 441418334Speter } 441518334Speter 441618334Speter /* Now make the result by performing the requested operations. */ 441718334Speter result = ops[0]; 441818334Speter for (i = 1; i < n_ops; i++) 441918334Speter result = cse_gen_binary (negs[i] ? MINUS : PLUS, mode, result, ops[i]); 442018334Speter 442118334Speter return negate ? gen_rtx (NEG, mode, result) : result; 442218334Speter} 442318334Speter 442418334Speter/* Make a binary operation by properly ordering the operands and 442518334Speter seeing if the expression folds. */ 442618334Speter 442718334Speterstatic rtx 442818334Spetercse_gen_binary (code, mode, op0, op1) 442918334Speter enum rtx_code code; 443018334Speter enum machine_mode mode; 443118334Speter rtx op0, op1; 443218334Speter{ 443318334Speter rtx tem; 443418334Speter 443518334Speter /* Put complex operands first and constants second if commutative. */ 443618334Speter if (GET_RTX_CLASS (code) == 'c' 443718334Speter && ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT) 443818334Speter || (GET_RTX_CLASS (GET_CODE (op0)) == 'o' 443918334Speter && GET_RTX_CLASS (GET_CODE (op1)) != 'o') 444018334Speter || (GET_CODE (op0) == SUBREG 444118334Speter && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o' 444218334Speter && GET_RTX_CLASS (GET_CODE (op1)) != 'o'))) 444318334Speter tem = op0, op0 = op1, op1 = tem; 444418334Speter 444518334Speter /* If this simplifies, do it. */ 444618334Speter tem = simplify_binary_operation (code, mode, op0, op1); 444718334Speter 444818334Speter if (tem) 444918334Speter return tem; 445018334Speter 445118334Speter /* Handle addition and subtraction of CONST_INT specially. Otherwise, 445218334Speter just form the operation. */ 445318334Speter 445418334Speter if (code == PLUS && GET_CODE (op1) == CONST_INT 445518334Speter && GET_MODE (op0) != VOIDmode) 445618334Speter return plus_constant (op0, INTVAL (op1)); 445718334Speter else if (code == MINUS && GET_CODE (op1) == CONST_INT 445818334Speter && GET_MODE (op0) != VOIDmode) 445918334Speter return plus_constant (op0, - INTVAL (op1)); 446018334Speter else 446118334Speter return gen_rtx (code, mode, op0, op1); 446218334Speter} 446318334Speter 446418334Speter/* Like simplify_binary_operation except used for relational operators. 446518334Speter MODE is the mode of the operands, not that of the result. If MODE 446618334Speter is VOIDmode, both operands must also be VOIDmode and we compare the 446718334Speter operands in "infinite precision". 446818334Speter 446918334Speter If no simplification is possible, this function returns zero. Otherwise, 447018334Speter it returns either const_true_rtx or const0_rtx. */ 447118334Speter 447218334Speterrtx 447318334Spetersimplify_relational_operation (code, mode, op0, op1) 447418334Speter enum rtx_code code; 447518334Speter enum machine_mode mode; 447618334Speter rtx op0, op1; 447718334Speter{ 447818334Speter int equal, op0lt, op0ltu, op1lt, op1ltu; 447918334Speter rtx tem; 448018334Speter 448118334Speter /* If op0 is a compare, extract the comparison arguments from it. */ 448218334Speter if (GET_CODE (op0) == COMPARE && op1 == const0_rtx) 448318334Speter op1 = XEXP (op0, 1), op0 = XEXP (op0, 0); 448418334Speter 448518334Speter /* We can't simplify MODE_CC values since we don't know what the 448618334Speter actual comparison is. */ 448718334Speter if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC 448818334Speter#ifdef HAVE_cc0 448918334Speter || op0 == cc0_rtx 449018334Speter#endif 449118334Speter ) 449218334Speter return 0; 449318334Speter 449418334Speter /* For integer comparisons of A and B maybe we can simplify A - B and can 449518334Speter then simplify a comparison of that with zero. If A and B are both either 449618334Speter a register or a CONST_INT, this can't help; testing for these cases will 449718334Speter prevent infinite recursion here and speed things up. 449818334Speter 449918334Speter If CODE is an unsigned comparison, then we can never do this optimization, 450018334Speter because it gives an incorrect result if the subtraction wraps around zero. 450118334Speter ANSI C defines unsigned operations such that they never overflow, and 450218334Speter thus such cases can not be ignored. */ 450318334Speter 450418334Speter if (INTEGRAL_MODE_P (mode) && op1 != const0_rtx 450518334Speter && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == CONST_INT) 450618334Speter && (GET_CODE (op1) == REG || GET_CODE (op1) == CONST_INT)) 450718334Speter && 0 != (tem = simplify_binary_operation (MINUS, mode, op0, op1)) 450818334Speter && code != GTU && code != GEU && code != LTU && code != LEU) 450918334Speter return simplify_relational_operation (signed_condition (code), 451018334Speter mode, tem, const0_rtx); 451118334Speter 451218334Speter /* For non-IEEE floating-point, if the two operands are equal, we know the 451318334Speter result. */ 451418334Speter if (rtx_equal_p (op0, op1) 451518334Speter && (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT 451618334Speter || ! FLOAT_MODE_P (GET_MODE (op0)) || flag_fast_math)) 451718334Speter equal = 1, op0lt = 0, op0ltu = 0, op1lt = 0, op1ltu = 0; 451818334Speter 451918334Speter /* If the operands are floating-point constants, see if we can fold 452018334Speter the result. */ 452118334Speter#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC) 452218334Speter else if (GET_CODE (op0) == CONST_DOUBLE && GET_CODE (op1) == CONST_DOUBLE 452318334Speter && GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT) 452418334Speter { 452518334Speter REAL_VALUE_TYPE d0, d1; 452618334Speter jmp_buf handler; 452718334Speter 452818334Speter if (setjmp (handler)) 452918334Speter return 0; 453018334Speter 453118334Speter set_float_handler (handler); 453218334Speter REAL_VALUE_FROM_CONST_DOUBLE (d0, op0); 453318334Speter REAL_VALUE_FROM_CONST_DOUBLE (d1, op1); 453418334Speter equal = REAL_VALUES_EQUAL (d0, d1); 453518334Speter op0lt = op0ltu = REAL_VALUES_LESS (d0, d1); 453618334Speter op1lt = op1ltu = REAL_VALUES_LESS (d1, d0); 453718334Speter set_float_handler (NULL_PTR); 453818334Speter } 453918334Speter#endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */ 454018334Speter 454118334Speter /* Otherwise, see if the operands are both integers. */ 454218334Speter else if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode) 454318334Speter && (GET_CODE (op0) == CONST_DOUBLE || GET_CODE (op0) == CONST_INT) 454418334Speter && (GET_CODE (op1) == CONST_DOUBLE || GET_CODE (op1) == CONST_INT)) 454518334Speter { 454618334Speter int width = GET_MODE_BITSIZE (mode); 454718334Speter HOST_WIDE_INT l0s, h0s, l1s, h1s; 454818334Speter unsigned HOST_WIDE_INT l0u, h0u, l1u, h1u; 454918334Speter 455018334Speter /* Get the two words comprising each integer constant. */ 455118334Speter if (GET_CODE (op0) == CONST_DOUBLE) 455218334Speter { 455318334Speter l0u = l0s = CONST_DOUBLE_LOW (op0); 455418334Speter h0u = h0s = CONST_DOUBLE_HIGH (op0); 455518334Speter } 455618334Speter else 455718334Speter { 455818334Speter l0u = l0s = INTVAL (op0); 455918334Speter h0u = 0, h0s = l0s < 0 ? -1 : 0; 456018334Speter } 456118334Speter 456218334Speter if (GET_CODE (op1) == CONST_DOUBLE) 456318334Speter { 456418334Speter l1u = l1s = CONST_DOUBLE_LOW (op1); 456518334Speter h1u = h1s = CONST_DOUBLE_HIGH (op1); 456618334Speter } 456718334Speter else 456818334Speter { 456918334Speter l1u = l1s = INTVAL (op1); 457018334Speter h1u = 0, h1s = l1s < 0 ? -1 : 0; 457118334Speter } 457218334Speter 457318334Speter /* If WIDTH is nonzero and smaller than HOST_BITS_PER_WIDE_INT, 457418334Speter we have to sign or zero-extend the values. */ 457518334Speter if (width != 0 && width <= HOST_BITS_PER_WIDE_INT) 457618334Speter h0u = h1u = 0, h0s = l0s < 0 ? -1 : 0, h1s = l1s < 0 ? -1 : 0; 457718334Speter 457818334Speter if (width != 0 && width < HOST_BITS_PER_WIDE_INT) 457918334Speter { 458018334Speter l0u &= ((HOST_WIDE_INT) 1 << width) - 1; 458118334Speter l1u &= ((HOST_WIDE_INT) 1 << width) - 1; 458218334Speter 458318334Speter if (l0s & ((HOST_WIDE_INT) 1 << (width - 1))) 458418334Speter l0s |= ((HOST_WIDE_INT) (-1) << width); 458518334Speter 458618334Speter if (l1s & ((HOST_WIDE_INT) 1 << (width - 1))) 458718334Speter l1s |= ((HOST_WIDE_INT) (-1) << width); 458818334Speter } 458918334Speter 459018334Speter equal = (h0u == h1u && l0u == l1u); 459118334Speter op0lt = (h0s < h1s || (h0s == h1s && l0s < l1s)); 459218334Speter op1lt = (h1s < h0s || (h1s == h0s && l1s < l0s)); 459318334Speter op0ltu = (h0u < h1u || (h0u == h1u && l0u < l1u)); 459418334Speter op1ltu = (h1u < h0u || (h1u == h0u && l1u < l0u)); 459518334Speter } 459618334Speter 459718334Speter /* Otherwise, there are some code-specific tests we can make. */ 459818334Speter else 459918334Speter { 460018334Speter switch (code) 460118334Speter { 460218334Speter case EQ: 460318334Speter /* References to the frame plus a constant or labels cannot 460418334Speter be zero, but a SYMBOL_REF can due to #pragma weak. */ 460518334Speter if (((NONZERO_BASE_PLUS_P (op0) && op1 == const0_rtx) 460618334Speter || GET_CODE (op0) == LABEL_REF) 460718334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM 460818334Speter /* On some machines, the ap reg can be 0 sometimes. */ 460918334Speter && op0 != arg_pointer_rtx 461018334Speter#endif 461118334Speter ) 461218334Speter return const0_rtx; 461318334Speter break; 461418334Speter 461518334Speter case NE: 461618334Speter if (((NONZERO_BASE_PLUS_P (op0) && op1 == const0_rtx) 461718334Speter || GET_CODE (op0) == LABEL_REF) 461818334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM 461918334Speter && op0 != arg_pointer_rtx 462018334Speter#endif 462118334Speter ) 462218334Speter return const_true_rtx; 462318334Speter break; 462418334Speter 462518334Speter case GEU: 462618334Speter /* Unsigned values are never negative. */ 462718334Speter if (op1 == const0_rtx) 462818334Speter return const_true_rtx; 462918334Speter break; 463018334Speter 463118334Speter case LTU: 463218334Speter if (op1 == const0_rtx) 463318334Speter return const0_rtx; 463418334Speter break; 463518334Speter 463618334Speter case LEU: 463718334Speter /* Unsigned values are never greater than the largest 463818334Speter unsigned value. */ 463918334Speter if (GET_CODE (op1) == CONST_INT 464018334Speter && INTVAL (op1) == GET_MODE_MASK (mode) 464118334Speter && INTEGRAL_MODE_P (mode)) 464218334Speter return const_true_rtx; 464318334Speter break; 464418334Speter 464518334Speter case GTU: 464618334Speter if (GET_CODE (op1) == CONST_INT 464718334Speter && INTVAL (op1) == GET_MODE_MASK (mode) 464818334Speter && INTEGRAL_MODE_P (mode)) 464918334Speter return const0_rtx; 465018334Speter break; 465118334Speter } 465218334Speter 465318334Speter return 0; 465418334Speter } 465518334Speter 465618334Speter /* If we reach here, EQUAL, OP0LT, OP0LTU, OP1LT, and OP1LTU are set 465718334Speter as appropriate. */ 465818334Speter switch (code) 465918334Speter { 466018334Speter case EQ: 466118334Speter return equal ? const_true_rtx : const0_rtx; 466218334Speter case NE: 466318334Speter return ! equal ? const_true_rtx : const0_rtx; 466418334Speter case LT: 466518334Speter return op0lt ? const_true_rtx : const0_rtx; 466618334Speter case GT: 466718334Speter return op1lt ? const_true_rtx : const0_rtx; 466818334Speter case LTU: 466918334Speter return op0ltu ? const_true_rtx : const0_rtx; 467018334Speter case GTU: 467118334Speter return op1ltu ? const_true_rtx : const0_rtx; 467218334Speter case LE: 467318334Speter return equal || op0lt ? const_true_rtx : const0_rtx; 467418334Speter case GE: 467518334Speter return equal || op1lt ? const_true_rtx : const0_rtx; 467618334Speter case LEU: 467718334Speter return equal || op0ltu ? const_true_rtx : const0_rtx; 467818334Speter case GEU: 467918334Speter return equal || op1ltu ? const_true_rtx : const0_rtx; 468018334Speter } 468118334Speter 468218334Speter abort (); 468318334Speter} 468418334Speter 468518334Speter/* Simplify CODE, an operation with result mode MODE and three operands, 468618334Speter OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became 468718334Speter a constant. Return 0 if no simplifications is possible. */ 468818334Speter 468918334Speterrtx 469018334Spetersimplify_ternary_operation (code, mode, op0_mode, op0, op1, op2) 469118334Speter enum rtx_code code; 469218334Speter enum machine_mode mode, op0_mode; 469318334Speter rtx op0, op1, op2; 469418334Speter{ 469518334Speter int width = GET_MODE_BITSIZE (mode); 469618334Speter 469718334Speter /* VOIDmode means "infinite" precision. */ 469818334Speter if (width == 0) 469918334Speter width = HOST_BITS_PER_WIDE_INT; 470018334Speter 470118334Speter switch (code) 470218334Speter { 470318334Speter case SIGN_EXTRACT: 470418334Speter case ZERO_EXTRACT: 470518334Speter if (GET_CODE (op0) == CONST_INT 470618334Speter && GET_CODE (op1) == CONST_INT 470718334Speter && GET_CODE (op2) == CONST_INT 470818334Speter && INTVAL (op1) + INTVAL (op2) <= GET_MODE_BITSIZE (op0_mode) 470918334Speter && width <= HOST_BITS_PER_WIDE_INT) 471018334Speter { 471118334Speter /* Extracting a bit-field from a constant */ 471218334Speter HOST_WIDE_INT val = INTVAL (op0); 471318334Speter 471418334Speter if (BITS_BIG_ENDIAN) 471518334Speter val >>= (GET_MODE_BITSIZE (op0_mode) 471618334Speter - INTVAL (op2) - INTVAL (op1)); 471718334Speter else 471818334Speter val >>= INTVAL (op2); 471918334Speter 472018334Speter if (HOST_BITS_PER_WIDE_INT != INTVAL (op1)) 472118334Speter { 472218334Speter /* First zero-extend. */ 472318334Speter val &= ((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1; 472418334Speter /* If desired, propagate sign bit. */ 472518334Speter if (code == SIGN_EXTRACT 472618334Speter && (val & ((HOST_WIDE_INT) 1 << (INTVAL (op1) - 1)))) 472718334Speter val |= ~ (((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1); 472818334Speter } 472918334Speter 473018334Speter /* Clear the bits that don't belong in our mode, 473118334Speter unless they and our sign bit are all one. 473218334Speter So we get either a reasonable negative value or a reasonable 473318334Speter unsigned value for this mode. */ 473418334Speter if (width < HOST_BITS_PER_WIDE_INT 473518334Speter && ((val & ((HOST_WIDE_INT) (-1) << (width - 1))) 473618334Speter != ((HOST_WIDE_INT) (-1) << (width - 1)))) 473718334Speter val &= ((HOST_WIDE_INT) 1 << width) - 1; 473818334Speter 473918334Speter return GEN_INT (val); 474018334Speter } 474118334Speter break; 474218334Speter 474318334Speter case IF_THEN_ELSE: 474418334Speter if (GET_CODE (op0) == CONST_INT) 474518334Speter return op0 != const0_rtx ? op1 : op2; 474618334Speter break; 474718334Speter 474818334Speter default: 474918334Speter abort (); 475018334Speter } 475118334Speter 475218334Speter return 0; 475318334Speter} 475418334Speter 475518334Speter/* If X is a nontrivial arithmetic operation on an argument 475618334Speter for which a constant value can be determined, return 475718334Speter the result of operating on that value, as a constant. 475818334Speter Otherwise, return X, possibly with one or more operands 475918334Speter modified by recursive calls to this function. 476018334Speter 476118334Speter If X is a register whose contents are known, we do NOT 476218334Speter return those contents here. equiv_constant is called to 476318334Speter perform that task. 476418334Speter 476518334Speter INSN is the insn that we may be modifying. If it is 0, make a copy 476618334Speter of X before modifying it. */ 476718334Speter 476818334Speterstatic rtx 476918334Speterfold_rtx (x, insn) 477018334Speter rtx x; 477118334Speter rtx insn; 477218334Speter{ 477318334Speter register enum rtx_code code; 477418334Speter register enum machine_mode mode; 477518334Speter register char *fmt; 477618334Speter register int i; 477718334Speter rtx new = 0; 477818334Speter int copied = 0; 477918334Speter int must_swap = 0; 478018334Speter 478118334Speter /* Folded equivalents of first two operands of X. */ 478218334Speter rtx folded_arg0; 478318334Speter rtx folded_arg1; 478418334Speter 478518334Speter /* Constant equivalents of first three operands of X; 478618334Speter 0 when no such equivalent is known. */ 478718334Speter rtx const_arg0; 478818334Speter rtx const_arg1; 478918334Speter rtx const_arg2; 479018334Speter 479118334Speter /* The mode of the first operand of X. We need this for sign and zero 479218334Speter extends. */ 479318334Speter enum machine_mode mode_arg0; 479418334Speter 479518334Speter if (x == 0) 479618334Speter return x; 479718334Speter 479818334Speter mode = GET_MODE (x); 479918334Speter code = GET_CODE (x); 480018334Speter switch (code) 480118334Speter { 480218334Speter case CONST: 480318334Speter case CONST_INT: 480418334Speter case CONST_DOUBLE: 480518334Speter case SYMBOL_REF: 480618334Speter case LABEL_REF: 480718334Speter case REG: 480818334Speter /* No use simplifying an EXPR_LIST 480918334Speter since they are used only for lists of args 481018334Speter in a function call's REG_EQUAL note. */ 481118334Speter case EXPR_LIST: 481218334Speter return x; 481318334Speter 481418334Speter#ifdef HAVE_cc0 481518334Speter case CC0: 481618334Speter return prev_insn_cc0; 481718334Speter#endif 481818334Speter 481918334Speter case PC: 482018334Speter /* If the next insn is a CODE_LABEL followed by a jump table, 482118334Speter PC's value is a LABEL_REF pointing to that label. That 482218334Speter lets us fold switch statements on the Vax. */ 482318334Speter if (insn && GET_CODE (insn) == JUMP_INSN) 482418334Speter { 482518334Speter rtx next = next_nonnote_insn (insn); 482618334Speter 482718334Speter if (next && GET_CODE (next) == CODE_LABEL 482818334Speter && NEXT_INSN (next) != 0 482918334Speter && GET_CODE (NEXT_INSN (next)) == JUMP_INSN 483018334Speter && (GET_CODE (PATTERN (NEXT_INSN (next))) == ADDR_VEC 483118334Speter || GET_CODE (PATTERN (NEXT_INSN (next))) == ADDR_DIFF_VEC)) 483218334Speter return gen_rtx (LABEL_REF, Pmode, next); 483318334Speter } 483418334Speter break; 483518334Speter 483618334Speter case SUBREG: 483718334Speter /* See if we previously assigned a constant value to this SUBREG. */ 483818334Speter if ((new = lookup_as_function (x, CONST_INT)) != 0 483918334Speter || (new = lookup_as_function (x, CONST_DOUBLE)) != 0) 484018334Speter return new; 484118334Speter 484218334Speter /* If this is a paradoxical SUBREG, we have no idea what value the 484318334Speter extra bits would have. However, if the operand is equivalent 484418334Speter to a SUBREG whose operand is the same as our mode, and all the 484518334Speter modes are within a word, we can just use the inner operand 484618334Speter because these SUBREGs just say how to treat the register. 484718334Speter 484818334Speter Similarly if we find an integer constant. */ 484918334Speter 485018334Speter if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 485118334Speter { 485218334Speter enum machine_mode imode = GET_MODE (SUBREG_REG (x)); 485318334Speter struct table_elt *elt; 485418334Speter 485518334Speter if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD 485618334Speter && GET_MODE_SIZE (imode) <= UNITS_PER_WORD 485718334Speter && (elt = lookup (SUBREG_REG (x), HASH (SUBREG_REG (x), imode), 485818334Speter imode)) != 0) 485918334Speter for (elt = elt->first_same_value; 486018334Speter elt; elt = elt->next_same_value) 486118334Speter { 486218334Speter if (CONSTANT_P (elt->exp) 486318334Speter && GET_MODE (elt->exp) == VOIDmode) 486418334Speter return elt->exp; 486518334Speter 486618334Speter if (GET_CODE (elt->exp) == SUBREG 486718334Speter && GET_MODE (SUBREG_REG (elt->exp)) == mode 486818334Speter && exp_equiv_p (elt->exp, elt->exp, 1, 0)) 486918334Speter return copy_rtx (SUBREG_REG (elt->exp)); 487018334Speter } 487118334Speter 487218334Speter return x; 487318334Speter } 487418334Speter 487518334Speter /* Fold SUBREG_REG. If it changed, see if we can simplify the SUBREG. 487618334Speter We might be able to if the SUBREG is extracting a single word in an 487718334Speter integral mode or extracting the low part. */ 487818334Speter 487918334Speter folded_arg0 = fold_rtx (SUBREG_REG (x), insn); 488018334Speter const_arg0 = equiv_constant (folded_arg0); 488118334Speter if (const_arg0) 488218334Speter folded_arg0 = const_arg0; 488318334Speter 488418334Speter if (folded_arg0 != SUBREG_REG (x)) 488518334Speter { 488618334Speter new = 0; 488718334Speter 488818334Speter if (GET_MODE_CLASS (mode) == MODE_INT 488918334Speter && GET_MODE_SIZE (mode) == UNITS_PER_WORD 489018334Speter && GET_MODE (SUBREG_REG (x)) != VOIDmode) 489118334Speter new = operand_subword (folded_arg0, SUBREG_WORD (x), 0, 489218334Speter GET_MODE (SUBREG_REG (x))); 489318334Speter if (new == 0 && subreg_lowpart_p (x)) 489418334Speter new = gen_lowpart_if_possible (mode, folded_arg0); 489518334Speter if (new) 489618334Speter return new; 489718334Speter } 489818334Speter 489918334Speter /* If this is a narrowing SUBREG and our operand is a REG, see if 490018334Speter we can find an equivalence for REG that is an arithmetic operation 490118334Speter in a wider mode where both operands are paradoxical SUBREGs 490218334Speter from objects of our result mode. In that case, we couldn't report 490318334Speter an equivalent value for that operation, since we don't know what the 490418334Speter extra bits will be. But we can find an equivalence for this SUBREG 490518334Speter by folding that operation is the narrow mode. This allows us to 490618334Speter fold arithmetic in narrow modes when the machine only supports 490718334Speter word-sized arithmetic. 490818334Speter 490918334Speter Also look for a case where we have a SUBREG whose operand is the 491018334Speter same as our result. If both modes are smaller than a word, we 491118334Speter are simply interpreting a register in different modes and we 491218334Speter can use the inner value. */ 491318334Speter 491418334Speter if (GET_CODE (folded_arg0) == REG 491518334Speter && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (folded_arg0)) 491618334Speter && subreg_lowpart_p (x)) 491718334Speter { 491818334Speter struct table_elt *elt; 491918334Speter 492018334Speter /* We can use HASH here since we know that canon_hash won't be 492118334Speter called. */ 492218334Speter elt = lookup (folded_arg0, 492318334Speter HASH (folded_arg0, GET_MODE (folded_arg0)), 492418334Speter GET_MODE (folded_arg0)); 492518334Speter 492618334Speter if (elt) 492718334Speter elt = elt->first_same_value; 492818334Speter 492918334Speter for (; elt; elt = elt->next_same_value) 493018334Speter { 493118334Speter enum rtx_code eltcode = GET_CODE (elt->exp); 493218334Speter 493318334Speter /* Just check for unary and binary operations. */ 493418334Speter if (GET_RTX_CLASS (GET_CODE (elt->exp)) == '1' 493518334Speter && GET_CODE (elt->exp) != SIGN_EXTEND 493618334Speter && GET_CODE (elt->exp) != ZERO_EXTEND 493718334Speter && GET_CODE (XEXP (elt->exp, 0)) == SUBREG 493818334Speter && GET_MODE (SUBREG_REG (XEXP (elt->exp, 0))) == mode) 493918334Speter { 494018334Speter rtx op0 = SUBREG_REG (XEXP (elt->exp, 0)); 494118334Speter 494218334Speter if (GET_CODE (op0) != REG && ! CONSTANT_P (op0)) 494318334Speter op0 = fold_rtx (op0, NULL_RTX); 494418334Speter 494518334Speter op0 = equiv_constant (op0); 494618334Speter if (op0) 494718334Speter new = simplify_unary_operation (GET_CODE (elt->exp), mode, 494818334Speter op0, mode); 494918334Speter } 495018334Speter else if ((GET_RTX_CLASS (GET_CODE (elt->exp)) == '2' 495118334Speter || GET_RTX_CLASS (GET_CODE (elt->exp)) == 'c') 495218334Speter && eltcode != DIV && eltcode != MOD 495318334Speter && eltcode != UDIV && eltcode != UMOD 495418334Speter && eltcode != ASHIFTRT && eltcode != LSHIFTRT 495518334Speter && eltcode != ROTATE && eltcode != ROTATERT 495618334Speter && ((GET_CODE (XEXP (elt->exp, 0)) == SUBREG 495718334Speter && (GET_MODE (SUBREG_REG (XEXP (elt->exp, 0))) 495818334Speter == mode)) 495918334Speter || CONSTANT_P (XEXP (elt->exp, 0))) 496018334Speter && ((GET_CODE (XEXP (elt->exp, 1)) == SUBREG 496118334Speter && (GET_MODE (SUBREG_REG (XEXP (elt->exp, 1))) 496218334Speter == mode)) 496318334Speter || CONSTANT_P (XEXP (elt->exp, 1)))) 496418334Speter { 496518334Speter rtx op0 = gen_lowpart_common (mode, XEXP (elt->exp, 0)); 496618334Speter rtx op1 = gen_lowpart_common (mode, XEXP (elt->exp, 1)); 496718334Speter 496818334Speter if (op0 && GET_CODE (op0) != REG && ! CONSTANT_P (op0)) 496918334Speter op0 = fold_rtx (op0, NULL_RTX); 497018334Speter 497118334Speter if (op0) 497218334Speter op0 = equiv_constant (op0); 497318334Speter 497418334Speter if (op1 && GET_CODE (op1) != REG && ! CONSTANT_P (op1)) 497518334Speter op1 = fold_rtx (op1, NULL_RTX); 497618334Speter 497718334Speter if (op1) 497818334Speter op1 = equiv_constant (op1); 497918334Speter 498018334Speter /* If we are looking for the low SImode part of 498118334Speter (ashift:DI c (const_int 32)), it doesn't work 498218334Speter to compute that in SImode, because a 32-bit shift 498318334Speter in SImode is unpredictable. We know the value is 0. */ 498418334Speter if (op0 && op1 498518334Speter && GET_CODE (elt->exp) == ASHIFT 498618334Speter && GET_CODE (op1) == CONST_INT 498718334Speter && INTVAL (op1) >= GET_MODE_BITSIZE (mode)) 498818334Speter { 498918334Speter if (INTVAL (op1) < GET_MODE_BITSIZE (GET_MODE (elt->exp))) 499018334Speter 499118334Speter /* If the count fits in the inner mode's width, 499218334Speter but exceeds the outer mode's width, 499318334Speter the value will get truncated to 0 499418334Speter by the subreg. */ 499518334Speter new = const0_rtx; 499618334Speter else 499718334Speter /* If the count exceeds even the inner mode's width, 499818334Speter don't fold this expression. */ 499918334Speter new = 0; 500018334Speter } 500118334Speter else if (op0 && op1) 500218334Speter new = simplify_binary_operation (GET_CODE (elt->exp), mode, 500318334Speter op0, op1); 500418334Speter } 500518334Speter 500618334Speter else if (GET_CODE (elt->exp) == SUBREG 500718334Speter && GET_MODE (SUBREG_REG (elt->exp)) == mode 500818334Speter && (GET_MODE_SIZE (GET_MODE (folded_arg0)) 500918334Speter <= UNITS_PER_WORD) 501018334Speter && exp_equiv_p (elt->exp, elt->exp, 1, 0)) 501118334Speter new = copy_rtx (SUBREG_REG (elt->exp)); 501218334Speter 501318334Speter if (new) 501418334Speter return new; 501518334Speter } 501618334Speter } 501718334Speter 501818334Speter return x; 501918334Speter 502018334Speter case NOT: 502118334Speter case NEG: 502218334Speter /* If we have (NOT Y), see if Y is known to be (NOT Z). 502318334Speter If so, (NOT Y) simplifies to Z. Similarly for NEG. */ 502418334Speter new = lookup_as_function (XEXP (x, 0), code); 502518334Speter if (new) 502618334Speter return fold_rtx (copy_rtx (XEXP (new, 0)), insn); 502718334Speter break; 502818334Speter 502918334Speter case MEM: 503018334Speter /* If we are not actually processing an insn, don't try to find the 503118334Speter best address. Not only don't we care, but we could modify the 503218334Speter MEM in an invalid way since we have no insn to validate against. */ 503318334Speter if (insn != 0) 503418334Speter find_best_addr (insn, &XEXP (x, 0)); 503518334Speter 503618334Speter { 503718334Speter /* Even if we don't fold in the insn itself, 503818334Speter we can safely do so here, in hopes of getting a constant. */ 503918334Speter rtx addr = fold_rtx (XEXP (x, 0), NULL_RTX); 504018334Speter rtx base = 0; 504118334Speter HOST_WIDE_INT offset = 0; 504218334Speter 504318334Speter if (GET_CODE (addr) == REG 504418334Speter && REGNO_QTY_VALID_P (REGNO (addr)) 504518334Speter && GET_MODE (addr) == qty_mode[reg_qty[REGNO (addr)]] 504618334Speter && qty_const[reg_qty[REGNO (addr)]] != 0) 504718334Speter addr = qty_const[reg_qty[REGNO (addr)]]; 504818334Speter 504918334Speter /* If address is constant, split it into a base and integer offset. */ 505018334Speter if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF) 505118334Speter base = addr; 505218334Speter else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS 505318334Speter && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT) 505418334Speter { 505518334Speter base = XEXP (XEXP (addr, 0), 0); 505618334Speter offset = INTVAL (XEXP (XEXP (addr, 0), 1)); 505718334Speter } 505818334Speter else if (GET_CODE (addr) == LO_SUM 505918334Speter && GET_CODE (XEXP (addr, 1)) == SYMBOL_REF) 506018334Speter base = XEXP (addr, 1); 506118334Speter 506218334Speter /* If this is a constant pool reference, we can fold it into its 506318334Speter constant to allow better value tracking. */ 506418334Speter if (base && GET_CODE (base) == SYMBOL_REF 506518334Speter && CONSTANT_POOL_ADDRESS_P (base)) 506618334Speter { 506718334Speter rtx constant = get_pool_constant (base); 506818334Speter enum machine_mode const_mode = get_pool_mode (base); 506918334Speter rtx new; 507018334Speter 507118334Speter if (CONSTANT_P (constant) && GET_CODE (constant) != CONST_INT) 507218334Speter constant_pool_entries_cost = COST (constant); 507318334Speter 507418334Speter /* If we are loading the full constant, we have an equivalence. */ 507518334Speter if (offset == 0 && mode == const_mode) 507618334Speter return constant; 507718334Speter 507818334Speter /* If this actually isn't a constant (weird!), we can't do 507918334Speter anything. Otherwise, handle the two most common cases: 508018334Speter extracting a word from a multi-word constant, and extracting 508118334Speter the low-order bits. Other cases don't seem common enough to 508218334Speter worry about. */ 508318334Speter if (! CONSTANT_P (constant)) 508418334Speter return x; 508518334Speter 508618334Speter if (GET_MODE_CLASS (mode) == MODE_INT 508718334Speter && GET_MODE_SIZE (mode) == UNITS_PER_WORD 508818334Speter && offset % UNITS_PER_WORD == 0 508918334Speter && (new = operand_subword (constant, 509018334Speter offset / UNITS_PER_WORD, 509118334Speter 0, const_mode)) != 0) 509218334Speter return new; 509318334Speter 509418334Speter if (((BYTES_BIG_ENDIAN 509518334Speter && offset == GET_MODE_SIZE (GET_MODE (constant)) - 1) 509618334Speter || (! BYTES_BIG_ENDIAN && offset == 0)) 509718334Speter && (new = gen_lowpart_if_possible (mode, constant)) != 0) 509818334Speter return new; 509918334Speter } 510018334Speter 510118334Speter /* If this is a reference to a label at a known position in a jump 510218334Speter table, we also know its value. */ 510318334Speter if (base && GET_CODE (base) == LABEL_REF) 510418334Speter { 510518334Speter rtx label = XEXP (base, 0); 510618334Speter rtx table_insn = NEXT_INSN (label); 510718334Speter 510818334Speter if (table_insn && GET_CODE (table_insn) == JUMP_INSN 510918334Speter && GET_CODE (PATTERN (table_insn)) == ADDR_VEC) 511018334Speter { 511118334Speter rtx table = PATTERN (table_insn); 511218334Speter 511318334Speter if (offset >= 0 511418334Speter && (offset / GET_MODE_SIZE (GET_MODE (table)) 511518334Speter < XVECLEN (table, 0))) 511618334Speter return XVECEXP (table, 0, 511718334Speter offset / GET_MODE_SIZE (GET_MODE (table))); 511818334Speter } 511918334Speter if (table_insn && GET_CODE (table_insn) == JUMP_INSN 512018334Speter && GET_CODE (PATTERN (table_insn)) == ADDR_DIFF_VEC) 512118334Speter { 512218334Speter rtx table = PATTERN (table_insn); 512318334Speter 512418334Speter if (offset >= 0 512518334Speter && (offset / GET_MODE_SIZE (GET_MODE (table)) 512618334Speter < XVECLEN (table, 1))) 512718334Speter { 512818334Speter offset /= GET_MODE_SIZE (GET_MODE (table)); 512918334Speter new = gen_rtx (MINUS, Pmode, XVECEXP (table, 1, offset), 513018334Speter XEXP (table, 0)); 513118334Speter 513218334Speter if (GET_MODE (table) != Pmode) 513318334Speter new = gen_rtx (TRUNCATE, GET_MODE (table), new); 513418334Speter 513518334Speter /* Indicate this is a constant. This isn't a 513618334Speter valid form of CONST, but it will only be used 513718334Speter to fold the next insns and then discarded, so 513818334Speter it should be safe. */ 513918334Speter return gen_rtx (CONST, GET_MODE (new), new); 514018334Speter } 514118334Speter } 514218334Speter } 514318334Speter 514418334Speter return x; 514518334Speter } 514618334Speter } 514718334Speter 514818334Speter const_arg0 = 0; 514918334Speter const_arg1 = 0; 515018334Speter const_arg2 = 0; 515118334Speter mode_arg0 = VOIDmode; 515218334Speter 515318334Speter /* Try folding our operands. 515418334Speter Then see which ones have constant values known. */ 515518334Speter 515618334Speter fmt = GET_RTX_FORMAT (code); 515718334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 515818334Speter if (fmt[i] == 'e') 515918334Speter { 516018334Speter rtx arg = XEXP (x, i); 516118334Speter rtx folded_arg = arg, const_arg = 0; 516218334Speter enum machine_mode mode_arg = GET_MODE (arg); 516318334Speter rtx cheap_arg, expensive_arg; 516418334Speter rtx replacements[2]; 516518334Speter int j; 516618334Speter 516718334Speter /* Most arguments are cheap, so handle them specially. */ 516818334Speter switch (GET_CODE (arg)) 516918334Speter { 517018334Speter case REG: 517118334Speter /* This is the same as calling equiv_constant; it is duplicated 517218334Speter here for speed. */ 517318334Speter if (REGNO_QTY_VALID_P (REGNO (arg)) 517418334Speter && qty_const[reg_qty[REGNO (arg)]] != 0 517518334Speter && GET_CODE (qty_const[reg_qty[REGNO (arg)]]) != REG 517618334Speter && GET_CODE (qty_const[reg_qty[REGNO (arg)]]) != PLUS) 517718334Speter const_arg 517818334Speter = gen_lowpart_if_possible (GET_MODE (arg), 517918334Speter qty_const[reg_qty[REGNO (arg)]]); 518018334Speter break; 518118334Speter 518218334Speter case CONST: 518318334Speter case CONST_INT: 518418334Speter case SYMBOL_REF: 518518334Speter case LABEL_REF: 518618334Speter case CONST_DOUBLE: 518718334Speter const_arg = arg; 518818334Speter break; 518918334Speter 519018334Speter#ifdef HAVE_cc0 519118334Speter case CC0: 519218334Speter folded_arg = prev_insn_cc0; 519318334Speter mode_arg = prev_insn_cc0_mode; 519418334Speter const_arg = equiv_constant (folded_arg); 519518334Speter break; 519618334Speter#endif 519718334Speter 519818334Speter default: 519918334Speter folded_arg = fold_rtx (arg, insn); 520018334Speter const_arg = equiv_constant (folded_arg); 520118334Speter } 520218334Speter 520318334Speter /* For the first three operands, see if the operand 520418334Speter is constant or equivalent to a constant. */ 520518334Speter switch (i) 520618334Speter { 520718334Speter case 0: 520818334Speter folded_arg0 = folded_arg; 520918334Speter const_arg0 = const_arg; 521018334Speter mode_arg0 = mode_arg; 521118334Speter break; 521218334Speter case 1: 521318334Speter folded_arg1 = folded_arg; 521418334Speter const_arg1 = const_arg; 521518334Speter break; 521618334Speter case 2: 521718334Speter const_arg2 = const_arg; 521818334Speter break; 521918334Speter } 522018334Speter 522118334Speter /* Pick the least expensive of the folded argument and an 522218334Speter equivalent constant argument. */ 522318334Speter if (const_arg == 0 || const_arg == folded_arg 522418334Speter || COST (const_arg) > COST (folded_arg)) 522518334Speter cheap_arg = folded_arg, expensive_arg = const_arg; 522618334Speter else 522718334Speter cheap_arg = const_arg, expensive_arg = folded_arg; 522818334Speter 522918334Speter /* Try to replace the operand with the cheapest of the two 523018334Speter possibilities. If it doesn't work and this is either of the first 523118334Speter two operands of a commutative operation, try swapping them. 523218334Speter If THAT fails, try the more expensive, provided it is cheaper 523318334Speter than what is already there. */ 523418334Speter 523518334Speter if (cheap_arg == XEXP (x, i)) 523618334Speter continue; 523718334Speter 523818334Speter if (insn == 0 && ! copied) 523918334Speter { 524018334Speter x = copy_rtx (x); 524118334Speter copied = 1; 524218334Speter } 524318334Speter 524418334Speter replacements[0] = cheap_arg, replacements[1] = expensive_arg; 524518334Speter for (j = 0; 524618334Speter j < 2 && replacements[j] 524718334Speter && COST (replacements[j]) < COST (XEXP (x, i)); 524818334Speter j++) 524918334Speter { 525018334Speter if (validate_change (insn, &XEXP (x, i), replacements[j], 0)) 525118334Speter break; 525218334Speter 525318334Speter if (code == NE || code == EQ || GET_RTX_CLASS (code) == 'c') 525418334Speter { 525518334Speter validate_change (insn, &XEXP (x, i), XEXP (x, 1 - i), 1); 525618334Speter validate_change (insn, &XEXP (x, 1 - i), replacements[j], 1); 525718334Speter 525818334Speter if (apply_change_group ()) 525918334Speter { 526018334Speter /* Swap them back to be invalid so that this loop can 526118334Speter continue and flag them to be swapped back later. */ 526218334Speter rtx tem; 526318334Speter 526418334Speter tem = XEXP (x, 0); XEXP (x, 0) = XEXP (x, 1); 526518334Speter XEXP (x, 1) = tem; 526618334Speter must_swap = 1; 526718334Speter break; 526818334Speter } 526918334Speter } 527018334Speter } 527118334Speter } 527218334Speter 527318334Speter else if (fmt[i] == 'E') 527418334Speter /* Don't try to fold inside of a vector of expressions. 527518334Speter Doing nothing is harmless. */ 527618334Speter ; 527718334Speter 527818334Speter /* If a commutative operation, place a constant integer as the second 527918334Speter operand unless the first operand is also a constant integer. Otherwise, 528018334Speter place any constant second unless the first operand is also a constant. */ 528118334Speter 528218334Speter if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c') 528318334Speter { 528418334Speter if (must_swap || (const_arg0 528518334Speter && (const_arg1 == 0 528618334Speter || (GET_CODE (const_arg0) == CONST_INT 528718334Speter && GET_CODE (const_arg1) != CONST_INT)))) 528818334Speter { 528918334Speter register rtx tem = XEXP (x, 0); 529018334Speter 529118334Speter if (insn == 0 && ! copied) 529218334Speter { 529318334Speter x = copy_rtx (x); 529418334Speter copied = 1; 529518334Speter } 529618334Speter 529718334Speter validate_change (insn, &XEXP (x, 0), XEXP (x, 1), 1); 529818334Speter validate_change (insn, &XEXP (x, 1), tem, 1); 529918334Speter if (apply_change_group ()) 530018334Speter { 530118334Speter tem = const_arg0, const_arg0 = const_arg1, const_arg1 = tem; 530218334Speter tem = folded_arg0, folded_arg0 = folded_arg1, folded_arg1 = tem; 530318334Speter } 530418334Speter } 530518334Speter } 530618334Speter 530718334Speter /* If X is an arithmetic operation, see if we can simplify it. */ 530818334Speter 530918334Speter switch (GET_RTX_CLASS (code)) 531018334Speter { 531118334Speter case '1': 531218334Speter { 531318334Speter int is_const = 0; 531418334Speter 531518334Speter /* We can't simplify extension ops unless we know the 531618334Speter original mode. */ 531718334Speter if ((code == ZERO_EXTEND || code == SIGN_EXTEND) 531818334Speter && mode_arg0 == VOIDmode) 531918334Speter break; 532018334Speter 532118334Speter /* If we had a CONST, strip it off and put it back later if we 532218334Speter fold. */ 532318334Speter if (const_arg0 != 0 && GET_CODE (const_arg0) == CONST) 532418334Speter is_const = 1, const_arg0 = XEXP (const_arg0, 0); 532518334Speter 532618334Speter new = simplify_unary_operation (code, mode, 532718334Speter const_arg0 ? const_arg0 : folded_arg0, 532818334Speter mode_arg0); 532918334Speter if (new != 0 && is_const) 533018334Speter new = gen_rtx (CONST, mode, new); 533118334Speter } 533218334Speter break; 533318334Speter 533418334Speter case '<': 533518334Speter /* See what items are actually being compared and set FOLDED_ARG[01] 533618334Speter to those values and CODE to the actual comparison code. If any are 533718334Speter constant, set CONST_ARG0 and CONST_ARG1 appropriately. We needn't 533818334Speter do anything if both operands are already known to be constant. */ 533918334Speter 534018334Speter if (const_arg0 == 0 || const_arg1 == 0) 534118334Speter { 534218334Speter struct table_elt *p0, *p1; 534318334Speter rtx true = const_true_rtx, false = const0_rtx; 534418334Speter enum machine_mode mode_arg1; 534518334Speter 534618334Speter#ifdef FLOAT_STORE_FLAG_VALUE 534718334Speter if (GET_MODE_CLASS (mode) == MODE_FLOAT) 534818334Speter { 534918334Speter true = CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE, 535018334Speter mode); 535118334Speter false = CONST0_RTX (mode); 535218334Speter } 535318334Speter#endif 535418334Speter 535518334Speter code = find_comparison_args (code, &folded_arg0, &folded_arg1, 535618334Speter &mode_arg0, &mode_arg1); 535718334Speter const_arg0 = equiv_constant (folded_arg0); 535818334Speter const_arg1 = equiv_constant (folded_arg1); 535918334Speter 536018334Speter /* If the mode is VOIDmode or a MODE_CC mode, we don't know 536118334Speter what kinds of things are being compared, so we can't do 536218334Speter anything with this comparison. */ 536318334Speter 536418334Speter if (mode_arg0 == VOIDmode || GET_MODE_CLASS (mode_arg0) == MODE_CC) 536518334Speter break; 536618334Speter 536718334Speter /* If we do not now have two constants being compared, see if we 536818334Speter can nevertheless deduce some things about the comparison. */ 536918334Speter if (const_arg0 == 0 || const_arg1 == 0) 537018334Speter { 537118334Speter /* Is FOLDED_ARG0 frame-pointer plus a constant? Or non-explicit 537218334Speter constant? These aren't zero, but we don't know their sign. */ 537318334Speter if (const_arg1 == const0_rtx 537418334Speter && (NONZERO_BASE_PLUS_P (folded_arg0) 537518334Speter#if 0 /* Sad to say, on sysvr4, #pragma weak can make a symbol address 537618334Speter come out as 0. */ 537718334Speter || GET_CODE (folded_arg0) == SYMBOL_REF 537818334Speter#endif 537918334Speter || GET_CODE (folded_arg0) == LABEL_REF 538018334Speter || GET_CODE (folded_arg0) == CONST)) 538118334Speter { 538218334Speter if (code == EQ) 538318334Speter return false; 538418334Speter else if (code == NE) 538518334Speter return true; 538618334Speter } 538718334Speter 538818334Speter /* See if the two operands are the same. We don't do this 538918334Speter for IEEE floating-point since we can't assume x == x 539018334Speter since x might be a NaN. */ 539118334Speter 539218334Speter if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT 539318334Speter || ! FLOAT_MODE_P (mode_arg0) || flag_fast_math) 539418334Speter && (folded_arg0 == folded_arg1 539518334Speter || (GET_CODE (folded_arg0) == REG 539618334Speter && GET_CODE (folded_arg1) == REG 539718334Speter && (reg_qty[REGNO (folded_arg0)] 539818334Speter == reg_qty[REGNO (folded_arg1)])) 539918334Speter || ((p0 = lookup (folded_arg0, 540018334Speter (safe_hash (folded_arg0, mode_arg0) 540118334Speter % NBUCKETS), mode_arg0)) 540218334Speter && (p1 = lookup (folded_arg1, 540318334Speter (safe_hash (folded_arg1, mode_arg0) 540418334Speter % NBUCKETS), mode_arg0)) 540518334Speter && p0->first_same_value == p1->first_same_value))) 540618334Speter return ((code == EQ || code == LE || code == GE 540718334Speter || code == LEU || code == GEU) 540818334Speter ? true : false); 540918334Speter 541018334Speter /* If FOLDED_ARG0 is a register, see if the comparison we are 541118334Speter doing now is either the same as we did before or the reverse 541218334Speter (we only check the reverse if not floating-point). */ 541318334Speter else if (GET_CODE (folded_arg0) == REG) 541418334Speter { 541518334Speter int qty = reg_qty[REGNO (folded_arg0)]; 541618334Speter 541718334Speter if (REGNO_QTY_VALID_P (REGNO (folded_arg0)) 541818334Speter && (comparison_dominates_p (qty_comparison_code[qty], code) 541918334Speter || (comparison_dominates_p (qty_comparison_code[qty], 542018334Speter reverse_condition (code)) 542118334Speter && ! FLOAT_MODE_P (mode_arg0))) 542218334Speter && (rtx_equal_p (qty_comparison_const[qty], folded_arg1) 542318334Speter || (const_arg1 542418334Speter && rtx_equal_p (qty_comparison_const[qty], 542518334Speter const_arg1)) 542618334Speter || (GET_CODE (folded_arg1) == REG 542718334Speter && (reg_qty[REGNO (folded_arg1)] 542818334Speter == qty_comparison_qty[qty])))) 542918334Speter return (comparison_dominates_p (qty_comparison_code[qty], 543018334Speter code) 543118334Speter ? true : false); 543218334Speter } 543318334Speter } 543418334Speter } 543518334Speter 543618334Speter /* If we are comparing against zero, see if the first operand is 543718334Speter equivalent to an IOR with a constant. If so, we may be able to 543818334Speter determine the result of this comparison. */ 543918334Speter 544018334Speter if (const_arg1 == const0_rtx) 544118334Speter { 544218334Speter rtx y = lookup_as_function (folded_arg0, IOR); 544318334Speter rtx inner_const; 544418334Speter 544518334Speter if (y != 0 544618334Speter && (inner_const = equiv_constant (XEXP (y, 1))) != 0 544718334Speter && GET_CODE (inner_const) == CONST_INT 544818334Speter && INTVAL (inner_const) != 0) 544918334Speter { 545018334Speter int sign_bitnum = GET_MODE_BITSIZE (mode_arg0) - 1; 545118334Speter int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum 545218334Speter && (INTVAL (inner_const) 545318334Speter & ((HOST_WIDE_INT) 1 << sign_bitnum))); 545418334Speter rtx true = const_true_rtx, false = const0_rtx; 545518334Speter 545618334Speter#ifdef FLOAT_STORE_FLAG_VALUE 545718334Speter if (GET_MODE_CLASS (mode) == MODE_FLOAT) 545818334Speter { 545918334Speter true = CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE, 546018334Speter mode); 546118334Speter false = CONST0_RTX (mode); 546218334Speter } 546318334Speter#endif 546418334Speter 546518334Speter switch (code) 546618334Speter { 546718334Speter case EQ: 546818334Speter return false; 546918334Speter case NE: 547018334Speter return true; 547118334Speter case LT: case LE: 547218334Speter if (has_sign) 547318334Speter return true; 547418334Speter break; 547518334Speter case GT: case GE: 547618334Speter if (has_sign) 547718334Speter return false; 547818334Speter break; 547918334Speter } 548018334Speter } 548118334Speter } 548218334Speter 548318334Speter new = simplify_relational_operation (code, mode_arg0, 548418334Speter const_arg0 ? const_arg0 : folded_arg0, 548518334Speter const_arg1 ? const_arg1 : folded_arg1); 548618334Speter#ifdef FLOAT_STORE_FLAG_VALUE 548718334Speter if (new != 0 && GET_MODE_CLASS (mode) == MODE_FLOAT) 548818334Speter new = ((new == const0_rtx) ? CONST0_RTX (mode) 548918334Speter : CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE, mode)); 549018334Speter#endif 549118334Speter break; 549218334Speter 549318334Speter case '2': 549418334Speter case 'c': 549518334Speter switch (code) 549618334Speter { 549718334Speter case PLUS: 549818334Speter /* If the second operand is a LABEL_REF, see if the first is a MINUS 549918334Speter with that LABEL_REF as its second operand. If so, the result is 550018334Speter the first operand of that MINUS. This handles switches with an 550118334Speter ADDR_DIFF_VEC table. */ 550218334Speter if (const_arg1 && GET_CODE (const_arg1) == LABEL_REF) 550318334Speter { 550418334Speter rtx y 550518334Speter = GET_CODE (folded_arg0) == MINUS ? folded_arg0 550618334Speter : lookup_as_function (folded_arg0, MINUS); 550718334Speter 550818334Speter if (y != 0 && GET_CODE (XEXP (y, 1)) == LABEL_REF 550918334Speter && XEXP (XEXP (y, 1), 0) == XEXP (const_arg1, 0)) 551018334Speter return XEXP (y, 0); 551118334Speter 551218334Speter /* Now try for a CONST of a MINUS like the above. */ 551318334Speter if ((y = (GET_CODE (folded_arg0) == CONST ? folded_arg0 551418334Speter : lookup_as_function (folded_arg0, CONST))) != 0 551518334Speter && GET_CODE (XEXP (y, 0)) == MINUS 551618334Speter && GET_CODE (XEXP (XEXP (y, 0), 1)) == LABEL_REF 551718334Speter && XEXP (XEXP (XEXP (y, 0),1), 0) == XEXP (const_arg1, 0)) 551818334Speter return XEXP (XEXP (y, 0), 0); 551918334Speter } 552018334Speter 552118334Speter /* Likewise if the operands are in the other order. */ 552218334Speter if (const_arg0 && GET_CODE (const_arg0) == LABEL_REF) 552318334Speter { 552418334Speter rtx y 552518334Speter = GET_CODE (folded_arg1) == MINUS ? folded_arg1 552618334Speter : lookup_as_function (folded_arg1, MINUS); 552718334Speter 552818334Speter if (y != 0 && GET_CODE (XEXP (y, 1)) == LABEL_REF 552918334Speter && XEXP (XEXP (y, 1), 0) == XEXP (const_arg0, 0)) 553018334Speter return XEXP (y, 0); 553118334Speter 553218334Speter /* Now try for a CONST of a MINUS like the above. */ 553318334Speter if ((y = (GET_CODE (folded_arg1) == CONST ? folded_arg1 553418334Speter : lookup_as_function (folded_arg1, CONST))) != 0 553518334Speter && GET_CODE (XEXP (y, 0)) == MINUS 553618334Speter && GET_CODE (XEXP (XEXP (y, 0), 1)) == LABEL_REF 553718334Speter && XEXP (XEXP (XEXP (y, 0),1), 0) == XEXP (const_arg0, 0)) 553818334Speter return XEXP (XEXP (y, 0), 0); 553918334Speter } 554018334Speter 554118334Speter /* If second operand is a register equivalent to a negative 554218334Speter CONST_INT, see if we can find a register equivalent to the 554318334Speter positive constant. Make a MINUS if so. Don't do this for 554418334Speter a negative constant since we might then alternate between 554518334Speter chosing positive and negative constants. Having the positive 554618334Speter constant previously-used is the more common case. */ 554718334Speter if (const_arg1 && GET_CODE (const_arg1) == CONST_INT 554818334Speter && INTVAL (const_arg1) < 0 && GET_CODE (folded_arg1) == REG) 554918334Speter { 555018334Speter rtx new_const = GEN_INT (- INTVAL (const_arg1)); 555118334Speter struct table_elt *p 555218334Speter = lookup (new_const, safe_hash (new_const, mode) % NBUCKETS, 555318334Speter mode); 555418334Speter 555518334Speter if (p) 555618334Speter for (p = p->first_same_value; p; p = p->next_same_value) 555718334Speter if (GET_CODE (p->exp) == REG) 555818334Speter return cse_gen_binary (MINUS, mode, folded_arg0, 555918334Speter canon_reg (p->exp, NULL_RTX)); 556018334Speter } 556118334Speter goto from_plus; 556218334Speter 556318334Speter case MINUS: 556418334Speter /* If we have (MINUS Y C), see if Y is known to be (PLUS Z C2). 556518334Speter If so, produce (PLUS Z C2-C). */ 556618334Speter if (const_arg1 != 0 && GET_CODE (const_arg1) == CONST_INT) 556718334Speter { 556818334Speter rtx y = lookup_as_function (XEXP (x, 0), PLUS); 556918334Speter if (y && GET_CODE (XEXP (y, 1)) == CONST_INT) 557018334Speter return fold_rtx (plus_constant (copy_rtx (y), 557118334Speter -INTVAL (const_arg1)), 557218334Speter NULL_RTX); 557318334Speter } 557418334Speter 557518334Speter /* ... fall through ... */ 557618334Speter 557718334Speter from_plus: 557818334Speter case SMIN: case SMAX: case UMIN: case UMAX: 557918334Speter case IOR: case AND: case XOR: 558018334Speter case MULT: case DIV: case UDIV: 558118334Speter case ASHIFT: case LSHIFTRT: case ASHIFTRT: 558218334Speter /* If we have (<op> <reg> <const_int>) for an associative OP and REG 558318334Speter is known to be of similar form, we may be able to replace the 558418334Speter operation with a combined operation. This may eliminate the 558518334Speter intermediate operation if every use is simplified in this way. 558618334Speter Note that the similar optimization done by combine.c only works 558718334Speter if the intermediate operation's result has only one reference. */ 558818334Speter 558918334Speter if (GET_CODE (folded_arg0) == REG 559018334Speter && const_arg1 && GET_CODE (const_arg1) == CONST_INT) 559118334Speter { 559218334Speter int is_shift 559318334Speter = (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT); 559418334Speter rtx y = lookup_as_function (folded_arg0, code); 559518334Speter rtx inner_const; 559618334Speter enum rtx_code associate_code; 559718334Speter rtx new_const; 559818334Speter 559918334Speter if (y == 0 560018334Speter || 0 == (inner_const 560118334Speter = equiv_constant (fold_rtx (XEXP (y, 1), 0))) 560218334Speter || GET_CODE (inner_const) != CONST_INT 560318334Speter /* If we have compiled a statement like 560418334Speter "if (x == (x & mask1))", and now are looking at 560518334Speter "x & mask2", we will have a case where the first operand 560618334Speter of Y is the same as our first operand. Unless we detect 560718334Speter this case, an infinite loop will result. */ 560818334Speter || XEXP (y, 0) == folded_arg0) 560918334Speter break; 561018334Speter 561118334Speter /* Don't associate these operations if they are a PLUS with the 561218334Speter same constant and it is a power of two. These might be doable 561318334Speter with a pre- or post-increment. Similarly for two subtracts of 561418334Speter identical powers of two with post decrement. */ 561518334Speter 561618334Speter if (code == PLUS && INTVAL (const_arg1) == INTVAL (inner_const) 561718334Speter && (0 561818334Speter#if defined(HAVE_PRE_INCREMENT) || defined(HAVE_POST_INCREMENT) 561918334Speter || exact_log2 (INTVAL (const_arg1)) >= 0 562018334Speter#endif 562118334Speter#if defined(HAVE_PRE_DECREMENT) || defined(HAVE_POST_DECREMENT) 562218334Speter || exact_log2 (- INTVAL (const_arg1)) >= 0 562318334Speter#endif 562418334Speter )) 562518334Speter break; 562618334Speter 562718334Speter /* Compute the code used to compose the constants. For example, 562818334Speter A/C1/C2 is A/(C1 * C2), so if CODE == DIV, we want MULT. */ 562918334Speter 563018334Speter associate_code 563118334Speter = (code == MULT || code == DIV || code == UDIV ? MULT 563218334Speter : is_shift || code == PLUS || code == MINUS ? PLUS : code); 563318334Speter 563418334Speter new_const = simplify_binary_operation (associate_code, mode, 563518334Speter const_arg1, inner_const); 563618334Speter 563718334Speter if (new_const == 0) 563818334Speter break; 563918334Speter 564018334Speter /* If we are associating shift operations, don't let this 564118334Speter produce a shift of the size of the object or larger. 564218334Speter This could occur when we follow a sign-extend by a right 564318334Speter shift on a machine that does a sign-extend as a pair 564418334Speter of shifts. */ 564518334Speter 564618334Speter if (is_shift && GET_CODE (new_const) == CONST_INT 564718334Speter && INTVAL (new_const) >= GET_MODE_BITSIZE (mode)) 564818334Speter { 564918334Speter /* As an exception, we can turn an ASHIFTRT of this 565018334Speter form into a shift of the number of bits - 1. */ 565118334Speter if (code == ASHIFTRT) 565218334Speter new_const = GEN_INT (GET_MODE_BITSIZE (mode) - 1); 565318334Speter else 565418334Speter break; 565518334Speter } 565618334Speter 565718334Speter y = copy_rtx (XEXP (y, 0)); 565818334Speter 565918334Speter /* If Y contains our first operand (the most common way this 566018334Speter can happen is if Y is a MEM), we would do into an infinite 566118334Speter loop if we tried to fold it. So don't in that case. */ 566218334Speter 566318334Speter if (! reg_mentioned_p (folded_arg0, y)) 566418334Speter y = fold_rtx (y, insn); 566518334Speter 566618334Speter return cse_gen_binary (code, mode, y, new_const); 566718334Speter } 566818334Speter } 566918334Speter 567018334Speter new = simplify_binary_operation (code, mode, 567118334Speter const_arg0 ? const_arg0 : folded_arg0, 567218334Speter const_arg1 ? const_arg1 : folded_arg1); 567318334Speter break; 567418334Speter 567518334Speter case 'o': 567618334Speter /* (lo_sum (high X) X) is simply X. */ 567718334Speter if (code == LO_SUM && const_arg0 != 0 567818334Speter && GET_CODE (const_arg0) == HIGH 567918334Speter && rtx_equal_p (XEXP (const_arg0, 0), const_arg1)) 568018334Speter return const_arg1; 568118334Speter break; 568218334Speter 568318334Speter case '3': 568418334Speter case 'b': 568518334Speter new = simplify_ternary_operation (code, mode, mode_arg0, 568618334Speter const_arg0 ? const_arg0 : folded_arg0, 568718334Speter const_arg1 ? const_arg1 : folded_arg1, 568818334Speter const_arg2 ? const_arg2 : XEXP (x, 2)); 568918334Speter break; 569018334Speter } 569118334Speter 569218334Speter return new ? new : x; 569318334Speter} 569418334Speter 569518334Speter/* Return a constant value currently equivalent to X. 569618334Speter Return 0 if we don't know one. */ 569718334Speter 569818334Speterstatic rtx 569918334Speterequiv_constant (x) 570018334Speter rtx x; 570118334Speter{ 570218334Speter if (GET_CODE (x) == REG 570318334Speter && REGNO_QTY_VALID_P (REGNO (x)) 570418334Speter && qty_const[reg_qty[REGNO (x)]]) 570518334Speter x = gen_lowpart_if_possible (GET_MODE (x), qty_const[reg_qty[REGNO (x)]]); 570618334Speter 570718334Speter if (x != 0 && CONSTANT_P (x)) 570818334Speter return x; 570918334Speter 571018334Speter /* If X is a MEM, try to fold it outside the context of any insn to see if 571118334Speter it might be equivalent to a constant. That handles the case where it 571218334Speter is a constant-pool reference. Then try to look it up in the hash table 571318334Speter in case it is something whose value we have seen before. */ 571418334Speter 571518334Speter if (GET_CODE (x) == MEM) 571618334Speter { 571718334Speter struct table_elt *elt; 571818334Speter 571918334Speter x = fold_rtx (x, NULL_RTX); 572018334Speter if (CONSTANT_P (x)) 572118334Speter return x; 572218334Speter 572318334Speter elt = lookup (x, safe_hash (x, GET_MODE (x)) % NBUCKETS, GET_MODE (x)); 572418334Speter if (elt == 0) 572518334Speter return 0; 572618334Speter 572718334Speter for (elt = elt->first_same_value; elt; elt = elt->next_same_value) 572818334Speter if (elt->is_const && CONSTANT_P (elt->exp)) 572918334Speter return elt->exp; 573018334Speter } 573118334Speter 573218334Speter return 0; 573318334Speter} 573418334Speter 573518334Speter/* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a fixed-point 573618334Speter number, return an rtx (MEM, SUBREG, or CONST_INT) that refers to the 573718334Speter least-significant part of X. 573818334Speter MODE specifies how big a part of X to return. 573918334Speter 574018334Speter If the requested operation cannot be done, 0 is returned. 574118334Speter 574218334Speter This is similar to gen_lowpart in emit-rtl.c. */ 574318334Speter 574418334Speterrtx 574518334Spetergen_lowpart_if_possible (mode, x) 574618334Speter enum machine_mode mode; 574718334Speter register rtx x; 574818334Speter{ 574918334Speter rtx result = gen_lowpart_common (mode, x); 575018334Speter 575118334Speter if (result) 575218334Speter return result; 575318334Speter else if (GET_CODE (x) == MEM) 575418334Speter { 575518334Speter /* This is the only other case we handle. */ 575618334Speter register int offset = 0; 575718334Speter rtx new; 575818334Speter 575918334Speter if (WORDS_BIG_ENDIAN) 576018334Speter offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD) 576118334Speter - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)); 576218334Speter if (BYTES_BIG_ENDIAN) 576318334Speter /* Adjust the address so that the address-after-the-data is 576418334Speter unchanged. */ 576518334Speter offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)) 576618334Speter - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))); 576718334Speter new = gen_rtx (MEM, mode, plus_constant (XEXP (x, 0), offset)); 576818334Speter if (! memory_address_p (mode, XEXP (new, 0))) 576918334Speter return 0; 577018334Speter MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x); 577118334Speter RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x); 577218334Speter MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x); 577318334Speter return new; 577418334Speter } 577518334Speter else 577618334Speter return 0; 577718334Speter} 577818334Speter 577918334Speter/* Given INSN, a jump insn, TAKEN indicates if we are following the "taken" 578018334Speter branch. It will be zero if not. 578118334Speter 578218334Speter In certain cases, this can cause us to add an equivalence. For example, 578318334Speter if we are following the taken case of 578418334Speter if (i == 2) 578518334Speter we can add the fact that `i' and '2' are now equivalent. 578618334Speter 578718334Speter In any case, we can record that this comparison was passed. If the same 578818334Speter comparison is seen later, we will know its value. */ 578918334Speter 579018334Speterstatic void 579118334Speterrecord_jump_equiv (insn, taken) 579218334Speter rtx insn; 579318334Speter int taken; 579418334Speter{ 579518334Speter int cond_known_true; 579618334Speter rtx op0, op1; 579718334Speter enum machine_mode mode, mode0, mode1; 579818334Speter int reversed_nonequality = 0; 579918334Speter enum rtx_code code; 580018334Speter 580118334Speter /* Ensure this is the right kind of insn. */ 580218334Speter if (! condjump_p (insn) || simplejump_p (insn)) 580318334Speter return; 580418334Speter 580518334Speter /* See if this jump condition is known true or false. */ 580618334Speter if (taken) 580718334Speter cond_known_true = (XEXP (SET_SRC (PATTERN (insn)), 2) == pc_rtx); 580818334Speter else 580918334Speter cond_known_true = (XEXP (SET_SRC (PATTERN (insn)), 1) == pc_rtx); 581018334Speter 581118334Speter /* Get the type of comparison being done and the operands being compared. 581218334Speter If we had to reverse a non-equality condition, record that fact so we 581318334Speter know that it isn't valid for floating-point. */ 581418334Speter code = GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)); 581518334Speter op0 = fold_rtx (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0), insn); 581618334Speter op1 = fold_rtx (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 1), insn); 581718334Speter 581818334Speter code = find_comparison_args (code, &op0, &op1, &mode0, &mode1); 581918334Speter if (! cond_known_true) 582018334Speter { 582118334Speter reversed_nonequality = (code != EQ && code != NE); 582218334Speter code = reverse_condition (code); 582318334Speter } 582418334Speter 582518334Speter /* The mode is the mode of the non-constant. */ 582618334Speter mode = mode0; 582718334Speter if (mode1 != VOIDmode) 582818334Speter mode = mode1; 582918334Speter 583018334Speter record_jump_cond (code, mode, op0, op1, reversed_nonequality); 583118334Speter} 583218334Speter 583318334Speter/* We know that comparison CODE applied to OP0 and OP1 in MODE is true. 583418334Speter REVERSED_NONEQUALITY is nonzero if CODE had to be swapped. 583518334Speter Make any useful entries we can with that information. Called from 583618334Speter above function and called recursively. */ 583718334Speter 583818334Speterstatic void 583918334Speterrecord_jump_cond (code, mode, op0, op1, reversed_nonequality) 584018334Speter enum rtx_code code; 584118334Speter enum machine_mode mode; 584218334Speter rtx op0, op1; 584318334Speter int reversed_nonequality; 584418334Speter{ 584518334Speter unsigned op0_hash, op1_hash; 584618334Speter int op0_in_memory, op0_in_struct, op1_in_memory, op1_in_struct; 584718334Speter struct table_elt *op0_elt, *op1_elt; 584818334Speter 584918334Speter /* If OP0 and OP1 are known equal, and either is a paradoxical SUBREG, 585018334Speter we know that they are also equal in the smaller mode (this is also 585118334Speter true for all smaller modes whether or not there is a SUBREG, but 585218334Speter is not worth testing for with no SUBREG. */ 585318334Speter 585418334Speter /* Note that GET_MODE (op0) may not equal MODE. */ 585518334Speter if (code == EQ && GET_CODE (op0) == SUBREG 585618334Speter && (GET_MODE_SIZE (GET_MODE (op0)) 585718334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))) 585818334Speter { 585918334Speter enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0)); 586018334Speter rtx tem = gen_lowpart_if_possible (inner_mode, op1); 586118334Speter 586218334Speter record_jump_cond (code, mode, SUBREG_REG (op0), 586318334Speter tem ? tem : gen_rtx (SUBREG, inner_mode, op1, 0), 586418334Speter reversed_nonequality); 586518334Speter } 586618334Speter 586718334Speter if (code == EQ && GET_CODE (op1) == SUBREG 586818334Speter && (GET_MODE_SIZE (GET_MODE (op1)) 586918334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1))))) 587018334Speter { 587118334Speter enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op1)); 587218334Speter rtx tem = gen_lowpart_if_possible (inner_mode, op0); 587318334Speter 587418334Speter record_jump_cond (code, mode, SUBREG_REG (op1), 587518334Speter tem ? tem : gen_rtx (SUBREG, inner_mode, op0, 0), 587618334Speter reversed_nonequality); 587718334Speter } 587818334Speter 587918334Speter /* Similarly, if this is an NE comparison, and either is a SUBREG 588018334Speter making a smaller mode, we know the whole thing is also NE. */ 588118334Speter 588218334Speter /* Note that GET_MODE (op0) may not equal MODE; 588318334Speter if we test MODE instead, we can get an infinite recursion 588418334Speter alternating between two modes each wider than MODE. */ 588518334Speter 588618334Speter if (code == NE && GET_CODE (op0) == SUBREG 588718334Speter && subreg_lowpart_p (op0) 588818334Speter && (GET_MODE_SIZE (GET_MODE (op0)) 588918334Speter < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))) 589018334Speter { 589118334Speter enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0)); 589218334Speter rtx tem = gen_lowpart_if_possible (inner_mode, op1); 589318334Speter 589418334Speter record_jump_cond (code, mode, SUBREG_REG (op0), 589518334Speter tem ? tem : gen_rtx (SUBREG, inner_mode, op1, 0), 589618334Speter reversed_nonequality); 589718334Speter } 589818334Speter 589918334Speter if (code == NE && GET_CODE (op1) == SUBREG 590018334Speter && subreg_lowpart_p (op1) 590118334Speter && (GET_MODE_SIZE (GET_MODE (op1)) 590218334Speter < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1))))) 590318334Speter { 590418334Speter enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op1)); 590518334Speter rtx tem = gen_lowpart_if_possible (inner_mode, op0); 590618334Speter 590718334Speter record_jump_cond (code, mode, SUBREG_REG (op1), 590818334Speter tem ? tem : gen_rtx (SUBREG, inner_mode, op0, 0), 590918334Speter reversed_nonequality); 591018334Speter } 591118334Speter 591218334Speter /* Hash both operands. */ 591318334Speter 591418334Speter do_not_record = 0; 591518334Speter hash_arg_in_memory = 0; 591618334Speter hash_arg_in_struct = 0; 591718334Speter op0_hash = HASH (op0, mode); 591818334Speter op0_in_memory = hash_arg_in_memory; 591918334Speter op0_in_struct = hash_arg_in_struct; 592018334Speter 592118334Speter if (do_not_record) 592218334Speter return; 592318334Speter 592418334Speter do_not_record = 0; 592518334Speter hash_arg_in_memory = 0; 592618334Speter hash_arg_in_struct = 0; 592718334Speter op1_hash = HASH (op1, mode); 592818334Speter op1_in_memory = hash_arg_in_memory; 592918334Speter op1_in_struct = hash_arg_in_struct; 593018334Speter 593118334Speter if (do_not_record) 593218334Speter return; 593318334Speter 593418334Speter /* Look up both operands. */ 593518334Speter op0_elt = lookup (op0, op0_hash, mode); 593618334Speter op1_elt = lookup (op1, op1_hash, mode); 593718334Speter 593818334Speter /* If both operands are already equivalent or if they are not in the 593918334Speter table but are identical, do nothing. */ 594018334Speter if ((op0_elt != 0 && op1_elt != 0 594118334Speter && op0_elt->first_same_value == op1_elt->first_same_value) 594218334Speter || op0 == op1 || rtx_equal_p (op0, op1)) 594318334Speter return; 594418334Speter 594518334Speter /* If we aren't setting two things equal all we can do is save this 594618334Speter comparison. Similarly if this is floating-point. In the latter 594718334Speter case, OP1 might be zero and both -0.0 and 0.0 are equal to it. 594818334Speter If we record the equality, we might inadvertently delete code 594918334Speter whose intent was to change -0 to +0. */ 595018334Speter 595118334Speter if (code != EQ || FLOAT_MODE_P (GET_MODE (op0))) 595218334Speter { 595318334Speter /* If we reversed a floating-point comparison, if OP0 is not a 595418334Speter register, or if OP1 is neither a register or constant, we can't 595518334Speter do anything. */ 595618334Speter 595718334Speter if (GET_CODE (op1) != REG) 595818334Speter op1 = equiv_constant (op1); 595918334Speter 596018334Speter if ((reversed_nonequality && FLOAT_MODE_P (mode)) 596118334Speter || GET_CODE (op0) != REG || op1 == 0) 596218334Speter return; 596318334Speter 596418334Speter /* Put OP0 in the hash table if it isn't already. This gives it a 596518334Speter new quantity number. */ 596618334Speter if (op0_elt == 0) 596718334Speter { 596818334Speter if (insert_regs (op0, NULL_PTR, 0)) 596918334Speter { 597018334Speter rehash_using_reg (op0); 597118334Speter op0_hash = HASH (op0, mode); 597218334Speter 597318334Speter /* If OP0 is contained in OP1, this changes its hash code 597418334Speter as well. Faster to rehash than to check, except 597518334Speter for the simple case of a constant. */ 597618334Speter if (! CONSTANT_P (op1)) 597718334Speter op1_hash = HASH (op1,mode); 597818334Speter } 597918334Speter 598018334Speter op0_elt = insert (op0, NULL_PTR, op0_hash, mode); 598118334Speter op0_elt->in_memory = op0_in_memory; 598218334Speter op0_elt->in_struct = op0_in_struct; 598318334Speter } 598418334Speter 598518334Speter qty_comparison_code[reg_qty[REGNO (op0)]] = code; 598618334Speter if (GET_CODE (op1) == REG) 598718334Speter { 598818334Speter /* Look it up again--in case op0 and op1 are the same. */ 598918334Speter op1_elt = lookup (op1, op1_hash, mode); 599018334Speter 599118334Speter /* Put OP1 in the hash table so it gets a new quantity number. */ 599218334Speter if (op1_elt == 0) 599318334Speter { 599418334Speter if (insert_regs (op1, NULL_PTR, 0)) 599518334Speter { 599618334Speter rehash_using_reg (op1); 599718334Speter op1_hash = HASH (op1, mode); 599818334Speter } 599918334Speter 600018334Speter op1_elt = insert (op1, NULL_PTR, op1_hash, mode); 600118334Speter op1_elt->in_memory = op1_in_memory; 600218334Speter op1_elt->in_struct = op1_in_struct; 600318334Speter } 600418334Speter 600518334Speter qty_comparison_qty[reg_qty[REGNO (op0)]] = reg_qty[REGNO (op1)]; 600618334Speter qty_comparison_const[reg_qty[REGNO (op0)]] = 0; 600718334Speter } 600818334Speter else 600918334Speter { 601018334Speter qty_comparison_qty[reg_qty[REGNO (op0)]] = -1; 601118334Speter qty_comparison_const[reg_qty[REGNO (op0)]] = op1; 601218334Speter } 601318334Speter 601418334Speter return; 601518334Speter } 601618334Speter 601718334Speter /* If either side is still missing an equivalence, make it now, 601818334Speter then merge the equivalences. */ 601918334Speter 602018334Speter if (op0_elt == 0) 602118334Speter { 602218334Speter if (insert_regs (op0, NULL_PTR, 0)) 602318334Speter { 602418334Speter rehash_using_reg (op0); 602518334Speter op0_hash = HASH (op0, mode); 602618334Speter } 602718334Speter 602818334Speter op0_elt = insert (op0, NULL_PTR, op0_hash, mode); 602918334Speter op0_elt->in_memory = op0_in_memory; 603018334Speter op0_elt->in_struct = op0_in_struct; 603118334Speter } 603218334Speter 603318334Speter if (op1_elt == 0) 603418334Speter { 603518334Speter if (insert_regs (op1, NULL_PTR, 0)) 603618334Speter { 603718334Speter rehash_using_reg (op1); 603818334Speter op1_hash = HASH (op1, mode); 603918334Speter } 604018334Speter 604118334Speter op1_elt = insert (op1, NULL_PTR, op1_hash, mode); 604218334Speter op1_elt->in_memory = op1_in_memory; 604318334Speter op1_elt->in_struct = op1_in_struct; 604418334Speter } 604518334Speter 604618334Speter merge_equiv_classes (op0_elt, op1_elt); 604718334Speter last_jump_equiv_class = op0_elt; 604818334Speter} 604918334Speter 605018334Speter/* CSE processing for one instruction. 605118334Speter First simplify sources and addresses of all assignments 605218334Speter in the instruction, using previously-computed equivalents values. 605318334Speter Then install the new sources and destinations in the table 605418334Speter of available values. 605518334Speter 605618334Speter If IN_LIBCALL_BLOCK is nonzero, don't record any equivalence made in 605718334Speter the insn. */ 605818334Speter 605918334Speter/* Data on one SET contained in the instruction. */ 606018334Speter 606118334Speterstruct set 606218334Speter{ 606318334Speter /* The SET rtx itself. */ 606418334Speter rtx rtl; 606518334Speter /* The SET_SRC of the rtx (the original value, if it is changing). */ 606618334Speter rtx src; 606718334Speter /* The hash-table element for the SET_SRC of the SET. */ 606818334Speter struct table_elt *src_elt; 606918334Speter /* Hash value for the SET_SRC. */ 607018334Speter unsigned src_hash; 607118334Speter /* Hash value for the SET_DEST. */ 607218334Speter unsigned dest_hash; 607318334Speter /* The SET_DEST, with SUBREG, etc., stripped. */ 607418334Speter rtx inner_dest; 607518334Speter /* Place where the pointer to the INNER_DEST was found. */ 607618334Speter rtx *inner_dest_loc; 607718334Speter /* Nonzero if the SET_SRC is in memory. */ 607818334Speter char src_in_memory; 607918334Speter /* Nonzero if the SET_SRC is in a structure. */ 608018334Speter char src_in_struct; 608118334Speter /* Nonzero if the SET_SRC contains something 608218334Speter whose value cannot be predicted and understood. */ 608318334Speter char src_volatile; 608418334Speter /* Original machine mode, in case it becomes a CONST_INT. */ 608518334Speter enum machine_mode mode; 608618334Speter /* A constant equivalent for SET_SRC, if any. */ 608718334Speter rtx src_const; 608818334Speter /* Hash value of constant equivalent for SET_SRC. */ 608918334Speter unsigned src_const_hash; 609018334Speter /* Table entry for constant equivalent for SET_SRC, if any. */ 609118334Speter struct table_elt *src_const_elt; 609218334Speter}; 609318334Speter 609418334Speterstatic void 609518334Spetercse_insn (insn, in_libcall_block) 609618334Speter rtx insn; 609718334Speter int in_libcall_block; 609818334Speter{ 609918334Speter register rtx x = PATTERN (insn); 610018334Speter register int i; 610118334Speter rtx tem; 610218334Speter register int n_sets = 0; 610318334Speter 610418334Speter /* Records what this insn does to set CC0. */ 610518334Speter rtx this_insn_cc0 = 0; 610618334Speter enum machine_mode this_insn_cc0_mode; 610718334Speter struct write_data writes_memory; 610818334Speter static struct write_data init = {0, 0, 0, 0}; 610918334Speter 611018334Speter rtx src_eqv = 0; 611118334Speter struct table_elt *src_eqv_elt = 0; 611218334Speter int src_eqv_volatile; 611318334Speter int src_eqv_in_memory; 611418334Speter int src_eqv_in_struct; 611518334Speter unsigned src_eqv_hash; 611618334Speter 611718334Speter struct set *sets; 611818334Speter 611918334Speter this_insn = insn; 612018334Speter writes_memory = init; 612118334Speter 612218334Speter /* Find all the SETs and CLOBBERs in this instruction. 612318334Speter Record all the SETs in the array `set' and count them. 612418334Speter Also determine whether there is a CLOBBER that invalidates 612518334Speter all memory references, or all references at varying addresses. */ 612618334Speter 612718334Speter if (GET_CODE (insn) == CALL_INSN) 612818334Speter { 612918334Speter for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1)) 613018334Speter if (GET_CODE (XEXP (tem, 0)) == CLOBBER) 613118334Speter invalidate (SET_DEST (XEXP (tem, 0)), VOIDmode); 613218334Speter } 613318334Speter 613418334Speter if (GET_CODE (x) == SET) 613518334Speter { 613618334Speter sets = (struct set *) alloca (sizeof (struct set)); 613718334Speter sets[0].rtl = x; 613818334Speter 613918334Speter /* Ignore SETs that are unconditional jumps. 614018334Speter They never need cse processing, so this does not hurt. 614118334Speter The reason is not efficiency but rather 614218334Speter so that we can test at the end for instructions 614318334Speter that have been simplified to unconditional jumps 614418334Speter and not be misled by unchanged instructions 614518334Speter that were unconditional jumps to begin with. */ 614618334Speter if (SET_DEST (x) == pc_rtx 614718334Speter && GET_CODE (SET_SRC (x)) == LABEL_REF) 614818334Speter ; 614918334Speter 615018334Speter /* Don't count call-insns, (set (reg 0) (call ...)), as a set. 615118334Speter The hard function value register is used only once, to copy to 615218334Speter someplace else, so it isn't worth cse'ing (and on 80386 is unsafe)! 615318334Speter Ensure we invalidate the destination register. On the 80386 no 615418334Speter other code would invalidate it since it is a fixed_reg. 615518334Speter We need not check the return of apply_change_group; see canon_reg. */ 615618334Speter 615718334Speter else if (GET_CODE (SET_SRC (x)) == CALL) 615818334Speter { 615918334Speter canon_reg (SET_SRC (x), insn); 616018334Speter apply_change_group (); 616118334Speter fold_rtx (SET_SRC (x), insn); 616218334Speter invalidate (SET_DEST (x), VOIDmode); 616318334Speter } 616418334Speter else 616518334Speter n_sets = 1; 616618334Speter } 616718334Speter else if (GET_CODE (x) == PARALLEL) 616818334Speter { 616918334Speter register int lim = XVECLEN (x, 0); 617018334Speter 617118334Speter sets = (struct set *) alloca (lim * sizeof (struct set)); 617218334Speter 617318334Speter /* Find all regs explicitly clobbered in this insn, 617418334Speter and ensure they are not replaced with any other regs 617518334Speter elsewhere in this insn. 617618334Speter When a reg that is clobbered is also used for input, 617718334Speter we should presume that that is for a reason, 617818334Speter and we should not substitute some other register 617918334Speter which is not supposed to be clobbered. 618018334Speter Therefore, this loop cannot be merged into the one below 618118334Speter because a CALL may precede a CLOBBER and refer to the 618218334Speter value clobbered. We must not let a canonicalization do 618318334Speter anything in that case. */ 618418334Speter for (i = 0; i < lim; i++) 618518334Speter { 618618334Speter register rtx y = XVECEXP (x, 0, i); 618718334Speter if (GET_CODE (y) == CLOBBER) 618818334Speter { 618918334Speter rtx clobbered = XEXP (y, 0); 619018334Speter 619118334Speter if (GET_CODE (clobbered) == REG 619218334Speter || GET_CODE (clobbered) == SUBREG) 619318334Speter invalidate (clobbered, VOIDmode); 619418334Speter else if (GET_CODE (clobbered) == STRICT_LOW_PART 619518334Speter || GET_CODE (clobbered) == ZERO_EXTRACT) 619618334Speter invalidate (XEXP (clobbered, 0), GET_MODE (clobbered)); 619718334Speter } 619818334Speter } 619918334Speter 620018334Speter for (i = 0; i < lim; i++) 620118334Speter { 620218334Speter register rtx y = XVECEXP (x, 0, i); 620318334Speter if (GET_CODE (y) == SET) 620418334Speter { 620518334Speter /* As above, we ignore unconditional jumps and call-insns and 620618334Speter ignore the result of apply_change_group. */ 620718334Speter if (GET_CODE (SET_SRC (y)) == CALL) 620818334Speter { 620918334Speter canon_reg (SET_SRC (y), insn); 621018334Speter apply_change_group (); 621118334Speter fold_rtx (SET_SRC (y), insn); 621218334Speter invalidate (SET_DEST (y), VOIDmode); 621318334Speter } 621418334Speter else if (SET_DEST (y) == pc_rtx 621518334Speter && GET_CODE (SET_SRC (y)) == LABEL_REF) 621618334Speter ; 621718334Speter else 621818334Speter sets[n_sets++].rtl = y; 621918334Speter } 622018334Speter else if (GET_CODE (y) == CLOBBER) 622118334Speter { 622218334Speter /* If we clobber memory, take note of that, 622318334Speter and canon the address. 622418334Speter This does nothing when a register is clobbered 622518334Speter because we have already invalidated the reg. */ 622618334Speter if (GET_CODE (XEXP (y, 0)) == MEM) 622718334Speter { 622818334Speter canon_reg (XEXP (y, 0), NULL_RTX); 622918334Speter note_mem_written (XEXP (y, 0), &writes_memory); 623018334Speter } 623118334Speter } 623218334Speter else if (GET_CODE (y) == USE 623318334Speter && ! (GET_CODE (XEXP (y, 0)) == REG 623418334Speter && REGNO (XEXP (y, 0)) < FIRST_PSEUDO_REGISTER)) 623518334Speter canon_reg (y, NULL_RTX); 623618334Speter else if (GET_CODE (y) == CALL) 623718334Speter { 623818334Speter /* The result of apply_change_group can be ignored; see 623918334Speter canon_reg. */ 624018334Speter canon_reg (y, insn); 624118334Speter apply_change_group (); 624218334Speter fold_rtx (y, insn); 624318334Speter } 624418334Speter } 624518334Speter } 624618334Speter else if (GET_CODE (x) == CLOBBER) 624718334Speter { 624818334Speter if (GET_CODE (XEXP (x, 0)) == MEM) 624918334Speter { 625018334Speter canon_reg (XEXP (x, 0), NULL_RTX); 625118334Speter note_mem_written (XEXP (x, 0), &writes_memory); 625218334Speter } 625318334Speter } 625418334Speter 625518334Speter /* Canonicalize a USE of a pseudo register or memory location. */ 625618334Speter else if (GET_CODE (x) == USE 625718334Speter && ! (GET_CODE (XEXP (x, 0)) == REG 625818334Speter && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)) 625918334Speter canon_reg (XEXP (x, 0), NULL_RTX); 626018334Speter else if (GET_CODE (x) == CALL) 626118334Speter { 626218334Speter /* The result of apply_change_group can be ignored; see canon_reg. */ 626318334Speter canon_reg (x, insn); 626418334Speter apply_change_group (); 626518334Speter fold_rtx (x, insn); 626618334Speter } 626718334Speter 626818334Speter /* Store the equivalent value in SRC_EQV, if different, or if the DEST 626918334Speter is a STRICT_LOW_PART. The latter condition is necessary because SRC_EQV 627018334Speter is handled specially for this case, and if it isn't set, then there will 627118334Speter be no equivalence for the destination. */ 627218334Speter if (n_sets == 1 && REG_NOTES (insn) != 0 627318334Speter && (tem = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0 627418334Speter && (! rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl)) 627518334Speter || GET_CODE (SET_DEST (sets[0].rtl)) == STRICT_LOW_PART)) 627618334Speter src_eqv = canon_reg (XEXP (tem, 0), NULL_RTX); 627718334Speter 627818334Speter /* Canonicalize sources and addresses of destinations. 627918334Speter We do this in a separate pass to avoid problems when a MATCH_DUP is 628018334Speter present in the insn pattern. In that case, we want to ensure that 628118334Speter we don't break the duplicate nature of the pattern. So we will replace 628218334Speter both operands at the same time. Otherwise, we would fail to find an 628318334Speter equivalent substitution in the loop calling validate_change below. 628418334Speter 628518334Speter We used to suppress canonicalization of DEST if it appears in SRC, 628618334Speter but we don't do this any more. */ 628718334Speter 628818334Speter for (i = 0; i < n_sets; i++) 628918334Speter { 629018334Speter rtx dest = SET_DEST (sets[i].rtl); 629118334Speter rtx src = SET_SRC (sets[i].rtl); 629218334Speter rtx new = canon_reg (src, insn); 629318334Speter 629418334Speter if ((GET_CODE (new) == REG && GET_CODE (src) == REG 629518334Speter && ((REGNO (new) < FIRST_PSEUDO_REGISTER) 629618334Speter != (REGNO (src) < FIRST_PSEUDO_REGISTER))) 629718334Speter || insn_n_dups[recog_memoized (insn)] > 0) 629818334Speter validate_change (insn, &SET_SRC (sets[i].rtl), new, 1); 629918334Speter else 630018334Speter SET_SRC (sets[i].rtl) = new; 630118334Speter 630218334Speter if (GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT) 630318334Speter { 630418334Speter validate_change (insn, &XEXP (dest, 1), 630518334Speter canon_reg (XEXP (dest, 1), insn), 1); 630618334Speter validate_change (insn, &XEXP (dest, 2), 630718334Speter canon_reg (XEXP (dest, 2), insn), 1); 630818334Speter } 630918334Speter 631018334Speter while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART 631118334Speter || GET_CODE (dest) == ZERO_EXTRACT 631218334Speter || GET_CODE (dest) == SIGN_EXTRACT) 631318334Speter dest = XEXP (dest, 0); 631418334Speter 631518334Speter if (GET_CODE (dest) == MEM) 631618334Speter canon_reg (dest, insn); 631718334Speter } 631818334Speter 631918334Speter /* Now that we have done all the replacements, we can apply the change 632018334Speter group and see if they all work. Note that this will cause some 632118334Speter canonicalizations that would have worked individually not to be applied 632218334Speter because some other canonicalization didn't work, but this should not 632318334Speter occur often. 632418334Speter 632518334Speter The result of apply_change_group can be ignored; see canon_reg. */ 632618334Speter 632718334Speter apply_change_group (); 632818334Speter 632918334Speter /* Set sets[i].src_elt to the class each source belongs to. 633018334Speter Detect assignments from or to volatile things 633118334Speter and set set[i] to zero so they will be ignored 633218334Speter in the rest of this function. 633318334Speter 633418334Speter Nothing in this loop changes the hash table or the register chains. */ 633518334Speter 633618334Speter for (i = 0; i < n_sets; i++) 633718334Speter { 633818334Speter register rtx src, dest; 633918334Speter register rtx src_folded; 634018334Speter register struct table_elt *elt = 0, *p; 634118334Speter enum machine_mode mode; 634218334Speter rtx src_eqv_here; 634318334Speter rtx src_const = 0; 634418334Speter rtx src_related = 0; 634518334Speter struct table_elt *src_const_elt = 0; 634618334Speter int src_cost = 10000, src_eqv_cost = 10000, src_folded_cost = 10000; 634718334Speter int src_related_cost = 10000, src_elt_cost = 10000; 634818334Speter /* Set non-zero if we need to call force_const_mem on with the 634918334Speter contents of src_folded before using it. */ 635018334Speter int src_folded_force_flag = 0; 635118334Speter 635218334Speter dest = SET_DEST (sets[i].rtl); 635318334Speter src = SET_SRC (sets[i].rtl); 635418334Speter 635518334Speter /* If SRC is a constant that has no machine mode, 635618334Speter hash it with the destination's machine mode. 635718334Speter This way we can keep different modes separate. */ 635818334Speter 635918334Speter mode = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src); 636018334Speter sets[i].mode = mode; 636118334Speter 636218334Speter if (src_eqv) 636318334Speter { 636418334Speter enum machine_mode eqvmode = mode; 636518334Speter if (GET_CODE (dest) == STRICT_LOW_PART) 636618334Speter eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0))); 636718334Speter do_not_record = 0; 636818334Speter hash_arg_in_memory = 0; 636918334Speter hash_arg_in_struct = 0; 637018334Speter src_eqv = fold_rtx (src_eqv, insn); 637118334Speter src_eqv_hash = HASH (src_eqv, eqvmode); 637218334Speter 637318334Speter /* Find the equivalence class for the equivalent expression. */ 637418334Speter 637518334Speter if (!do_not_record) 637618334Speter src_eqv_elt = lookup (src_eqv, src_eqv_hash, eqvmode); 637718334Speter 637818334Speter src_eqv_volatile = do_not_record; 637918334Speter src_eqv_in_memory = hash_arg_in_memory; 638018334Speter src_eqv_in_struct = hash_arg_in_struct; 638118334Speter } 638218334Speter 638318334Speter /* If this is a STRICT_LOW_PART assignment, src_eqv corresponds to the 638418334Speter value of the INNER register, not the destination. So it is not 638518334Speter a valid substitution for the source. But save it for later. */ 638618334Speter if (GET_CODE (dest) == STRICT_LOW_PART) 638718334Speter src_eqv_here = 0; 638818334Speter else 638918334Speter src_eqv_here = src_eqv; 639018334Speter 639118334Speter /* Simplify and foldable subexpressions in SRC. Then get the fully- 639218334Speter simplified result, which may not necessarily be valid. */ 639318334Speter src_folded = fold_rtx (src, insn); 639418334Speter 639518334Speter#if 0 639618334Speter /* ??? This caused bad code to be generated for the m68k port with -O2. 639718334Speter Suppose src is (CONST_INT -1), and that after truncation src_folded 639818334Speter is (CONST_INT 3). Suppose src_folded is then used for src_const. 639918334Speter At the end we will add src and src_const to the same equivalence 640018334Speter class. We now have 3 and -1 on the same equivalence class. This 640118334Speter causes later instructions to be mis-optimized. */ 640218334Speter /* If storing a constant in a bitfield, pre-truncate the constant 640318334Speter so we will be able to record it later. */ 640418334Speter if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT 640518334Speter || GET_CODE (SET_DEST (sets[i].rtl)) == SIGN_EXTRACT) 640618334Speter { 640718334Speter rtx width = XEXP (SET_DEST (sets[i].rtl), 1); 640818334Speter 640918334Speter if (GET_CODE (src) == CONST_INT 641018334Speter && GET_CODE (width) == CONST_INT 641118334Speter && INTVAL (width) < HOST_BITS_PER_WIDE_INT 641218334Speter && (INTVAL (src) & ((HOST_WIDE_INT) (-1) << INTVAL (width)))) 641318334Speter src_folded 641418334Speter = GEN_INT (INTVAL (src) & (((HOST_WIDE_INT) 1 641518334Speter << INTVAL (width)) - 1)); 641618334Speter } 641718334Speter#endif 641818334Speter 641918334Speter /* Compute SRC's hash code, and also notice if it 642018334Speter should not be recorded at all. In that case, 642118334Speter prevent any further processing of this assignment. */ 642218334Speter do_not_record = 0; 642318334Speter hash_arg_in_memory = 0; 642418334Speter hash_arg_in_struct = 0; 642518334Speter 642618334Speter sets[i].src = src; 642718334Speter sets[i].src_hash = HASH (src, mode); 642818334Speter sets[i].src_volatile = do_not_record; 642918334Speter sets[i].src_in_memory = hash_arg_in_memory; 643018334Speter sets[i].src_in_struct = hash_arg_in_struct; 643118334Speter 643218334Speter#if 0 643318334Speter /* It is no longer clear why we used to do this, but it doesn't 643418334Speter appear to still be needed. So let's try without it since this 643518334Speter code hurts cse'ing widened ops. */ 643618334Speter /* If source is a perverse subreg (such as QI treated as an SI), 643718334Speter treat it as volatile. It may do the work of an SI in one context 643818334Speter where the extra bits are not being used, but cannot replace an SI 643918334Speter in general. */ 644018334Speter if (GET_CODE (src) == SUBREG 644118334Speter && (GET_MODE_SIZE (GET_MODE (src)) 644218334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))) 644318334Speter sets[i].src_volatile = 1; 644418334Speter#endif 644518334Speter 644618334Speter /* Locate all possible equivalent forms for SRC. Try to replace 644718334Speter SRC in the insn with each cheaper equivalent. 644818334Speter 644918334Speter We have the following types of equivalents: SRC itself, a folded 645018334Speter version, a value given in a REG_EQUAL note, or a value related 645118334Speter to a constant. 645218334Speter 645318334Speter Each of these equivalents may be part of an additional class 645418334Speter of equivalents (if more than one is in the table, they must be in 645518334Speter the same class; we check for this). 645618334Speter 645718334Speter If the source is volatile, we don't do any table lookups. 645818334Speter 645918334Speter We note any constant equivalent for possible later use in a 646018334Speter REG_NOTE. */ 646118334Speter 646218334Speter if (!sets[i].src_volatile) 646318334Speter elt = lookup (src, sets[i].src_hash, mode); 646418334Speter 646518334Speter sets[i].src_elt = elt; 646618334Speter 646718334Speter if (elt && src_eqv_here && src_eqv_elt) 646818334Speter { 646918334Speter if (elt->first_same_value != src_eqv_elt->first_same_value) 647018334Speter { 647118334Speter /* The REG_EQUAL is indicating that two formerly distinct 647218334Speter classes are now equivalent. So merge them. */ 647318334Speter merge_equiv_classes (elt, src_eqv_elt); 647418334Speter src_eqv_hash = HASH (src_eqv, elt->mode); 647518334Speter src_eqv_elt = lookup (src_eqv, src_eqv_hash, elt->mode); 647618334Speter } 647718334Speter 647818334Speter src_eqv_here = 0; 647918334Speter } 648018334Speter 648118334Speter else if (src_eqv_elt) 648218334Speter elt = src_eqv_elt; 648318334Speter 648418334Speter /* Try to find a constant somewhere and record it in `src_const'. 648518334Speter Record its table element, if any, in `src_const_elt'. Look in 648618334Speter any known equivalences first. (If the constant is not in the 648718334Speter table, also set `sets[i].src_const_hash'). */ 648818334Speter if (elt) 648918334Speter for (p = elt->first_same_value; p; p = p->next_same_value) 649018334Speter if (p->is_const) 649118334Speter { 649218334Speter src_const = p->exp; 649318334Speter src_const_elt = elt; 649418334Speter break; 649518334Speter } 649618334Speter 649718334Speter if (src_const == 0 649818334Speter && (CONSTANT_P (src_folded) 649918334Speter /* Consider (minus (label_ref L1) (label_ref L2)) as 650018334Speter "constant" here so we will record it. This allows us 650118334Speter to fold switch statements when an ADDR_DIFF_VEC is used. */ 650218334Speter || (GET_CODE (src_folded) == MINUS 650318334Speter && GET_CODE (XEXP (src_folded, 0)) == LABEL_REF 650418334Speter && GET_CODE (XEXP (src_folded, 1)) == LABEL_REF))) 650518334Speter src_const = src_folded, src_const_elt = elt; 650618334Speter else if (src_const == 0 && src_eqv_here && CONSTANT_P (src_eqv_here)) 650718334Speter src_const = src_eqv_here, src_const_elt = src_eqv_elt; 650818334Speter 650918334Speter /* If we don't know if the constant is in the table, get its 651018334Speter hash code and look it up. */ 651118334Speter if (src_const && src_const_elt == 0) 651218334Speter { 651318334Speter sets[i].src_const_hash = HASH (src_const, mode); 651418334Speter src_const_elt = lookup (src_const, sets[i].src_const_hash, mode); 651518334Speter } 651618334Speter 651718334Speter sets[i].src_const = src_const; 651818334Speter sets[i].src_const_elt = src_const_elt; 651918334Speter 652018334Speter /* If the constant and our source are both in the table, mark them as 652118334Speter equivalent. Otherwise, if a constant is in the table but the source 652218334Speter isn't, set ELT to it. */ 652318334Speter if (src_const_elt && elt 652418334Speter && src_const_elt->first_same_value != elt->first_same_value) 652518334Speter merge_equiv_classes (elt, src_const_elt); 652618334Speter else if (src_const_elt && elt == 0) 652718334Speter elt = src_const_elt; 652818334Speter 652918334Speter /* See if there is a register linearly related to a constant 653018334Speter equivalent of SRC. */ 653118334Speter if (src_const 653218334Speter && (GET_CODE (src_const) == CONST 653318334Speter || (src_const_elt && src_const_elt->related_value != 0))) 653418334Speter { 653518334Speter src_related = use_related_value (src_const, src_const_elt); 653618334Speter if (src_related) 653718334Speter { 653818334Speter struct table_elt *src_related_elt 653918334Speter = lookup (src_related, HASH (src_related, mode), mode); 654018334Speter if (src_related_elt && elt) 654118334Speter { 654218334Speter if (elt->first_same_value 654318334Speter != src_related_elt->first_same_value) 654418334Speter /* This can occur when we previously saw a CONST 654518334Speter involving a SYMBOL_REF and then see the SYMBOL_REF 654618334Speter twice. Merge the involved classes. */ 654718334Speter merge_equiv_classes (elt, src_related_elt); 654818334Speter 654918334Speter src_related = 0; 655018334Speter src_related_elt = 0; 655118334Speter } 655218334Speter else if (src_related_elt && elt == 0) 655318334Speter elt = src_related_elt; 655418334Speter } 655518334Speter } 655618334Speter 655718334Speter /* See if we have a CONST_INT that is already in a register in a 655818334Speter wider mode. */ 655918334Speter 656018334Speter if (src_const && src_related == 0 && GET_CODE (src_const) == CONST_INT 656118334Speter && GET_MODE_CLASS (mode) == MODE_INT 656218334Speter && GET_MODE_BITSIZE (mode) < BITS_PER_WORD) 656318334Speter { 656418334Speter enum machine_mode wider_mode; 656518334Speter 656618334Speter for (wider_mode = GET_MODE_WIDER_MODE (mode); 656718334Speter GET_MODE_BITSIZE (wider_mode) <= BITS_PER_WORD 656818334Speter && src_related == 0; 656918334Speter wider_mode = GET_MODE_WIDER_MODE (wider_mode)) 657018334Speter { 657118334Speter struct table_elt *const_elt 657218334Speter = lookup (src_const, HASH (src_const, wider_mode), wider_mode); 657318334Speter 657418334Speter if (const_elt == 0) 657518334Speter continue; 657618334Speter 657718334Speter for (const_elt = const_elt->first_same_value; 657818334Speter const_elt; const_elt = const_elt->next_same_value) 657918334Speter if (GET_CODE (const_elt->exp) == REG) 658018334Speter { 658118334Speter src_related = gen_lowpart_if_possible (mode, 658218334Speter const_elt->exp); 658318334Speter break; 658418334Speter } 658518334Speter } 658618334Speter } 658718334Speter 658818334Speter /* Another possibility is that we have an AND with a constant in 658918334Speter a mode narrower than a word. If so, it might have been generated 659018334Speter as part of an "if" which would narrow the AND. If we already 659118334Speter have done the AND in a wider mode, we can use a SUBREG of that 659218334Speter value. */ 659318334Speter 659418334Speter if (flag_expensive_optimizations && ! src_related 659518334Speter && GET_CODE (src) == AND && GET_CODE (XEXP (src, 1)) == CONST_INT 659618334Speter && GET_MODE_SIZE (mode) < UNITS_PER_WORD) 659718334Speter { 659818334Speter enum machine_mode tmode; 659918334Speter rtx new_and = gen_rtx (AND, VOIDmode, NULL_RTX, XEXP (src, 1)); 660018334Speter 660118334Speter for (tmode = GET_MODE_WIDER_MODE (mode); 660218334Speter GET_MODE_SIZE (tmode) <= UNITS_PER_WORD; 660318334Speter tmode = GET_MODE_WIDER_MODE (tmode)) 660418334Speter { 660518334Speter rtx inner = gen_lowpart_if_possible (tmode, XEXP (src, 0)); 660618334Speter struct table_elt *larger_elt; 660718334Speter 660818334Speter if (inner) 660918334Speter { 661018334Speter PUT_MODE (new_and, tmode); 661118334Speter XEXP (new_and, 0) = inner; 661218334Speter larger_elt = lookup (new_and, HASH (new_and, tmode), tmode); 661318334Speter if (larger_elt == 0) 661418334Speter continue; 661518334Speter 661618334Speter for (larger_elt = larger_elt->first_same_value; 661718334Speter larger_elt; larger_elt = larger_elt->next_same_value) 661818334Speter if (GET_CODE (larger_elt->exp) == REG) 661918334Speter { 662018334Speter src_related 662118334Speter = gen_lowpart_if_possible (mode, larger_elt->exp); 662218334Speter break; 662318334Speter } 662418334Speter 662518334Speter if (src_related) 662618334Speter break; 662718334Speter } 662818334Speter } 662918334Speter } 663018334Speter 663118334Speter#ifdef LOAD_EXTEND_OP 663218334Speter /* See if a MEM has already been loaded with a widening operation; 663318334Speter if it has, we can use a subreg of that. Many CISC machines 663418334Speter also have such operations, but this is only likely to be 663518334Speter beneficial these machines. */ 663618334Speter 663718334Speter if (flag_expensive_optimizations && src_related == 0 663818334Speter && (GET_MODE_SIZE (mode) < UNITS_PER_WORD) 663918334Speter && GET_MODE_CLASS (mode) == MODE_INT 664018334Speter && GET_CODE (src) == MEM && ! do_not_record 664118334Speter && LOAD_EXTEND_OP (mode) != NIL) 664218334Speter { 664318334Speter enum machine_mode tmode; 664418334Speter 664518334Speter /* Set what we are trying to extend and the operation it might 664618334Speter have been extended with. */ 664718334Speter PUT_CODE (memory_extend_rtx, LOAD_EXTEND_OP (mode)); 664818334Speter XEXP (memory_extend_rtx, 0) = src; 664918334Speter 665018334Speter for (tmode = GET_MODE_WIDER_MODE (mode); 665118334Speter GET_MODE_SIZE (tmode) <= UNITS_PER_WORD; 665218334Speter tmode = GET_MODE_WIDER_MODE (tmode)) 665318334Speter { 665418334Speter struct table_elt *larger_elt; 665518334Speter 665618334Speter PUT_MODE (memory_extend_rtx, tmode); 665718334Speter larger_elt = lookup (memory_extend_rtx, 665818334Speter HASH (memory_extend_rtx, tmode), tmode); 665918334Speter if (larger_elt == 0) 666018334Speter continue; 666118334Speter 666218334Speter for (larger_elt = larger_elt->first_same_value; 666318334Speter larger_elt; larger_elt = larger_elt->next_same_value) 666418334Speter if (GET_CODE (larger_elt->exp) == REG) 666518334Speter { 666618334Speter src_related = gen_lowpart_if_possible (mode, 666718334Speter larger_elt->exp); 666818334Speter break; 666918334Speter } 667018334Speter 667118334Speter if (src_related) 667218334Speter break; 667318334Speter } 667418334Speter } 667518334Speter#endif /* LOAD_EXTEND_OP */ 667618334Speter 667718334Speter if (src == src_folded) 667818334Speter src_folded = 0; 667918334Speter 668018334Speter /* At this point, ELT, if non-zero, points to a class of expressions 668118334Speter equivalent to the source of this SET and SRC, SRC_EQV, SRC_FOLDED, 668218334Speter and SRC_RELATED, if non-zero, each contain additional equivalent 668318334Speter expressions. Prune these latter expressions by deleting expressions 668418334Speter already in the equivalence class. 668518334Speter 668618334Speter Check for an equivalent identical to the destination. If found, 668718334Speter this is the preferred equivalent since it will likely lead to 668818334Speter elimination of the insn. Indicate this by placing it in 668918334Speter `src_related'. */ 669018334Speter 669118334Speter if (elt) elt = elt->first_same_value; 669218334Speter for (p = elt; p; p = p->next_same_value) 669318334Speter { 669418334Speter enum rtx_code code = GET_CODE (p->exp); 669518334Speter 669618334Speter /* If the expression is not valid, ignore it. Then we do not 669718334Speter have to check for validity below. In most cases, we can use 669818334Speter `rtx_equal_p', since canonicalization has already been done. */ 669918334Speter if (code != REG && ! exp_equiv_p (p->exp, p->exp, 1, 0)) 670018334Speter continue; 670118334Speter 670218334Speter if (src && GET_CODE (src) == code && rtx_equal_p (src, p->exp)) 670318334Speter src = 0; 670418334Speter else if (src_folded && GET_CODE (src_folded) == code 670518334Speter && rtx_equal_p (src_folded, p->exp)) 670618334Speter src_folded = 0; 670718334Speter else if (src_eqv_here && GET_CODE (src_eqv_here) == code 670818334Speter && rtx_equal_p (src_eqv_here, p->exp)) 670918334Speter src_eqv_here = 0; 671018334Speter else if (src_related && GET_CODE (src_related) == code 671118334Speter && rtx_equal_p (src_related, p->exp)) 671218334Speter src_related = 0; 671318334Speter 671418334Speter /* This is the same as the destination of the insns, we want 671518334Speter to prefer it. Copy it to src_related. The code below will 671618334Speter then give it a negative cost. */ 671718334Speter if (GET_CODE (dest) == code && rtx_equal_p (p->exp, dest)) 671818334Speter src_related = dest; 671918334Speter 672018334Speter } 672118334Speter 672218334Speter /* Find the cheapest valid equivalent, trying all the available 672318334Speter possibilities. Prefer items not in the hash table to ones 672418334Speter that are when they are equal cost. Note that we can never 672518334Speter worsen an insn as the current contents will also succeed. 672618334Speter If we find an equivalent identical to the destination, use it as best, 672718334Speter since this insn will probably be eliminated in that case. */ 672818334Speter if (src) 672918334Speter { 673018334Speter if (rtx_equal_p (src, dest)) 673118334Speter src_cost = -1; 673218334Speter else 673318334Speter src_cost = COST (src); 673418334Speter } 673518334Speter 673618334Speter if (src_eqv_here) 673718334Speter { 673818334Speter if (rtx_equal_p (src_eqv_here, dest)) 673918334Speter src_eqv_cost = -1; 674018334Speter else 674118334Speter src_eqv_cost = COST (src_eqv_here); 674218334Speter } 674318334Speter 674418334Speter if (src_folded) 674518334Speter { 674618334Speter if (rtx_equal_p (src_folded, dest)) 674718334Speter src_folded_cost = -1; 674818334Speter else 674918334Speter src_folded_cost = COST (src_folded); 675018334Speter } 675118334Speter 675218334Speter if (src_related) 675318334Speter { 675418334Speter if (rtx_equal_p (src_related, dest)) 675518334Speter src_related_cost = -1; 675618334Speter else 675718334Speter src_related_cost = COST (src_related); 675818334Speter } 675918334Speter 676018334Speter /* If this was an indirect jump insn, a known label will really be 676118334Speter cheaper even though it looks more expensive. */ 676218334Speter if (dest == pc_rtx && src_const && GET_CODE (src_const) == LABEL_REF) 676318334Speter src_folded = src_const, src_folded_cost = -1; 676418334Speter 676518334Speter /* Terminate loop when replacement made. This must terminate since 676618334Speter the current contents will be tested and will always be valid. */ 676718334Speter while (1) 676818334Speter { 676918334Speter rtx trial; 677018334Speter 677118334Speter /* Skip invalid entries. */ 677218334Speter while (elt && GET_CODE (elt->exp) != REG 677318334Speter && ! exp_equiv_p (elt->exp, elt->exp, 1, 0)) 677418334Speter elt = elt->next_same_value; 677518334Speter 677618334Speter if (elt) src_elt_cost = elt->cost; 677718334Speter 677818334Speter /* Find cheapest and skip it for the next time. For items 677918334Speter of equal cost, use this order: 678018334Speter src_folded, src, src_eqv, src_related and hash table entry. */ 678118334Speter if (src_folded_cost <= src_cost 678218334Speter && src_folded_cost <= src_eqv_cost 678318334Speter && src_folded_cost <= src_related_cost 678418334Speter && src_folded_cost <= src_elt_cost) 678518334Speter { 678618334Speter trial = src_folded, src_folded_cost = 10000; 678718334Speter if (src_folded_force_flag) 678818334Speter trial = force_const_mem (mode, trial); 678918334Speter } 679018334Speter else if (src_cost <= src_eqv_cost 679118334Speter && src_cost <= src_related_cost 679218334Speter && src_cost <= src_elt_cost) 679318334Speter trial = src, src_cost = 10000; 679418334Speter else if (src_eqv_cost <= src_related_cost 679518334Speter && src_eqv_cost <= src_elt_cost) 679618334Speter trial = copy_rtx (src_eqv_here), src_eqv_cost = 10000; 679718334Speter else if (src_related_cost <= src_elt_cost) 679818334Speter trial = copy_rtx (src_related), src_related_cost = 10000; 679918334Speter else 680018334Speter { 680118334Speter trial = copy_rtx (elt->exp); 680218334Speter elt = elt->next_same_value; 680318334Speter src_elt_cost = 10000; 680418334Speter } 680518334Speter 680618334Speter /* We don't normally have an insn matching (set (pc) (pc)), so 680718334Speter check for this separately here. We will delete such an 680818334Speter insn below. 680918334Speter 681018334Speter Tablejump insns contain a USE of the table, so simply replacing 681118334Speter the operand with the constant won't match. This is simply an 681218334Speter unconditional branch, however, and is therefore valid. Just 681318334Speter insert the substitution here and we will delete and re-emit 681418334Speter the insn later. */ 681518334Speter 681618334Speter if (n_sets == 1 && dest == pc_rtx 681718334Speter && (trial == pc_rtx 681818334Speter || (GET_CODE (trial) == LABEL_REF 681918334Speter && ! condjump_p (insn)))) 682018334Speter { 682118334Speter /* If TRIAL is a label in front of a jump table, we are 682218334Speter really falling through the switch (this is how casesi 682318334Speter insns work), so we must branch around the table. */ 682418334Speter if (GET_CODE (trial) == CODE_LABEL 682518334Speter && NEXT_INSN (trial) != 0 682618334Speter && GET_CODE (NEXT_INSN (trial)) == JUMP_INSN 682718334Speter && (GET_CODE (PATTERN (NEXT_INSN (trial))) == ADDR_DIFF_VEC 682818334Speter || GET_CODE (PATTERN (NEXT_INSN (trial))) == ADDR_VEC)) 682918334Speter 683018334Speter trial = gen_rtx (LABEL_REF, Pmode, get_label_after (trial)); 683118334Speter 683218334Speter SET_SRC (sets[i].rtl) = trial; 683318334Speter cse_jumps_altered = 1; 683418334Speter break; 683518334Speter } 683618334Speter 683718334Speter /* Look for a substitution that makes a valid insn. */ 683818334Speter else if (validate_change (insn, &SET_SRC (sets[i].rtl), trial, 0)) 683918334Speter { 684018334Speter /* The result of apply_change_group can be ignored; see 684118334Speter canon_reg. */ 684218334Speter 684318334Speter validate_change (insn, &SET_SRC (sets[i].rtl), 684418334Speter canon_reg (SET_SRC (sets[i].rtl), insn), 684518334Speter 1); 684618334Speter apply_change_group (); 684718334Speter break; 684818334Speter } 684918334Speter 685018334Speter /* If we previously found constant pool entries for 685118334Speter constants and this is a constant, try making a 685218334Speter pool entry. Put it in src_folded unless we already have done 685318334Speter this since that is where it likely came from. */ 685418334Speter 685518334Speter else if (constant_pool_entries_cost 685618334Speter && CONSTANT_P (trial) 685718334Speter && ! (GET_CODE (trial) == CONST 685818334Speter && GET_CODE (XEXP (trial, 0)) == TRUNCATE) 685918334Speter && (src_folded == 0 686018334Speter || (GET_CODE (src_folded) != MEM 686118334Speter && ! src_folded_force_flag)) 686218334Speter && GET_MODE_CLASS (mode) != MODE_CC) 686318334Speter { 686418334Speter src_folded_force_flag = 1; 686518334Speter src_folded = trial; 686618334Speter src_folded_cost = constant_pool_entries_cost; 686718334Speter } 686818334Speter } 686918334Speter 687018334Speter src = SET_SRC (sets[i].rtl); 687118334Speter 687218334Speter /* In general, it is good to have a SET with SET_SRC == SET_DEST. 687318334Speter However, there is an important exception: If both are registers 687418334Speter that are not the head of their equivalence class, replace SET_SRC 687518334Speter with the head of the class. If we do not do this, we will have 687618334Speter both registers live over a portion of the basic block. This way, 687718334Speter their lifetimes will likely abut instead of overlapping. */ 687818334Speter if (GET_CODE (dest) == REG 687918334Speter && REGNO_QTY_VALID_P (REGNO (dest)) 688018334Speter && qty_mode[reg_qty[REGNO (dest)]] == GET_MODE (dest) 688118334Speter && qty_first_reg[reg_qty[REGNO (dest)]] != REGNO (dest) 688218334Speter && GET_CODE (src) == REG && REGNO (src) == REGNO (dest) 688318334Speter /* Don't do this if the original insn had a hard reg as 688418334Speter SET_SRC. */ 688518334Speter && (GET_CODE (sets[i].src) != REG 688618334Speter || REGNO (sets[i].src) >= FIRST_PSEUDO_REGISTER)) 688718334Speter /* We can't call canon_reg here because it won't do anything if 688818334Speter SRC is a hard register. */ 688918334Speter { 689018334Speter int first = qty_first_reg[reg_qty[REGNO (src)]]; 689118334Speter 689218334Speter src = SET_SRC (sets[i].rtl) 689318334Speter = first >= FIRST_PSEUDO_REGISTER ? regno_reg_rtx[first] 689418334Speter : gen_rtx (REG, GET_MODE (src), first); 689518334Speter 689618334Speter /* If we had a constant that is cheaper than what we are now 689718334Speter setting SRC to, use that constant. We ignored it when we 689818334Speter thought we could make this into a no-op. */ 689918334Speter if (src_const && COST (src_const) < COST (src) 690018334Speter && validate_change (insn, &SET_SRC (sets[i].rtl), src_const, 0)) 690118334Speter src = src_const; 690218334Speter } 690318334Speter 690418334Speter /* If we made a change, recompute SRC values. */ 690518334Speter if (src != sets[i].src) 690618334Speter { 690718334Speter do_not_record = 0; 690818334Speter hash_arg_in_memory = 0; 690918334Speter hash_arg_in_struct = 0; 691018334Speter sets[i].src = src; 691118334Speter sets[i].src_hash = HASH (src, mode); 691218334Speter sets[i].src_volatile = do_not_record; 691318334Speter sets[i].src_in_memory = hash_arg_in_memory; 691418334Speter sets[i].src_in_struct = hash_arg_in_struct; 691518334Speter sets[i].src_elt = lookup (src, sets[i].src_hash, mode); 691618334Speter } 691718334Speter 691818334Speter /* If this is a single SET, we are setting a register, and we have an 691918334Speter equivalent constant, we want to add a REG_NOTE. We don't want 692018334Speter to write a REG_EQUAL note for a constant pseudo since verifying that 692118334Speter that pseudo hasn't been eliminated is a pain. Such a note also 692218334Speter won't help anything. */ 692318334Speter if (n_sets == 1 && src_const && GET_CODE (dest) == REG 692418334Speter && GET_CODE (src_const) != REG) 692518334Speter { 692618334Speter tem = find_reg_note (insn, REG_EQUAL, NULL_RTX); 692718334Speter 692818334Speter /* Record the actual constant value in a REG_EQUAL note, making 692918334Speter a new one if one does not already exist. */ 693018334Speter if (tem) 693118334Speter XEXP (tem, 0) = src_const; 693218334Speter else 693318334Speter REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, 693418334Speter src_const, REG_NOTES (insn)); 693518334Speter 693618334Speter /* If storing a constant value in a register that 693718334Speter previously held the constant value 0, 693818334Speter record this fact with a REG_WAS_0 note on this insn. 693918334Speter 694018334Speter Note that the *register* is required to have previously held 0, 694118334Speter not just any register in the quantity and we must point to the 694218334Speter insn that set that register to zero. 694318334Speter 694418334Speter Rather than track each register individually, we just see if 694518334Speter the last set for this quantity was for this register. */ 694618334Speter 694718334Speter if (REGNO_QTY_VALID_P (REGNO (dest)) 694818334Speter && qty_const[reg_qty[REGNO (dest)]] == const0_rtx) 694918334Speter { 695018334Speter /* See if we previously had a REG_WAS_0 note. */ 695118334Speter rtx note = find_reg_note (insn, REG_WAS_0, NULL_RTX); 695218334Speter rtx const_insn = qty_const_insn[reg_qty[REGNO (dest)]]; 695318334Speter 695418334Speter if ((tem = single_set (const_insn)) != 0 695518334Speter && rtx_equal_p (SET_DEST (tem), dest)) 695618334Speter { 695718334Speter if (note) 695818334Speter XEXP (note, 0) = const_insn; 695918334Speter else 696018334Speter REG_NOTES (insn) = gen_rtx (INSN_LIST, REG_WAS_0, 696118334Speter const_insn, REG_NOTES (insn)); 696218334Speter } 696318334Speter } 696418334Speter } 696518334Speter 696618334Speter /* Now deal with the destination. */ 696718334Speter do_not_record = 0; 696818334Speter sets[i].inner_dest_loc = &SET_DEST (sets[0].rtl); 696918334Speter 697018334Speter /* Look within any SIGN_EXTRACT or ZERO_EXTRACT 697118334Speter to the MEM or REG within it. */ 697218334Speter while (GET_CODE (dest) == SIGN_EXTRACT 697318334Speter || GET_CODE (dest) == ZERO_EXTRACT 697418334Speter || GET_CODE (dest) == SUBREG 697518334Speter || GET_CODE (dest) == STRICT_LOW_PART) 697618334Speter { 697718334Speter sets[i].inner_dest_loc = &XEXP (dest, 0); 697818334Speter dest = XEXP (dest, 0); 697918334Speter } 698018334Speter 698118334Speter sets[i].inner_dest = dest; 698218334Speter 698318334Speter if (GET_CODE (dest) == MEM) 698418334Speter { 698518334Speter dest = fold_rtx (dest, insn); 698618334Speter 698718334Speter /* Decide whether we invalidate everything in memory, 698818334Speter or just things at non-fixed places. 698918334Speter Writing a large aggregate must invalidate everything 699018334Speter because we don't know how long it is. */ 699118334Speter note_mem_written (dest, &writes_memory); 699218334Speter } 699318334Speter 699418334Speter /* Compute the hash code of the destination now, 699518334Speter before the effects of this instruction are recorded, 699618334Speter since the register values used in the address computation 699718334Speter are those before this instruction. */ 699818334Speter sets[i].dest_hash = HASH (dest, mode); 699918334Speter 700018334Speter /* Don't enter a bit-field in the hash table 700118334Speter because the value in it after the store 700218334Speter may not equal what was stored, due to truncation. */ 700318334Speter 700418334Speter if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT 700518334Speter || GET_CODE (SET_DEST (sets[i].rtl)) == SIGN_EXTRACT) 700618334Speter { 700718334Speter rtx width = XEXP (SET_DEST (sets[i].rtl), 1); 700818334Speter 700918334Speter if (src_const != 0 && GET_CODE (src_const) == CONST_INT 701018334Speter && GET_CODE (width) == CONST_INT 701118334Speter && INTVAL (width) < HOST_BITS_PER_WIDE_INT 701218334Speter && ! (INTVAL (src_const) 701318334Speter & ((HOST_WIDE_INT) (-1) << INTVAL (width)))) 701418334Speter /* Exception: if the value is constant, 701518334Speter and it won't be truncated, record it. */ 701618334Speter ; 701718334Speter else 701818334Speter { 701918334Speter /* This is chosen so that the destination will be invalidated 702018334Speter but no new value will be recorded. 702118334Speter We must invalidate because sometimes constant 702218334Speter values can be recorded for bitfields. */ 702318334Speter sets[i].src_elt = 0; 702418334Speter sets[i].src_volatile = 1; 702518334Speter src_eqv = 0; 702618334Speter src_eqv_elt = 0; 702718334Speter } 702818334Speter } 702918334Speter 703018334Speter /* If only one set in a JUMP_INSN and it is now a no-op, we can delete 703118334Speter the insn. */ 703218334Speter else if (n_sets == 1 && dest == pc_rtx && src == pc_rtx) 703318334Speter { 703418334Speter PUT_CODE (insn, NOTE); 703518334Speter NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; 703618334Speter NOTE_SOURCE_FILE (insn) = 0; 703718334Speter cse_jumps_altered = 1; 703818334Speter /* One less use of the label this insn used to jump to. */ 703918334Speter --LABEL_NUSES (JUMP_LABEL (insn)); 704018334Speter /* No more processing for this set. */ 704118334Speter sets[i].rtl = 0; 704218334Speter } 704318334Speter 704418334Speter /* If this SET is now setting PC to a label, we know it used to 704518334Speter be a conditional or computed branch. So we see if we can follow 704618334Speter it. If it was a computed branch, delete it and re-emit. */ 704718334Speter else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF) 704818334Speter { 704918334Speter rtx p; 705018334Speter 705118334Speter /* If this is not in the format for a simple branch and 705218334Speter we are the only SET in it, re-emit it. */ 705318334Speter if (! simplejump_p (insn) && n_sets == 1) 705418334Speter { 705518334Speter rtx new = emit_jump_insn_before (gen_jump (XEXP (src, 0)), insn); 705618334Speter JUMP_LABEL (new) = XEXP (src, 0); 705718334Speter LABEL_NUSES (XEXP (src, 0))++; 705818334Speter delete_insn (insn); 705918334Speter insn = new; 706018334Speter } 706118334Speter else 706218334Speter /* Otherwise, force rerecognition, since it probably had 706318334Speter a different pattern before. 706418334Speter This shouldn't really be necessary, since whatever 706518334Speter changed the source value above should have done this. 706618334Speter Until the right place is found, might as well do this here. */ 706718334Speter INSN_CODE (insn) = -1; 706818334Speter 706918334Speter /* Now that we've converted this jump to an unconditional jump, 707018334Speter there is dead code after it. Delete the dead code until we 707118334Speter reach a BARRIER, the end of the function, or a label. Do 707218334Speter not delete NOTEs except for NOTE_INSN_DELETED since later 707318334Speter phases assume these notes are retained. */ 707418334Speter 707518334Speter p = insn; 707618334Speter 707718334Speter while (NEXT_INSN (p) != 0 707818334Speter && GET_CODE (NEXT_INSN (p)) != BARRIER 707918334Speter && GET_CODE (NEXT_INSN (p)) != CODE_LABEL) 708018334Speter { 708118334Speter if (GET_CODE (NEXT_INSN (p)) != NOTE 708218334Speter || NOTE_LINE_NUMBER (NEXT_INSN (p)) == NOTE_INSN_DELETED) 708318334Speter delete_insn (NEXT_INSN (p)); 708418334Speter else 708518334Speter p = NEXT_INSN (p); 708618334Speter } 708718334Speter 708818334Speter /* If we don't have a BARRIER immediately after INSN, put one there. 708918334Speter Much code assumes that there are no NOTEs between a JUMP_INSN and 709018334Speter BARRIER. */ 709118334Speter 709218334Speter if (NEXT_INSN (insn) == 0 709318334Speter || GET_CODE (NEXT_INSN (insn)) != BARRIER) 709418334Speter emit_barrier_before (NEXT_INSN (insn)); 709518334Speter 709618334Speter /* We might have two BARRIERs separated by notes. Delete the second 709718334Speter one if so. */ 709818334Speter 709918334Speter if (p != insn && NEXT_INSN (p) != 0 710018334Speter && GET_CODE (NEXT_INSN (p)) == BARRIER) 710118334Speter delete_insn (NEXT_INSN (p)); 710218334Speter 710318334Speter cse_jumps_altered = 1; 710418334Speter sets[i].rtl = 0; 710518334Speter } 710618334Speter 710718334Speter /* If destination is volatile, invalidate it and then do no further 710818334Speter processing for this assignment. */ 710918334Speter 711018334Speter else if (do_not_record) 711118334Speter { 711218334Speter if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG 711318334Speter || GET_CODE (dest) == MEM) 711418334Speter invalidate (dest, VOIDmode); 711518334Speter else if (GET_CODE (dest) == STRICT_LOW_PART 711618334Speter || GET_CODE (dest) == ZERO_EXTRACT) 711718334Speter invalidate (XEXP (dest, 0), GET_MODE (dest)); 711818334Speter sets[i].rtl = 0; 711918334Speter } 712018334Speter 712118334Speter if (sets[i].rtl != 0 && dest != SET_DEST (sets[i].rtl)) 712218334Speter sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode); 712318334Speter 712418334Speter#ifdef HAVE_cc0 712518334Speter /* If setting CC0, record what it was set to, or a constant, if it 712618334Speter is equivalent to a constant. If it is being set to a floating-point 712718334Speter value, make a COMPARE with the appropriate constant of 0. If we 712818334Speter don't do this, later code can interpret this as a test against 712918334Speter const0_rtx, which can cause problems if we try to put it into an 713018334Speter insn as a floating-point operand. */ 713118334Speter if (dest == cc0_rtx) 713218334Speter { 713318334Speter this_insn_cc0 = src_const && mode != VOIDmode ? src_const : src; 713418334Speter this_insn_cc0_mode = mode; 713518334Speter if (FLOAT_MODE_P (mode)) 713618334Speter this_insn_cc0 = gen_rtx (COMPARE, VOIDmode, this_insn_cc0, 713718334Speter CONST0_RTX (mode)); 713818334Speter } 713918334Speter#endif 714018334Speter } 714118334Speter 714218334Speter /* Now enter all non-volatile source expressions in the hash table 714318334Speter if they are not already present. 714418334Speter Record their equivalence classes in src_elt. 714518334Speter This way we can insert the corresponding destinations into 714618334Speter the same classes even if the actual sources are no longer in them 714718334Speter (having been invalidated). */ 714818334Speter 714918334Speter if (src_eqv && src_eqv_elt == 0 && sets[0].rtl != 0 && ! src_eqv_volatile 715018334Speter && ! rtx_equal_p (src_eqv, SET_DEST (sets[0].rtl))) 715118334Speter { 715218334Speter register struct table_elt *elt; 715318334Speter register struct table_elt *classp = sets[0].src_elt; 715418334Speter rtx dest = SET_DEST (sets[0].rtl); 715518334Speter enum machine_mode eqvmode = GET_MODE (dest); 715618334Speter 715718334Speter if (GET_CODE (dest) == STRICT_LOW_PART) 715818334Speter { 715918334Speter eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0))); 716018334Speter classp = 0; 716118334Speter } 716218334Speter if (insert_regs (src_eqv, classp, 0)) 716318334Speter { 716418334Speter rehash_using_reg (src_eqv); 716518334Speter src_eqv_hash = HASH (src_eqv, eqvmode); 716618334Speter } 716718334Speter elt = insert (src_eqv, classp, src_eqv_hash, eqvmode); 716818334Speter elt->in_memory = src_eqv_in_memory; 716918334Speter elt->in_struct = src_eqv_in_struct; 717018334Speter src_eqv_elt = elt; 717118334Speter 717218334Speter /* Check to see if src_eqv_elt is the same as a set source which 717318334Speter does not yet have an elt, and if so set the elt of the set source 717418334Speter to src_eqv_elt. */ 717518334Speter for (i = 0; i < n_sets; i++) 717618334Speter if (sets[i].rtl && sets[i].src_elt == 0 717718334Speter && rtx_equal_p (SET_SRC (sets[i].rtl), src_eqv)) 717818334Speter sets[i].src_elt = src_eqv_elt; 717918334Speter } 718018334Speter 718118334Speter for (i = 0; i < n_sets; i++) 718218334Speter if (sets[i].rtl && ! sets[i].src_volatile 718318334Speter && ! rtx_equal_p (SET_SRC (sets[i].rtl), SET_DEST (sets[i].rtl))) 718418334Speter { 718518334Speter if (GET_CODE (SET_DEST (sets[i].rtl)) == STRICT_LOW_PART) 718618334Speter { 718718334Speter /* REG_EQUAL in setting a STRICT_LOW_PART 718818334Speter gives an equivalent for the entire destination register, 718918334Speter not just for the subreg being stored in now. 719018334Speter This is a more interesting equivalence, so we arrange later 719118334Speter to treat the entire reg as the destination. */ 719218334Speter sets[i].src_elt = src_eqv_elt; 719318334Speter sets[i].src_hash = src_eqv_hash; 719418334Speter } 719518334Speter else 719618334Speter { 719718334Speter /* Insert source and constant equivalent into hash table, if not 719818334Speter already present. */ 719918334Speter register struct table_elt *classp = src_eqv_elt; 720018334Speter register rtx src = sets[i].src; 720118334Speter register rtx dest = SET_DEST (sets[i].rtl); 720218334Speter enum machine_mode mode 720318334Speter = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src); 720418334Speter 720518334Speter if (sets[i].src_elt == 0) 720618334Speter { 720718334Speter register struct table_elt *elt; 720818334Speter 720918334Speter /* Note that these insert_regs calls cannot remove 721018334Speter any of the src_elt's, because they would have failed to 721118334Speter match if not still valid. */ 721218334Speter if (insert_regs (src, classp, 0)) 721318334Speter { 721418334Speter rehash_using_reg (src); 721518334Speter sets[i].src_hash = HASH (src, mode); 721618334Speter } 721718334Speter elt = insert (src, classp, sets[i].src_hash, mode); 721818334Speter elt->in_memory = sets[i].src_in_memory; 721918334Speter elt->in_struct = sets[i].src_in_struct; 722018334Speter sets[i].src_elt = classp = elt; 722118334Speter } 722218334Speter 722318334Speter if (sets[i].src_const && sets[i].src_const_elt == 0 722418334Speter && src != sets[i].src_const 722518334Speter && ! rtx_equal_p (sets[i].src_const, src)) 722618334Speter sets[i].src_elt = insert (sets[i].src_const, classp, 722718334Speter sets[i].src_const_hash, mode); 722818334Speter } 722918334Speter } 723018334Speter else if (sets[i].src_elt == 0) 723118334Speter /* If we did not insert the source into the hash table (e.g., it was 723218334Speter volatile), note the equivalence class for the REG_EQUAL value, if any, 723318334Speter so that the destination goes into that class. */ 723418334Speter sets[i].src_elt = src_eqv_elt; 723518334Speter 723618334Speter invalidate_from_clobbers (&writes_memory, x); 723718334Speter 723818334Speter /* Some registers are invalidated by subroutine calls. Memory is 723918334Speter invalidated by non-constant calls. */ 724018334Speter 724118334Speter if (GET_CODE (insn) == CALL_INSN) 724218334Speter { 724318334Speter static struct write_data everything = {0, 1, 1, 1}; 724418334Speter 724518334Speter if (! CONST_CALL_P (insn)) 724618334Speter invalidate_memory (&everything); 724718334Speter invalidate_for_call (); 724818334Speter } 724918334Speter 725018334Speter /* Now invalidate everything set by this instruction. 725118334Speter If a SUBREG or other funny destination is being set, 725218334Speter sets[i].rtl is still nonzero, so here we invalidate the reg 725318334Speter a part of which is being set. */ 725418334Speter 725518334Speter for (i = 0; i < n_sets; i++) 725618334Speter if (sets[i].rtl) 725718334Speter { 725818334Speter /* We can't use the inner dest, because the mode associated with 725918334Speter a ZERO_EXTRACT is significant. */ 726018334Speter register rtx dest = SET_DEST (sets[i].rtl); 726118334Speter 726218334Speter /* Needed for registers to remove the register from its 726318334Speter previous quantity's chain. 726418334Speter Needed for memory if this is a nonvarying address, unless 726518334Speter we have just done an invalidate_memory that covers even those. */ 726618334Speter if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG 726718334Speter || (GET_CODE (dest) == MEM && ! writes_memory.all 726818334Speter && ! cse_rtx_addr_varies_p (dest))) 726918334Speter invalidate (dest, VOIDmode); 727018334Speter else if (GET_CODE (dest) == STRICT_LOW_PART 727118334Speter || GET_CODE (dest) == ZERO_EXTRACT) 727218334Speter invalidate (XEXP (dest, 0), GET_MODE (dest)); 727318334Speter } 727418334Speter 727518334Speter /* Make sure registers mentioned in destinations 727618334Speter are safe for use in an expression to be inserted. 727718334Speter This removes from the hash table 727818334Speter any invalid entry that refers to one of these registers. 727918334Speter 728018334Speter We don't care about the return value from mention_regs because 728118334Speter we are going to hash the SET_DEST values unconditionally. */ 728218334Speter 728318334Speter for (i = 0; i < n_sets; i++) 728418334Speter if (sets[i].rtl && GET_CODE (SET_DEST (sets[i].rtl)) != REG) 728518334Speter mention_regs (SET_DEST (sets[i].rtl)); 728618334Speter 728718334Speter /* We may have just removed some of the src_elt's from the hash table. 728818334Speter So replace each one with the current head of the same class. */ 728918334Speter 729018334Speter for (i = 0; i < n_sets; i++) 729118334Speter if (sets[i].rtl) 729218334Speter { 729318334Speter if (sets[i].src_elt && sets[i].src_elt->first_same_value == 0) 729418334Speter /* If elt was removed, find current head of same class, 729518334Speter or 0 if nothing remains of that class. */ 729618334Speter { 729718334Speter register struct table_elt *elt = sets[i].src_elt; 729818334Speter 729918334Speter while (elt && elt->prev_same_value) 730018334Speter elt = elt->prev_same_value; 730118334Speter 730218334Speter while (elt && elt->first_same_value == 0) 730318334Speter elt = elt->next_same_value; 730418334Speter sets[i].src_elt = elt ? elt->first_same_value : 0; 730518334Speter } 730618334Speter } 730718334Speter 730818334Speter /* Now insert the destinations into their equivalence classes. */ 730918334Speter 731018334Speter for (i = 0; i < n_sets; i++) 731118334Speter if (sets[i].rtl) 731218334Speter { 731318334Speter register rtx dest = SET_DEST (sets[i].rtl); 731418334Speter register struct table_elt *elt; 731518334Speter 731618334Speter /* Don't record value if we are not supposed to risk allocating 731718334Speter floating-point values in registers that might be wider than 731818334Speter memory. */ 731918334Speter if ((flag_float_store 732018334Speter && GET_CODE (dest) == MEM 732118334Speter && FLOAT_MODE_P (GET_MODE (dest))) 732218334Speter /* Don't record values of destinations set inside a libcall block 732318334Speter since we might delete the libcall. Things should have been set 732418334Speter up so we won't want to reuse such a value, but we play it safe 732518334Speter here. */ 732618334Speter || in_libcall_block 732718334Speter /* If we didn't put a REG_EQUAL value or a source into the hash 732818334Speter table, there is no point is recording DEST. */ 732918334Speter || sets[i].src_elt == 0 733018334Speter /* If DEST is a paradoxical SUBREG and SRC is a ZERO_EXTEND 733118334Speter or SIGN_EXTEND, don't record DEST since it can cause 733218334Speter some tracking to be wrong. 733318334Speter 733418334Speter ??? Think about this more later. */ 733518334Speter || (GET_CODE (dest) == SUBREG 733618334Speter && (GET_MODE_SIZE (GET_MODE (dest)) 733718334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))) 733818334Speter && (GET_CODE (sets[i].src) == SIGN_EXTEND 733918334Speter || GET_CODE (sets[i].src) == ZERO_EXTEND))) 734018334Speter continue; 734118334Speter 734218334Speter /* STRICT_LOW_PART isn't part of the value BEING set, 734318334Speter and neither is the SUBREG inside it. 734418334Speter Note that in this case SETS[I].SRC_ELT is really SRC_EQV_ELT. */ 734518334Speter if (GET_CODE (dest) == STRICT_LOW_PART) 734618334Speter dest = SUBREG_REG (XEXP (dest, 0)); 734718334Speter 734818334Speter if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG) 734918334Speter /* Registers must also be inserted into chains for quantities. */ 735018334Speter if (insert_regs (dest, sets[i].src_elt, 1)) 735118334Speter { 735218334Speter /* If `insert_regs' changes something, the hash code must be 735318334Speter recalculated. */ 735418334Speter rehash_using_reg (dest); 735518334Speter sets[i].dest_hash = HASH (dest, GET_MODE (dest)); 735618334Speter } 735718334Speter 735818334Speter elt = insert (dest, sets[i].src_elt, 735918334Speter sets[i].dest_hash, GET_MODE (dest)); 736018334Speter elt->in_memory = (GET_CODE (sets[i].inner_dest) == MEM 736118334Speter && ! RTX_UNCHANGING_P (sets[i].inner_dest)); 736218334Speter 736318334Speter if (elt->in_memory) 736418334Speter { 736518334Speter /* This implicitly assumes a whole struct 736618334Speter need not have MEM_IN_STRUCT_P. 736718334Speter But a whole struct is *supposed* to have MEM_IN_STRUCT_P. */ 736818334Speter elt->in_struct = (MEM_IN_STRUCT_P (sets[i].inner_dest) 736918334Speter || sets[i].inner_dest != SET_DEST (sets[i].rtl)); 737018334Speter } 737118334Speter 737218334Speter /* If we have (set (subreg:m1 (reg:m2 foo) 0) (bar:m1)), M1 is no 737318334Speter narrower than M2, and both M1 and M2 are the same number of words, 737418334Speter we are also doing (set (reg:m2 foo) (subreg:m2 (bar:m1) 0)) so 737518334Speter make that equivalence as well. 737618334Speter 737718334Speter However, BAR may have equivalences for which gen_lowpart_if_possible 737818334Speter will produce a simpler value than gen_lowpart_if_possible applied to 737918334Speter BAR (e.g., if BAR was ZERO_EXTENDed from M2), so we will scan all 738018334Speter BAR's equivalences. If we don't get a simplified form, make 738118334Speter the SUBREG. It will not be used in an equivalence, but will 738218334Speter cause two similar assignments to be detected. 738318334Speter 738418334Speter Note the loop below will find SUBREG_REG (DEST) since we have 738518334Speter already entered SRC and DEST of the SET in the table. */ 738618334Speter 738718334Speter if (GET_CODE (dest) == SUBREG 738818334Speter && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) - 1) 738918334Speter / UNITS_PER_WORD) 739018334Speter == (GET_MODE_SIZE (GET_MODE (dest)) - 1)/ UNITS_PER_WORD) 739118334Speter && (GET_MODE_SIZE (GET_MODE (dest)) 739218334Speter >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))) 739318334Speter && sets[i].src_elt != 0) 739418334Speter { 739518334Speter enum machine_mode new_mode = GET_MODE (SUBREG_REG (dest)); 739618334Speter struct table_elt *elt, *classp = 0; 739718334Speter 739818334Speter for (elt = sets[i].src_elt->first_same_value; elt; 739918334Speter elt = elt->next_same_value) 740018334Speter { 740118334Speter rtx new_src = 0; 740218334Speter unsigned src_hash; 740318334Speter struct table_elt *src_elt; 740418334Speter 740518334Speter /* Ignore invalid entries. */ 740618334Speter if (GET_CODE (elt->exp) != REG 740718334Speter && ! exp_equiv_p (elt->exp, elt->exp, 1, 0)) 740818334Speter continue; 740918334Speter 741018334Speter new_src = gen_lowpart_if_possible (new_mode, elt->exp); 741118334Speter if (new_src == 0) 741218334Speter new_src = gen_rtx (SUBREG, new_mode, elt->exp, 0); 741318334Speter 741418334Speter src_hash = HASH (new_src, new_mode); 741518334Speter src_elt = lookup (new_src, src_hash, new_mode); 741618334Speter 741718334Speter /* Put the new source in the hash table is if isn't 741818334Speter already. */ 741918334Speter if (src_elt == 0) 742018334Speter { 742118334Speter if (insert_regs (new_src, classp, 0)) 742218334Speter { 742318334Speter rehash_using_reg (new_src); 742418334Speter src_hash = HASH (new_src, new_mode); 742518334Speter } 742618334Speter src_elt = insert (new_src, classp, src_hash, new_mode); 742718334Speter src_elt->in_memory = elt->in_memory; 742818334Speter src_elt->in_struct = elt->in_struct; 742918334Speter } 743018334Speter else if (classp && classp != src_elt->first_same_value) 743118334Speter /* Show that two things that we've seen before are 743218334Speter actually the same. */ 743318334Speter merge_equiv_classes (src_elt, classp); 743418334Speter 743518334Speter classp = src_elt->first_same_value; 743618334Speter } 743718334Speter } 743818334Speter } 743918334Speter 744018334Speter /* Special handling for (set REG0 REG1) 744118334Speter where REG0 is the "cheapest", cheaper than REG1. 744218334Speter After cse, REG1 will probably not be used in the sequel, 744318334Speter so (if easily done) change this insn to (set REG1 REG0) and 744418334Speter replace REG1 with REG0 in the previous insn that computed their value. 744518334Speter Then REG1 will become a dead store and won't cloud the situation 744618334Speter for later optimizations. 744718334Speter 744818334Speter Do not make this change if REG1 is a hard register, because it will 744918334Speter then be used in the sequel and we may be changing a two-operand insn 745018334Speter into a three-operand insn. 745118334Speter 745218334Speter Also do not do this if we are operating on a copy of INSN. */ 745318334Speter 745418334Speter if (n_sets == 1 && sets[0].rtl && GET_CODE (SET_DEST (sets[0].rtl)) == REG 745518334Speter && NEXT_INSN (PREV_INSN (insn)) == insn 745618334Speter && GET_CODE (SET_SRC (sets[0].rtl)) == REG 745718334Speter && REGNO (SET_SRC (sets[0].rtl)) >= FIRST_PSEUDO_REGISTER 745818334Speter && REGNO_QTY_VALID_P (REGNO (SET_SRC (sets[0].rtl))) 745918334Speter && (qty_first_reg[reg_qty[REGNO (SET_SRC (sets[0].rtl))]] 746018334Speter == REGNO (SET_DEST (sets[0].rtl)))) 746118334Speter { 746218334Speter rtx prev = PREV_INSN (insn); 746318334Speter while (prev && GET_CODE (prev) == NOTE) 746418334Speter prev = PREV_INSN (prev); 746518334Speter 746618334Speter if (prev && GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SET 746718334Speter && SET_DEST (PATTERN (prev)) == SET_SRC (sets[0].rtl)) 746818334Speter { 746918334Speter rtx dest = SET_DEST (sets[0].rtl); 747018334Speter rtx note = find_reg_note (prev, REG_EQUIV, NULL_RTX); 747118334Speter 747218334Speter validate_change (prev, & SET_DEST (PATTERN (prev)), dest, 1); 747318334Speter validate_change (insn, & SET_DEST (sets[0].rtl), 747418334Speter SET_SRC (sets[0].rtl), 1); 747518334Speter validate_change (insn, & SET_SRC (sets[0].rtl), dest, 1); 747618334Speter apply_change_group (); 747718334Speter 747818334Speter /* If REG1 was equivalent to a constant, REG0 is not. */ 747918334Speter if (note) 748018334Speter PUT_REG_NOTE_KIND (note, REG_EQUAL); 748118334Speter 748218334Speter /* If there was a REG_WAS_0 note on PREV, remove it. Move 748318334Speter any REG_WAS_0 note on INSN to PREV. */ 748418334Speter note = find_reg_note (prev, REG_WAS_0, NULL_RTX); 748518334Speter if (note) 748618334Speter remove_note (prev, note); 748718334Speter 748818334Speter note = find_reg_note (insn, REG_WAS_0, NULL_RTX); 748918334Speter if (note) 749018334Speter { 749118334Speter remove_note (insn, note); 749218334Speter XEXP (note, 1) = REG_NOTES (prev); 749318334Speter REG_NOTES (prev) = note; 749418334Speter } 749518334Speter 749618334Speter /* If INSN has a REG_EQUAL note, and this note mentions REG0, 749718334Speter then we must delete it, because the value in REG0 has changed. */ 749818334Speter note = find_reg_note (insn, REG_EQUAL, NULL_RTX); 749918334Speter if (note && reg_mentioned_p (dest, XEXP (note, 0))) 750018334Speter remove_note (insn, note); 750118334Speter } 750218334Speter } 750318334Speter 750418334Speter /* If this is a conditional jump insn, record any known equivalences due to 750518334Speter the condition being tested. */ 750618334Speter 750718334Speter last_jump_equiv_class = 0; 750818334Speter if (GET_CODE (insn) == JUMP_INSN 750918334Speter && n_sets == 1 && GET_CODE (x) == SET 751018334Speter && GET_CODE (SET_SRC (x)) == IF_THEN_ELSE) 751118334Speter record_jump_equiv (insn, 0); 751218334Speter 751318334Speter#ifdef HAVE_cc0 751418334Speter /* If the previous insn set CC0 and this insn no longer references CC0, 751518334Speter delete the previous insn. Here we use the fact that nothing expects CC0 751618334Speter to be valid over an insn, which is true until the final pass. */ 751718334Speter if (prev_insn && GET_CODE (prev_insn) == INSN 751818334Speter && (tem = single_set (prev_insn)) != 0 751918334Speter && SET_DEST (tem) == cc0_rtx 752018334Speter && ! reg_mentioned_p (cc0_rtx, x)) 752118334Speter { 752218334Speter PUT_CODE (prev_insn, NOTE); 752318334Speter NOTE_LINE_NUMBER (prev_insn) = NOTE_INSN_DELETED; 752418334Speter NOTE_SOURCE_FILE (prev_insn) = 0; 752518334Speter } 752618334Speter 752718334Speter prev_insn_cc0 = this_insn_cc0; 752818334Speter prev_insn_cc0_mode = this_insn_cc0_mode; 752918334Speter#endif 753018334Speter 753118334Speter prev_insn = insn; 753218334Speter} 753318334Speter 753418334Speter/* Store 1 in *WRITES_PTR for those categories of memory ref 753518334Speter that must be invalidated when the expression WRITTEN is stored in. 753618334Speter If WRITTEN is null, say everything must be invalidated. */ 753718334Speter 753818334Speterstatic void 753918334Speternote_mem_written (written, writes_ptr) 754018334Speter rtx written; 754118334Speter struct write_data *writes_ptr; 754218334Speter{ 754318334Speter static struct write_data everything = {0, 1, 1, 1}; 754418334Speter 754518334Speter if (written == 0) 754618334Speter *writes_ptr = everything; 754718334Speter else if (GET_CODE (written) == MEM) 754818334Speter { 754918334Speter /* Pushing or popping the stack invalidates just the stack pointer. */ 755018334Speter rtx addr = XEXP (written, 0); 755118334Speter if ((GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC 755218334Speter || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC) 755318334Speter && GET_CODE (XEXP (addr, 0)) == REG 755418334Speter && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM) 755518334Speter { 755618334Speter writes_ptr->sp = 1; 755718334Speter return; 755818334Speter } 755918334Speter else if (GET_MODE (written) == BLKmode) 756018334Speter *writes_ptr = everything; 756118334Speter /* (mem (scratch)) means clobber everything. */ 756218334Speter else if (GET_CODE (addr) == SCRATCH) 756318334Speter *writes_ptr = everything; 756418334Speter else if (cse_rtx_addr_varies_p (written)) 756518334Speter { 756618334Speter /* A varying address that is a sum indicates an array element, 756718334Speter and that's just as good as a structure element 756818334Speter in implying that we need not invalidate scalar variables. 756918334Speter However, we must allow QImode aliasing of scalars, because the 757018334Speter ANSI C standard allows character pointers to alias anything. */ 757118334Speter if (! ((MEM_IN_STRUCT_P (written) 757218334Speter || GET_CODE (XEXP (written, 0)) == PLUS) 757318334Speter && GET_MODE (written) != QImode)) 757418334Speter writes_ptr->all = 1; 757518334Speter writes_ptr->nonscalar = 1; 757618334Speter } 757718334Speter writes_ptr->var = 1; 757818334Speter } 757918334Speter} 758018334Speter 758118334Speter/* Perform invalidation on the basis of everything about an insn 758218334Speter except for invalidating the actual places that are SET in it. 758318334Speter This includes the places CLOBBERed, and anything that might 758418334Speter alias with something that is SET or CLOBBERed. 758518334Speter 758618334Speter W points to the writes_memory for this insn, a struct write_data 758718334Speter saying which kinds of memory references must be invalidated. 758818334Speter X is the pattern of the insn. */ 758918334Speter 759018334Speterstatic void 759118334Speterinvalidate_from_clobbers (w, x) 759218334Speter struct write_data *w; 759318334Speter rtx x; 759418334Speter{ 759518334Speter /* If W->var is not set, W specifies no action. 759618334Speter If W->all is set, this step gets all memory refs 759718334Speter so they can be ignored in the rest of this function. */ 759818334Speter if (w->var) 759918334Speter invalidate_memory (w); 760018334Speter 760118334Speter if (w->sp) 760218334Speter { 760318334Speter if (reg_tick[STACK_POINTER_REGNUM] >= 0) 760418334Speter reg_tick[STACK_POINTER_REGNUM]++; 760518334Speter 760618334Speter /* This should be *very* rare. */ 760718334Speter if (TEST_HARD_REG_BIT (hard_regs_in_table, STACK_POINTER_REGNUM)) 760818334Speter invalidate (stack_pointer_rtx, VOIDmode); 760918334Speter } 761018334Speter 761118334Speter if (GET_CODE (x) == CLOBBER) 761218334Speter { 761318334Speter rtx ref = XEXP (x, 0); 761418334Speter if (ref) 761518334Speter { 761618334Speter if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG 761718334Speter || (GET_CODE (ref) == MEM && ! w->all)) 761818334Speter invalidate (ref, VOIDmode); 761918334Speter else if (GET_CODE (ref) == STRICT_LOW_PART 762018334Speter || GET_CODE (ref) == ZERO_EXTRACT) 762118334Speter invalidate (XEXP (ref, 0), GET_MODE (ref)); 762218334Speter } 762318334Speter } 762418334Speter else if (GET_CODE (x) == PARALLEL) 762518334Speter { 762618334Speter register int i; 762718334Speter for (i = XVECLEN (x, 0) - 1; i >= 0; i--) 762818334Speter { 762918334Speter register rtx y = XVECEXP (x, 0, i); 763018334Speter if (GET_CODE (y) == CLOBBER) 763118334Speter { 763218334Speter rtx ref = XEXP (y, 0); 763318334Speter if (ref) 763418334Speter { 763518334Speter if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG 763618334Speter || (GET_CODE (ref) == MEM && !w->all)) 763718334Speter invalidate (ref, VOIDmode); 763818334Speter else if (GET_CODE (ref) == STRICT_LOW_PART 763918334Speter || GET_CODE (ref) == ZERO_EXTRACT) 764018334Speter invalidate (XEXP (ref, 0), GET_MODE (ref)); 764118334Speter } 764218334Speter } 764318334Speter } 764418334Speter } 764518334Speter} 764618334Speter 764718334Speter/* Process X, part of the REG_NOTES of an insn. Look at any REG_EQUAL notes 764818334Speter and replace any registers in them with either an equivalent constant 764918334Speter or the canonical form of the register. If we are inside an address, 765018334Speter only do this if the address remains valid. 765118334Speter 765218334Speter OBJECT is 0 except when within a MEM in which case it is the MEM. 765318334Speter 765418334Speter Return the replacement for X. */ 765518334Speter 765618334Speterstatic rtx 765718334Spetercse_process_notes (x, object) 765818334Speter rtx x; 765918334Speter rtx object; 766018334Speter{ 766118334Speter enum rtx_code code = GET_CODE (x); 766218334Speter char *fmt = GET_RTX_FORMAT (code); 766318334Speter int i; 766418334Speter 766518334Speter switch (code) 766618334Speter { 766718334Speter case CONST_INT: 766818334Speter case CONST: 766918334Speter case SYMBOL_REF: 767018334Speter case LABEL_REF: 767118334Speter case CONST_DOUBLE: 767218334Speter case PC: 767318334Speter case CC0: 767418334Speter case LO_SUM: 767518334Speter return x; 767618334Speter 767718334Speter case MEM: 767818334Speter XEXP (x, 0) = cse_process_notes (XEXP (x, 0), x); 767918334Speter return x; 768018334Speter 768118334Speter case EXPR_LIST: 768218334Speter case INSN_LIST: 768318334Speter if (REG_NOTE_KIND (x) == REG_EQUAL) 768418334Speter XEXP (x, 0) = cse_process_notes (XEXP (x, 0), NULL_RTX); 768518334Speter if (XEXP (x, 1)) 768618334Speter XEXP (x, 1) = cse_process_notes (XEXP (x, 1), NULL_RTX); 768718334Speter return x; 768818334Speter 768918334Speter case SIGN_EXTEND: 769018334Speter case ZERO_EXTEND: 769118334Speter { 769218334Speter rtx new = cse_process_notes (XEXP (x, 0), object); 769318334Speter /* We don't substitute VOIDmode constants into these rtx, 769418334Speter since they would impede folding. */ 769518334Speter if (GET_MODE (new) != VOIDmode) 769618334Speter validate_change (object, &XEXP (x, 0), new, 0); 769718334Speter return x; 769818334Speter } 769918334Speter 770018334Speter case REG: 770118334Speter i = reg_qty[REGNO (x)]; 770218334Speter 770318334Speter /* Return a constant or a constant register. */ 770418334Speter if (REGNO_QTY_VALID_P (REGNO (x)) 770518334Speter && qty_const[i] != 0 770618334Speter && (CONSTANT_P (qty_const[i]) 770718334Speter || GET_CODE (qty_const[i]) == REG)) 770818334Speter { 770918334Speter rtx new = gen_lowpart_if_possible (GET_MODE (x), qty_const[i]); 771018334Speter if (new) 771118334Speter return new; 771218334Speter } 771318334Speter 771418334Speter /* Otherwise, canonicalize this register. */ 771518334Speter return canon_reg (x, NULL_RTX); 771618334Speter } 771718334Speter 771818334Speter for (i = 0; i < GET_RTX_LENGTH (code); i++) 771918334Speter if (fmt[i] == 'e') 772018334Speter validate_change (object, &XEXP (x, i), 772118334Speter cse_process_notes (XEXP (x, i), object), 0); 772218334Speter 772318334Speter return x; 772418334Speter} 772518334Speter 772618334Speter/* Find common subexpressions between the end test of a loop and the beginning 772718334Speter of the loop. LOOP_START is the CODE_LABEL at the start of a loop. 772818334Speter 772918334Speter Often we have a loop where an expression in the exit test is used 773018334Speter in the body of the loop. For example "while (*p) *q++ = *p++;". 773118334Speter Because of the way we duplicate the loop exit test in front of the loop, 773218334Speter however, we don't detect that common subexpression. This will be caught 773318334Speter when global cse is implemented, but this is a quite common case. 773418334Speter 773518334Speter This function handles the most common cases of these common expressions. 773618334Speter It is called after we have processed the basic block ending with the 773718334Speter NOTE_INSN_LOOP_END note that ends a loop and the previous JUMP_INSN 773818334Speter jumps to a label used only once. */ 773918334Speter 774018334Speterstatic void 774118334Spetercse_around_loop (loop_start) 774218334Speter rtx loop_start; 774318334Speter{ 774418334Speter rtx insn; 774518334Speter int i; 774618334Speter struct table_elt *p; 774718334Speter 774818334Speter /* If the jump at the end of the loop doesn't go to the start, we don't 774918334Speter do anything. */ 775018334Speter for (insn = PREV_INSN (loop_start); 775118334Speter insn && (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) >= 0); 775218334Speter insn = PREV_INSN (insn)) 775318334Speter ; 775418334Speter 775518334Speter if (insn == 0 775618334Speter || GET_CODE (insn) != NOTE 775718334Speter || NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG) 775818334Speter return; 775918334Speter 776018334Speter /* If the last insn of the loop (the end test) was an NE comparison, 776118334Speter we will interpret it as an EQ comparison, since we fell through 776218334Speter the loop. Any equivalences resulting from that comparison are 776318334Speter therefore not valid and must be invalidated. */ 776418334Speter if (last_jump_equiv_class) 776518334Speter for (p = last_jump_equiv_class->first_same_value; p; 776618334Speter p = p->next_same_value) 776718334Speter if (GET_CODE (p->exp) == MEM || GET_CODE (p->exp) == REG 776818334Speter || (GET_CODE (p->exp) == SUBREG 776918334Speter && GET_CODE (SUBREG_REG (p->exp)) == REG)) 777018334Speter invalidate (p->exp, VOIDmode); 777118334Speter else if (GET_CODE (p->exp) == STRICT_LOW_PART 777218334Speter || GET_CODE (p->exp) == ZERO_EXTRACT) 777318334Speter invalidate (XEXP (p->exp, 0), GET_MODE (p->exp)); 777418334Speter 777518334Speter /* Process insns starting after LOOP_START until we hit a CALL_INSN or 777618334Speter a CODE_LABEL (we could handle a CALL_INSN, but it isn't worth it). 777718334Speter 777818334Speter The only thing we do with SET_DEST is invalidate entries, so we 777918334Speter can safely process each SET in order. It is slightly less efficient 778018334Speter to do so, but we only want to handle the most common cases. */ 778118334Speter 778218334Speter for (insn = NEXT_INSN (loop_start); 778318334Speter GET_CODE (insn) != CALL_INSN && GET_CODE (insn) != CODE_LABEL 778418334Speter && ! (GET_CODE (insn) == NOTE 778518334Speter && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END); 778618334Speter insn = NEXT_INSN (insn)) 778718334Speter { 778818334Speter if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' 778918334Speter && (GET_CODE (PATTERN (insn)) == SET 779018334Speter || GET_CODE (PATTERN (insn)) == CLOBBER)) 779118334Speter cse_set_around_loop (PATTERN (insn), insn, loop_start); 779218334Speter else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' 779318334Speter && GET_CODE (PATTERN (insn)) == PARALLEL) 779418334Speter for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) 779518334Speter if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET 779618334Speter || GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == CLOBBER) 779718334Speter cse_set_around_loop (XVECEXP (PATTERN (insn), 0, i), insn, 779818334Speter loop_start); 779918334Speter } 780018334Speter} 780118334Speter 780218334Speter/* Variable used for communications between the next two routines. */ 780318334Speter 780418334Speterstatic struct write_data skipped_writes_memory; 780518334Speter 780618334Speter/* Process one SET of an insn that was skipped. We ignore CLOBBERs 780718334Speter since they are done elsewhere. This function is called via note_stores. */ 780818334Speter 780918334Speterstatic void 781018334Speterinvalidate_skipped_set (dest, set) 781118334Speter rtx set; 781218334Speter rtx dest; 781318334Speter{ 781418334Speter if (GET_CODE (dest) == MEM) 781518334Speter note_mem_written (dest, &skipped_writes_memory); 781618334Speter 781718334Speter /* There are times when an address can appear varying and be a PLUS 781818334Speter during this scan when it would be a fixed address were we to know 781918334Speter the proper equivalences. So promote "nonscalar" to be "all". */ 782018334Speter if (skipped_writes_memory.nonscalar) 782118334Speter skipped_writes_memory.all = 1; 782218334Speter 782348743Sobrien if (GET_CODE (set) == CLOBBER 782448743Sobrien#ifdef HAVE_cc0 782548743Sobrien || dest == cc0_rtx 782648743Sobrien#endif 782748743Sobrien || dest == pc_rtx) 782848743Sobrien return; 782948743Sobrien 783018334Speter if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG 783118334Speter || (! skipped_writes_memory.all && ! cse_rtx_addr_varies_p (dest))) 783218334Speter invalidate (dest, VOIDmode); 783318334Speter else if (GET_CODE (dest) == STRICT_LOW_PART 783418334Speter || GET_CODE (dest) == ZERO_EXTRACT) 783518334Speter invalidate (XEXP (dest, 0), GET_MODE (dest)); 783618334Speter} 783718334Speter 783818334Speter/* Invalidate all insns from START up to the end of the function or the 783918334Speter next label. This called when we wish to CSE around a block that is 784018334Speter conditionally executed. */ 784118334Speter 784218334Speterstatic void 784318334Speterinvalidate_skipped_block (start) 784418334Speter rtx start; 784518334Speter{ 784618334Speter rtx insn; 784718334Speter static struct write_data init = {0, 0, 0, 0}; 784818334Speter static struct write_data everything = {0, 1, 1, 1}; 784918334Speter 785018334Speter for (insn = start; insn && GET_CODE (insn) != CODE_LABEL; 785118334Speter insn = NEXT_INSN (insn)) 785218334Speter { 785318334Speter if (GET_RTX_CLASS (GET_CODE (insn)) != 'i') 785418334Speter continue; 785518334Speter 785618334Speter skipped_writes_memory = init; 785718334Speter 785818334Speter if (GET_CODE (insn) == CALL_INSN) 785918334Speter { 786018334Speter invalidate_for_call (); 786118334Speter skipped_writes_memory = everything; 786218334Speter } 786318334Speter 786418334Speter note_stores (PATTERN (insn), invalidate_skipped_set); 786518334Speter invalidate_from_clobbers (&skipped_writes_memory, PATTERN (insn)); 786618334Speter } 786718334Speter} 786818334Speter 786918334Speter/* Used for communication between the following two routines; contains a 787018334Speter value to be checked for modification. */ 787118334Speter 787218334Speterstatic rtx cse_check_loop_start_value; 787318334Speter 787418334Speter/* If modifying X will modify the value in CSE_CHECK_LOOP_START_VALUE, 787518334Speter indicate that fact by setting CSE_CHECK_LOOP_START_VALUE to 0. */ 787618334Speter 787718334Speterstatic void 787818334Spetercse_check_loop_start (x, set) 787918334Speter rtx x; 788018334Speter rtx set; 788118334Speter{ 788218334Speter if (cse_check_loop_start_value == 0 788318334Speter || GET_CODE (x) == CC0 || GET_CODE (x) == PC) 788418334Speter return; 788518334Speter 788618334Speter if ((GET_CODE (x) == MEM && GET_CODE (cse_check_loop_start_value) == MEM) 788718334Speter || reg_overlap_mentioned_p (x, cse_check_loop_start_value)) 788818334Speter cse_check_loop_start_value = 0; 788918334Speter} 789018334Speter 789118334Speter/* X is a SET or CLOBBER contained in INSN that was found near the start of 789218334Speter a loop that starts with the label at LOOP_START. 789318334Speter 789418334Speter If X is a SET, we see if its SET_SRC is currently in our hash table. 789518334Speter If so, we see if it has a value equal to some register used only in the 789618334Speter loop exit code (as marked by jump.c). 789718334Speter 789818334Speter If those two conditions are true, we search backwards from the start of 789918334Speter the loop to see if that same value was loaded into a register that still 790018334Speter retains its value at the start of the loop. 790118334Speter 790218334Speter If so, we insert an insn after the load to copy the destination of that 790318334Speter load into the equivalent register and (try to) replace our SET_SRC with that 790418334Speter register. 790518334Speter 790618334Speter In any event, we invalidate whatever this SET or CLOBBER modifies. */ 790718334Speter 790818334Speterstatic void 790918334Spetercse_set_around_loop (x, insn, loop_start) 791018334Speter rtx x; 791118334Speter rtx insn; 791218334Speter rtx loop_start; 791318334Speter{ 791418334Speter struct table_elt *src_elt; 791518334Speter static struct write_data init = {0, 0, 0, 0}; 791618334Speter struct write_data writes_memory; 791718334Speter 791818334Speter writes_memory = init; 791918334Speter 792018334Speter /* If this is a SET, see if we can replace SET_SRC, but ignore SETs that 792118334Speter are setting PC or CC0 or whose SET_SRC is already a register. */ 792218334Speter if (GET_CODE (x) == SET 792318334Speter && GET_CODE (SET_DEST (x)) != PC && GET_CODE (SET_DEST (x)) != CC0 792418334Speter && GET_CODE (SET_SRC (x)) != REG) 792518334Speter { 792618334Speter src_elt = lookup (SET_SRC (x), 792718334Speter HASH (SET_SRC (x), GET_MODE (SET_DEST (x))), 792818334Speter GET_MODE (SET_DEST (x))); 792918334Speter 793018334Speter if (src_elt) 793118334Speter for (src_elt = src_elt->first_same_value; src_elt; 793218334Speter src_elt = src_elt->next_same_value) 793318334Speter if (GET_CODE (src_elt->exp) == REG && REG_LOOP_TEST_P (src_elt->exp) 793418334Speter && COST (src_elt->exp) < COST (SET_SRC (x))) 793518334Speter { 793618334Speter rtx p, set; 793718334Speter 793818334Speter /* Look for an insn in front of LOOP_START that sets 793918334Speter something in the desired mode to SET_SRC (x) before we hit 794018334Speter a label or CALL_INSN. */ 794118334Speter 794218334Speter for (p = prev_nonnote_insn (loop_start); 794318334Speter p && GET_CODE (p) != CALL_INSN 794418334Speter && GET_CODE (p) != CODE_LABEL; 794518334Speter p = prev_nonnote_insn (p)) 794618334Speter if ((set = single_set (p)) != 0 794718334Speter && GET_CODE (SET_DEST (set)) == REG 794818334Speter && GET_MODE (SET_DEST (set)) == src_elt->mode 794918334Speter && rtx_equal_p (SET_SRC (set), SET_SRC (x))) 795018334Speter { 795118334Speter /* We now have to ensure that nothing between P 795218334Speter and LOOP_START modified anything referenced in 795318334Speter SET_SRC (x). We know that nothing within the loop 795418334Speter can modify it, or we would have invalidated it in 795518334Speter the hash table. */ 795618334Speter rtx q; 795718334Speter 795818334Speter cse_check_loop_start_value = SET_SRC (x); 795918334Speter for (q = p; q != loop_start; q = NEXT_INSN (q)) 796018334Speter if (GET_RTX_CLASS (GET_CODE (q)) == 'i') 796118334Speter note_stores (PATTERN (q), cse_check_loop_start); 796218334Speter 796318334Speter /* If nothing was changed and we can replace our 796418334Speter SET_SRC, add an insn after P to copy its destination 796518334Speter to what we will be replacing SET_SRC with. */ 796618334Speter if (cse_check_loop_start_value 796718334Speter && validate_change (insn, &SET_SRC (x), 796818334Speter src_elt->exp, 0)) 796918334Speter emit_insn_after (gen_move_insn (src_elt->exp, 797018334Speter SET_DEST (set)), 797118334Speter p); 797218334Speter break; 797318334Speter } 797418334Speter } 797518334Speter } 797618334Speter 797718334Speter /* Now invalidate anything modified by X. */ 797818334Speter note_mem_written (SET_DEST (x), &writes_memory); 797918334Speter 798018334Speter if (writes_memory.var) 798118334Speter invalidate_memory (&writes_memory); 798218334Speter 798318334Speter /* See comment on similar code in cse_insn for explanation of these tests. */ 798418334Speter if (GET_CODE (SET_DEST (x)) == REG || GET_CODE (SET_DEST (x)) == SUBREG 798518334Speter || (GET_CODE (SET_DEST (x)) == MEM && ! writes_memory.all 798618334Speter && ! cse_rtx_addr_varies_p (SET_DEST (x)))) 798718334Speter invalidate (SET_DEST (x), VOIDmode); 798818334Speter else if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART 798918334Speter || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT) 799018334Speter invalidate (XEXP (SET_DEST (x), 0), GET_MODE (SET_DEST (x))); 799118334Speter} 799218334Speter 799318334Speter/* Find the end of INSN's basic block and return its range, 799418334Speter the total number of SETs in all the insns of the block, the last insn of the 799518334Speter block, and the branch path. 799618334Speter 799718334Speter The branch path indicates which branches should be followed. If a non-zero 799818334Speter path size is specified, the block should be rescanned and a different set 799918334Speter of branches will be taken. The branch path is only used if 800018334Speter FLAG_CSE_FOLLOW_JUMPS or FLAG_CSE_SKIP_BLOCKS is non-zero. 800118334Speter 800218334Speter DATA is a pointer to a struct cse_basic_block_data, defined below, that is 800318334Speter used to describe the block. It is filled in with the information about 800418334Speter the current block. The incoming structure's branch path, if any, is used 800518334Speter to construct the output branch path. */ 800618334Speter 800718334Spetervoid 800818334Spetercse_end_of_basic_block (insn, data, follow_jumps, after_loop, skip_blocks) 800918334Speter rtx insn; 801018334Speter struct cse_basic_block_data *data; 801118334Speter int follow_jumps; 801218334Speter int after_loop; 801318334Speter int skip_blocks; 801418334Speter{ 801518334Speter rtx p = insn, q; 801618334Speter int nsets = 0; 801718334Speter int low_cuid = INSN_CUID (insn), high_cuid = INSN_CUID (insn); 801818334Speter rtx next = GET_RTX_CLASS (GET_CODE (insn)) == 'i' ? insn : next_real_insn (insn); 801918334Speter int path_size = data->path_size; 802018334Speter int path_entry = 0; 802118334Speter int i; 802218334Speter 802318334Speter /* Update the previous branch path, if any. If the last branch was 802418334Speter previously TAKEN, mark it NOT_TAKEN. If it was previously NOT_TAKEN, 802518334Speter shorten the path by one and look at the previous branch. We know that 802618334Speter at least one branch must have been taken if PATH_SIZE is non-zero. */ 802718334Speter while (path_size > 0) 802818334Speter { 802918334Speter if (data->path[path_size - 1].status != NOT_TAKEN) 803018334Speter { 803118334Speter data->path[path_size - 1].status = NOT_TAKEN; 803218334Speter break; 803318334Speter } 803418334Speter else 803518334Speter path_size--; 803618334Speter } 803718334Speter 803818334Speter /* Scan to end of this basic block. */ 803918334Speter while (p && GET_CODE (p) != CODE_LABEL) 804018334Speter { 804118334Speter /* Don't cse out the end of a loop. This makes a difference 804218334Speter only for the unusual loops that always execute at least once; 804318334Speter all other loops have labels there so we will stop in any case. 804418334Speter Cse'ing out the end of the loop is dangerous because it 804518334Speter might cause an invariant expression inside the loop 804618334Speter to be reused after the end of the loop. This would make it 804718334Speter hard to move the expression out of the loop in loop.c, 804818334Speter especially if it is one of several equivalent expressions 804918334Speter and loop.c would like to eliminate it. 805018334Speter 805118334Speter If we are running after loop.c has finished, we can ignore 805218334Speter the NOTE_INSN_LOOP_END. */ 805318334Speter 805418334Speter if (! after_loop && GET_CODE (p) == NOTE 805518334Speter && NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END) 805618334Speter break; 805718334Speter 805818334Speter /* Don't cse over a call to setjmp; on some machines (eg vax) 805918334Speter the regs restored by the longjmp come from 806018334Speter a later time than the setjmp. */ 806118334Speter if (GET_CODE (p) == NOTE 806218334Speter && NOTE_LINE_NUMBER (p) == NOTE_INSN_SETJMP) 806318334Speter break; 806418334Speter 806518334Speter /* A PARALLEL can have lots of SETs in it, 806618334Speter especially if it is really an ASM_OPERANDS. */ 806718334Speter if (GET_RTX_CLASS (GET_CODE (p)) == 'i' 806818334Speter && GET_CODE (PATTERN (p)) == PARALLEL) 806918334Speter nsets += XVECLEN (PATTERN (p), 0); 807018334Speter else if (GET_CODE (p) != NOTE) 807118334Speter nsets += 1; 807218334Speter 807318334Speter /* Ignore insns made by CSE; they cannot affect the boundaries of 807418334Speter the basic block. */ 807518334Speter 807618334Speter if (INSN_UID (p) <= max_uid && INSN_CUID (p) > high_cuid) 807718334Speter high_cuid = INSN_CUID (p); 807818334Speter if (INSN_UID (p) <= max_uid && INSN_CUID (p) < low_cuid) 807918334Speter low_cuid = INSN_CUID (p); 808018334Speter 808118334Speter /* See if this insn is in our branch path. If it is and we are to 808218334Speter take it, do so. */ 808318334Speter if (path_entry < path_size && data->path[path_entry].branch == p) 808418334Speter { 808518334Speter if (data->path[path_entry].status != NOT_TAKEN) 808618334Speter p = JUMP_LABEL (p); 808718334Speter 808818334Speter /* Point to next entry in path, if any. */ 808918334Speter path_entry++; 809018334Speter } 809118334Speter 809218334Speter /* If this is a conditional jump, we can follow it if -fcse-follow-jumps 809318334Speter was specified, we haven't reached our maximum path length, there are 809418334Speter insns following the target of the jump, this is the only use of the 809518334Speter jump label, and the target label is preceded by a BARRIER. 809618334Speter 809718334Speter Alternatively, we can follow the jump if it branches around a 809818334Speter block of code and there are no other branches into the block. 809918334Speter In this case invalidate_skipped_block will be called to invalidate any 810018334Speter registers set in the block when following the jump. */ 810118334Speter 810218334Speter else if ((follow_jumps || skip_blocks) && path_size < PATHLENGTH - 1 810318334Speter && GET_CODE (p) == JUMP_INSN 810418334Speter && GET_CODE (PATTERN (p)) == SET 810518334Speter && GET_CODE (SET_SRC (PATTERN (p))) == IF_THEN_ELSE 810618334Speter && LABEL_NUSES (JUMP_LABEL (p)) == 1 810718334Speter && NEXT_INSN (JUMP_LABEL (p)) != 0) 810818334Speter { 810918334Speter for (q = PREV_INSN (JUMP_LABEL (p)); q; q = PREV_INSN (q)) 811018334Speter if ((GET_CODE (q) != NOTE 811118334Speter || NOTE_LINE_NUMBER (q) == NOTE_INSN_LOOP_END 811218334Speter || NOTE_LINE_NUMBER (q) == NOTE_INSN_SETJMP) 811318334Speter && (GET_CODE (q) != CODE_LABEL || LABEL_NUSES (q) != 0)) 811418334Speter break; 811518334Speter 811618334Speter /* If we ran into a BARRIER, this code is an extension of the 811718334Speter basic block when the branch is taken. */ 811818334Speter if (follow_jumps && q != 0 && GET_CODE (q) == BARRIER) 811918334Speter { 812018334Speter /* Don't allow ourself to keep walking around an 812118334Speter always-executed loop. */ 812218334Speter if (next_real_insn (q) == next) 812318334Speter { 812418334Speter p = NEXT_INSN (p); 812518334Speter continue; 812618334Speter } 812718334Speter 812818334Speter /* Similarly, don't put a branch in our path more than once. */ 812918334Speter for (i = 0; i < path_entry; i++) 813018334Speter if (data->path[i].branch == p) 813118334Speter break; 813218334Speter 813318334Speter if (i != path_entry) 813418334Speter break; 813518334Speter 813618334Speter data->path[path_entry].branch = p; 813718334Speter data->path[path_entry++].status = TAKEN; 813818334Speter 813918334Speter /* This branch now ends our path. It was possible that we 814018334Speter didn't see this branch the last time around (when the 814118334Speter insn in front of the target was a JUMP_INSN that was 814218334Speter turned into a no-op). */ 814318334Speter path_size = path_entry; 814418334Speter 814518334Speter p = JUMP_LABEL (p); 814618334Speter /* Mark block so we won't scan it again later. */ 814718334Speter PUT_MODE (NEXT_INSN (p), QImode); 814818334Speter } 814918334Speter /* Detect a branch around a block of code. */ 815018334Speter else if (skip_blocks && q != 0 && GET_CODE (q) != CODE_LABEL) 815118334Speter { 815218334Speter register rtx tmp; 815318334Speter 815418334Speter if (next_real_insn (q) == next) 815518334Speter { 815618334Speter p = NEXT_INSN (p); 815718334Speter continue; 815818334Speter } 815918334Speter 816018334Speter for (i = 0; i < path_entry; i++) 816118334Speter if (data->path[i].branch == p) 816218334Speter break; 816318334Speter 816418334Speter if (i != path_entry) 816518334Speter break; 816618334Speter 816718334Speter /* This is no_labels_between_p (p, q) with an added check for 816818334Speter reaching the end of a function (in case Q precedes P). */ 816918334Speter for (tmp = NEXT_INSN (p); tmp && tmp != q; tmp = NEXT_INSN (tmp)) 817018334Speter if (GET_CODE (tmp) == CODE_LABEL) 817118334Speter break; 817218334Speter 817318334Speter if (tmp == q) 817418334Speter { 817518334Speter data->path[path_entry].branch = p; 817618334Speter data->path[path_entry++].status = AROUND; 817718334Speter 817818334Speter path_size = path_entry; 817918334Speter 818018334Speter p = JUMP_LABEL (p); 818118334Speter /* Mark block so we won't scan it again later. */ 818218334Speter PUT_MODE (NEXT_INSN (p), QImode); 818318334Speter } 818418334Speter } 818518334Speter } 818618334Speter p = NEXT_INSN (p); 818718334Speter } 818818334Speter 818918334Speter data->low_cuid = low_cuid; 819018334Speter data->high_cuid = high_cuid; 819118334Speter data->nsets = nsets; 819218334Speter data->last = p; 819318334Speter 819418334Speter /* If all jumps in the path are not taken, set our path length to zero 819518334Speter so a rescan won't be done. */ 819618334Speter for (i = path_size - 1; i >= 0; i--) 819718334Speter if (data->path[i].status != NOT_TAKEN) 819818334Speter break; 819918334Speter 820018334Speter if (i == -1) 820118334Speter data->path_size = 0; 820218334Speter else 820318334Speter data->path_size = path_size; 820418334Speter 820518334Speter /* End the current branch path. */ 820618334Speter data->path[path_size].branch = 0; 820718334Speter} 820818334Speter 820918334Speter/* Perform cse on the instructions of a function. 821018334Speter F is the first instruction. 821118334Speter NREGS is one plus the highest pseudo-reg number used in the instruction. 821218334Speter 821318334Speter AFTER_LOOP is 1 if this is the cse call done after loop optimization 821418334Speter (only if -frerun-cse-after-loop). 821518334Speter 821618334Speter Returns 1 if jump_optimize should be redone due to simplifications 821718334Speter in conditional jump instructions. */ 821818334Speter 821918334Speterint 822018334Spetercse_main (f, nregs, after_loop, file) 822118334Speter rtx f; 822218334Speter int nregs; 822318334Speter int after_loop; 822418334Speter FILE *file; 822518334Speter{ 822618334Speter struct cse_basic_block_data val; 822718334Speter register rtx insn = f; 822818334Speter register int i; 822918334Speter 823018334Speter cse_jumps_altered = 0; 823118334Speter recorded_label_ref = 0; 823218334Speter constant_pool_entries_cost = 0; 823318334Speter val.path_size = 0; 823418334Speter 823518334Speter init_recog (); 823618334Speter 823718334Speter max_reg = nregs; 823818334Speter 823918334Speter all_minus_one = (int *) alloca (nregs * sizeof (int)); 824018334Speter consec_ints = (int *) alloca (nregs * sizeof (int)); 824118334Speter 824218334Speter for (i = 0; i < nregs; i++) 824318334Speter { 824418334Speter all_minus_one[i] = -1; 824518334Speter consec_ints[i] = i; 824618334Speter } 824718334Speter 824818334Speter reg_next_eqv = (int *) alloca (nregs * sizeof (int)); 824918334Speter reg_prev_eqv = (int *) alloca (nregs * sizeof (int)); 825018334Speter reg_qty = (int *) alloca (nregs * sizeof (int)); 825118334Speter reg_in_table = (int *) alloca (nregs * sizeof (int)); 825218334Speter reg_tick = (int *) alloca (nregs * sizeof (int)); 825318334Speter 825418334Speter#ifdef LOAD_EXTEND_OP 825518334Speter 825618334Speter /* Allocate scratch rtl here. cse_insn will fill in the memory reference 825718334Speter and change the code and mode as appropriate. */ 825818334Speter memory_extend_rtx = gen_rtx (ZERO_EXTEND, VOIDmode, 0); 825918334Speter#endif 826018334Speter 826118334Speter /* Discard all the free elements of the previous function 826218334Speter since they are allocated in the temporarily obstack. */ 826318334Speter bzero ((char *) table, sizeof table); 826418334Speter free_element_chain = 0; 826518334Speter n_elements_made = 0; 826618334Speter 826718334Speter /* Find the largest uid. */ 826818334Speter 826918334Speter max_uid = get_max_uid (); 827018334Speter uid_cuid = (int *) alloca ((max_uid + 1) * sizeof (int)); 827118334Speter bzero ((char *) uid_cuid, (max_uid + 1) * sizeof (int)); 827218334Speter 827318334Speter /* Compute the mapping from uids to cuids. 827418334Speter CUIDs are numbers assigned to insns, like uids, 827518334Speter except that cuids increase monotonically through the code. 827618334Speter Don't assign cuids to line-number NOTEs, so that the distance in cuids 827718334Speter between two insns is not affected by -g. */ 827818334Speter 827918334Speter for (insn = f, i = 0; insn; insn = NEXT_INSN (insn)) 828018334Speter { 828118334Speter if (GET_CODE (insn) != NOTE 828218334Speter || NOTE_LINE_NUMBER (insn) < 0) 828318334Speter INSN_CUID (insn) = ++i; 828418334Speter else 828518334Speter /* Give a line number note the same cuid as preceding insn. */ 828618334Speter INSN_CUID (insn) = i; 828718334Speter } 828818334Speter 828918334Speter /* Initialize which registers are clobbered by calls. */ 829018334Speter 829118334Speter CLEAR_HARD_REG_SET (regs_invalidated_by_call); 829218334Speter 829318334Speter for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 829418334Speter if ((call_used_regs[i] 829518334Speter /* Used to check !fixed_regs[i] here, but that isn't safe; 829618334Speter fixed regs are still call-clobbered, and sched can get 829718334Speter confused if they can "live across calls". 829818334Speter 829918334Speter The frame pointer is always preserved across calls. The arg 830018334Speter pointer is if it is fixed. The stack pointer usually is, unless 830118334Speter RETURN_POPS_ARGS, in which case an explicit CLOBBER 830218334Speter will be present. If we are generating PIC code, the PIC offset 830318334Speter table register is preserved across calls. */ 830418334Speter 830518334Speter && i != STACK_POINTER_REGNUM 830618334Speter && i != FRAME_POINTER_REGNUM 830718334Speter#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM 830818334Speter && i != HARD_FRAME_POINTER_REGNUM 830918334Speter#endif 831018334Speter#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM 831118334Speter && ! (i == ARG_POINTER_REGNUM && fixed_regs[i]) 831218334Speter#endif 831318334Speter#if defined (PIC_OFFSET_TABLE_REGNUM) && !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED) 831418334Speter && ! (i == PIC_OFFSET_TABLE_REGNUM && flag_pic) 831518334Speter#endif 831618334Speter ) 831718334Speter || global_regs[i]) 831818334Speter SET_HARD_REG_BIT (regs_invalidated_by_call, i); 831918334Speter 832018334Speter /* Loop over basic blocks. 832118334Speter Compute the maximum number of qty's needed for each basic block 832218334Speter (which is 2 for each SET). */ 832318334Speter insn = f; 832418334Speter while (insn) 832518334Speter { 832618334Speter cse_end_of_basic_block (insn, &val, flag_cse_follow_jumps, after_loop, 832718334Speter flag_cse_skip_blocks); 832818334Speter 832918334Speter /* If this basic block was already processed or has no sets, skip it. */ 833018334Speter if (val.nsets == 0 || GET_MODE (insn) == QImode) 833118334Speter { 833218334Speter PUT_MODE (insn, VOIDmode); 833318334Speter insn = (val.last ? NEXT_INSN (val.last) : 0); 833418334Speter val.path_size = 0; 833518334Speter continue; 833618334Speter } 833718334Speter 833818334Speter cse_basic_block_start = val.low_cuid; 833918334Speter cse_basic_block_end = val.high_cuid; 834018334Speter max_qty = val.nsets * 2; 834118334Speter 834218334Speter if (file) 834318334Speter fprintf (file, ";; Processing block from %d to %d, %d sets.\n", 834418334Speter INSN_UID (insn), val.last ? INSN_UID (val.last) : 0, 834518334Speter val.nsets); 834618334Speter 834718334Speter /* Make MAX_QTY bigger to give us room to optimize 834818334Speter past the end of this basic block, if that should prove useful. */ 834918334Speter if (max_qty < 500) 835018334Speter max_qty = 500; 835118334Speter 835218334Speter max_qty += max_reg; 835318334Speter 835418334Speter /* If this basic block is being extended by following certain jumps, 835518334Speter (see `cse_end_of_basic_block'), we reprocess the code from the start. 835618334Speter Otherwise, we start after this basic block. */ 835718334Speter if (val.path_size > 0) 835818334Speter cse_basic_block (insn, val.last, val.path, 0); 835918334Speter else 836018334Speter { 836118334Speter int old_cse_jumps_altered = cse_jumps_altered; 836218334Speter rtx temp; 836318334Speter 836418334Speter /* When cse changes a conditional jump to an unconditional 836518334Speter jump, we want to reprocess the block, since it will give 836618334Speter us a new branch path to investigate. */ 836718334Speter cse_jumps_altered = 0; 836818334Speter temp = cse_basic_block (insn, val.last, val.path, ! after_loop); 836918334Speter if (cse_jumps_altered == 0 837018334Speter || (flag_cse_follow_jumps == 0 && flag_cse_skip_blocks == 0)) 837118334Speter insn = temp; 837218334Speter 837318334Speter cse_jumps_altered |= old_cse_jumps_altered; 837418334Speter } 837518334Speter 837618334Speter#ifdef USE_C_ALLOCA 837718334Speter alloca (0); 837818334Speter#endif 837918334Speter } 838018334Speter 838118334Speter /* Tell refers_to_mem_p that qty_const info is not available. */ 838218334Speter qty_const = 0; 838318334Speter 838418334Speter if (max_elements_made < n_elements_made) 838518334Speter max_elements_made = n_elements_made; 838618334Speter 838718334Speter return cse_jumps_altered || recorded_label_ref; 838818334Speter} 838918334Speter 839018334Speter/* Process a single basic block. FROM and TO and the limits of the basic 839118334Speter block. NEXT_BRANCH points to the branch path when following jumps or 839218334Speter a null path when not following jumps. 839318334Speter 839418334Speter AROUND_LOOP is non-zero if we are to try to cse around to the start of a 839518334Speter loop. This is true when we are being called for the last time on a 839618334Speter block and this CSE pass is before loop.c. */ 839718334Speter 839818334Speterstatic rtx 839918334Spetercse_basic_block (from, to, next_branch, around_loop) 840018334Speter register rtx from, to; 840118334Speter struct branch_path *next_branch; 840218334Speter int around_loop; 840318334Speter{ 840418334Speter register rtx insn; 840518334Speter int to_usage = 0; 840618334Speter int in_libcall_block = 0; 840718334Speter 840818334Speter /* Each of these arrays is undefined before max_reg, so only allocate 840918334Speter the space actually needed and adjust the start below. */ 841018334Speter 841118334Speter qty_first_reg = (int *) alloca ((max_qty - max_reg) * sizeof (int)); 841218334Speter qty_last_reg = (int *) alloca ((max_qty - max_reg) * sizeof (int)); 841318334Speter qty_mode= (enum machine_mode *) alloca ((max_qty - max_reg) * sizeof (enum machine_mode)); 841418334Speter qty_const = (rtx *) alloca ((max_qty - max_reg) * sizeof (rtx)); 841518334Speter qty_const_insn = (rtx *) alloca ((max_qty - max_reg) * sizeof (rtx)); 841618334Speter qty_comparison_code 841718334Speter = (enum rtx_code *) alloca ((max_qty - max_reg) * sizeof (enum rtx_code)); 841818334Speter qty_comparison_qty = (int *) alloca ((max_qty - max_reg) * sizeof (int)); 841918334Speter qty_comparison_const = (rtx *) alloca ((max_qty - max_reg) * sizeof (rtx)); 842018334Speter 842118334Speter qty_first_reg -= max_reg; 842218334Speter qty_last_reg -= max_reg; 842318334Speter qty_mode -= max_reg; 842418334Speter qty_const -= max_reg; 842518334Speter qty_const_insn -= max_reg; 842618334Speter qty_comparison_code -= max_reg; 842718334Speter qty_comparison_qty -= max_reg; 842818334Speter qty_comparison_const -= max_reg; 842918334Speter 843018334Speter new_basic_block (); 843118334Speter 843218334Speter /* TO might be a label. If so, protect it from being deleted. */ 843318334Speter if (to != 0 && GET_CODE (to) == CODE_LABEL) 843418334Speter ++LABEL_NUSES (to); 843518334Speter 843618334Speter for (insn = from; insn != to; insn = NEXT_INSN (insn)) 843718334Speter { 843818334Speter register enum rtx_code code; 843918334Speter 844018334Speter /* See if this is a branch that is part of the path. If so, and it is 844118334Speter to be taken, do so. */ 844218334Speter if (next_branch->branch == insn) 844318334Speter { 844418334Speter enum taken status = next_branch++->status; 844518334Speter if (status != NOT_TAKEN) 844618334Speter { 844718334Speter if (status == TAKEN) 844818334Speter record_jump_equiv (insn, 1); 844918334Speter else 845018334Speter invalidate_skipped_block (NEXT_INSN (insn)); 845118334Speter 845218334Speter /* Set the last insn as the jump insn; it doesn't affect cc0. 845318334Speter Then follow this branch. */ 845418334Speter#ifdef HAVE_cc0 845518334Speter prev_insn_cc0 = 0; 845618334Speter#endif 845718334Speter prev_insn = insn; 845818334Speter insn = JUMP_LABEL (insn); 845918334Speter continue; 846018334Speter } 846118334Speter } 846218334Speter 846318334Speter code = GET_CODE (insn); 846418334Speter if (GET_MODE (insn) == QImode) 846518334Speter PUT_MODE (insn, VOIDmode); 846618334Speter 846718334Speter if (GET_RTX_CLASS (code) == 'i') 846818334Speter { 846918334Speter /* Process notes first so we have all notes in canonical forms when 847018334Speter looking for duplicate operations. */ 847118334Speter 847218334Speter if (REG_NOTES (insn)) 847318334Speter REG_NOTES (insn) = cse_process_notes (REG_NOTES (insn), NULL_RTX); 847418334Speter 847518334Speter /* Track when we are inside in LIBCALL block. Inside such a block, 847618334Speter we do not want to record destinations. The last insn of a 847718334Speter LIBCALL block is not considered to be part of the block, since 847818334Speter its destination is the result of the block and hence should be 847918334Speter recorded. */ 848018334Speter 848118334Speter if (find_reg_note (insn, REG_LIBCALL, NULL_RTX)) 848218334Speter in_libcall_block = 1; 848318334Speter else if (find_reg_note (insn, REG_RETVAL, NULL_RTX)) 848418334Speter in_libcall_block = 0; 848518334Speter 848618334Speter cse_insn (insn, in_libcall_block); 848718334Speter } 848818334Speter 848918334Speter /* If INSN is now an unconditional jump, skip to the end of our 849018334Speter basic block by pretending that we just did the last insn in the 849118334Speter basic block. If we are jumping to the end of our block, show 849218334Speter that we can have one usage of TO. */ 849318334Speter 849418334Speter if (simplejump_p (insn)) 849518334Speter { 849618334Speter if (to == 0) 849718334Speter return 0; 849818334Speter 849918334Speter if (JUMP_LABEL (insn) == to) 850018334Speter to_usage = 1; 850118334Speter 850218334Speter /* Maybe TO was deleted because the jump is unconditional. 850318334Speter If so, there is nothing left in this basic block. */ 850418334Speter /* ??? Perhaps it would be smarter to set TO 850518334Speter to whatever follows this insn, 850618334Speter and pretend the basic block had always ended here. */ 850718334Speter if (INSN_DELETED_P (to)) 850818334Speter break; 850918334Speter 851018334Speter insn = PREV_INSN (to); 851118334Speter } 851218334Speter 851318334Speter /* See if it is ok to keep on going past the label 851418334Speter which used to end our basic block. Remember that we incremented 851518334Speter the count of that label, so we decrement it here. If we made 851618334Speter a jump unconditional, TO_USAGE will be one; in that case, we don't 851718334Speter want to count the use in that jump. */ 851818334Speter 851918334Speter if (to != 0 && NEXT_INSN (insn) == to 852018334Speter && GET_CODE (to) == CODE_LABEL && --LABEL_NUSES (to) == to_usage) 852118334Speter { 852218334Speter struct cse_basic_block_data val; 852318334Speter rtx prev; 852418334Speter 852518334Speter insn = NEXT_INSN (to); 852618334Speter 852718334Speter if (LABEL_NUSES (to) == 0) 852818334Speter insn = delete_insn (to); 852918334Speter 853018334Speter /* If TO was the last insn in the function, we are done. */ 853118334Speter if (insn == 0) 853218334Speter return 0; 853318334Speter 853418334Speter /* If TO was preceded by a BARRIER we are done with this block 853518334Speter because it has no continuation. */ 853618334Speter prev = prev_nonnote_insn (to); 853718334Speter if (prev && GET_CODE (prev) == BARRIER) 853818334Speter return insn; 853918334Speter 854018334Speter /* Find the end of the following block. Note that we won't be 854118334Speter following branches in this case. */ 854218334Speter to_usage = 0; 854318334Speter val.path_size = 0; 854418334Speter cse_end_of_basic_block (insn, &val, 0, 0, 0); 854518334Speter 854618334Speter /* If the tables we allocated have enough space left 854718334Speter to handle all the SETs in the next basic block, 854818334Speter continue through it. Otherwise, return, 854918334Speter and that block will be scanned individually. */ 855018334Speter if (val.nsets * 2 + next_qty > max_qty) 855118334Speter break; 855218334Speter 855318334Speter cse_basic_block_start = val.low_cuid; 855418334Speter cse_basic_block_end = val.high_cuid; 855518334Speter to = val.last; 855618334Speter 855718334Speter /* Prevent TO from being deleted if it is a label. */ 855818334Speter if (to != 0 && GET_CODE (to) == CODE_LABEL) 855918334Speter ++LABEL_NUSES (to); 856018334Speter 856118334Speter /* Back up so we process the first insn in the extension. */ 856218334Speter insn = PREV_INSN (insn); 856318334Speter } 856418334Speter } 856518334Speter 856618334Speter if (next_qty > max_qty) 856718334Speter abort (); 856818334Speter 856918334Speter /* If we are running before loop.c, we stopped on a NOTE_INSN_LOOP_END, and 857018334Speter the previous insn is the only insn that branches to the head of a loop, 857118334Speter we can cse into the loop. Don't do this if we changed the jump 857218334Speter structure of a loop unless we aren't going to be following jumps. */ 857318334Speter 857418334Speter if ((cse_jumps_altered == 0 857518334Speter || (flag_cse_follow_jumps == 0 && flag_cse_skip_blocks == 0)) 857618334Speter && around_loop && to != 0 857718334Speter && GET_CODE (to) == NOTE && NOTE_LINE_NUMBER (to) == NOTE_INSN_LOOP_END 857818334Speter && GET_CODE (PREV_INSN (to)) == JUMP_INSN 857918334Speter && JUMP_LABEL (PREV_INSN (to)) != 0 858018334Speter && LABEL_NUSES (JUMP_LABEL (PREV_INSN (to))) == 1) 858118334Speter cse_around_loop (JUMP_LABEL (PREV_INSN (to))); 858218334Speter 858318334Speter return to ? NEXT_INSN (to) : 0; 858418334Speter} 858518334Speter 858618334Speter/* Count the number of times registers are used (not set) in X. 858718334Speter COUNTS is an array in which we accumulate the count, INCR is how much 858818334Speter we count each register usage. 858918334Speter 859018334Speter Don't count a usage of DEST, which is the SET_DEST of a SET which 859118334Speter contains X in its SET_SRC. This is because such a SET does not 859218334Speter modify the liveness of DEST. */ 859318334Speter 859418334Speterstatic void 859518334Spetercount_reg_usage (x, counts, dest, incr) 859618334Speter rtx x; 859718334Speter int *counts; 859818334Speter rtx dest; 859918334Speter int incr; 860018334Speter{ 860118334Speter enum rtx_code code; 860218334Speter char *fmt; 860318334Speter int i, j; 860418334Speter 860518334Speter if (x == 0) 860618334Speter return; 860718334Speter 860818334Speter switch (code = GET_CODE (x)) 860918334Speter { 861018334Speter case REG: 861118334Speter if (x != dest) 861218334Speter counts[REGNO (x)] += incr; 861318334Speter return; 861418334Speter 861518334Speter case PC: 861618334Speter case CC0: 861718334Speter case CONST: 861818334Speter case CONST_INT: 861918334Speter case CONST_DOUBLE: 862018334Speter case SYMBOL_REF: 862118334Speter case LABEL_REF: 862218334Speter case CLOBBER: 862318334Speter return; 862418334Speter 862518334Speter case SET: 862618334Speter /* Unless we are setting a REG, count everything in SET_DEST. */ 862718334Speter if (GET_CODE (SET_DEST (x)) != REG) 862818334Speter count_reg_usage (SET_DEST (x), counts, NULL_RTX, incr); 862918334Speter 863018334Speter /* If SRC has side-effects, then we can't delete this insn, so the 863118334Speter usage of SET_DEST inside SRC counts. 863218334Speter 863318334Speter ??? Strictly-speaking, we might be preserving this insn 863418334Speter because some other SET has side-effects, but that's hard 863518334Speter to do and can't happen now. */ 863618334Speter count_reg_usage (SET_SRC (x), counts, 863718334Speter side_effects_p (SET_SRC (x)) ? NULL_RTX : SET_DEST (x), 863818334Speter incr); 863918334Speter return; 864018334Speter 864118334Speter case CALL_INSN: 864218334Speter count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, NULL_RTX, incr); 864318334Speter 864418334Speter /* ... falls through ... */ 864518334Speter case INSN: 864618334Speter case JUMP_INSN: 864718334Speter count_reg_usage (PATTERN (x), counts, NULL_RTX, incr); 864818334Speter 864918334Speter /* Things used in a REG_EQUAL note aren't dead since loop may try to 865018334Speter use them. */ 865118334Speter 865218334Speter count_reg_usage (REG_NOTES (x), counts, NULL_RTX, incr); 865318334Speter return; 865418334Speter 865518334Speter case EXPR_LIST: 865618334Speter case INSN_LIST: 865718334Speter if (REG_NOTE_KIND (x) == REG_EQUAL 865818334Speter || GET_CODE (XEXP (x,0)) == USE) 865918334Speter count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr); 866018334Speter count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr); 866118334Speter return; 866218334Speter } 866318334Speter 866418334Speter fmt = GET_RTX_FORMAT (code); 866518334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 866618334Speter { 866718334Speter if (fmt[i] == 'e') 866818334Speter count_reg_usage (XEXP (x, i), counts, dest, incr); 866918334Speter else if (fmt[i] == 'E') 867018334Speter for (j = XVECLEN (x, i) - 1; j >= 0; j--) 867118334Speter count_reg_usage (XVECEXP (x, i, j), counts, dest, incr); 867218334Speter } 867318334Speter} 867418334Speter 867518334Speter/* Scan all the insns and delete any that are dead; i.e., they store a register 867618334Speter that is never used or they copy a register to itself. 867718334Speter 867818334Speter This is used to remove insns made obviously dead by cse. It improves the 867918334Speter heuristics in loop since it won't try to move dead invariants out of loops 868018334Speter or make givs for dead quantities. The remaining passes of the compilation 868118334Speter are also sped up. */ 868218334Speter 868318334Spetervoid 868418334Speterdelete_dead_from_cse (insns, nreg) 868518334Speter rtx insns; 868618334Speter int nreg; 868718334Speter{ 868818334Speter int *counts = (int *) alloca (nreg * sizeof (int)); 868918334Speter rtx insn, prev; 869018334Speter rtx tem; 869118334Speter int i; 869218334Speter int in_libcall = 0; 869318334Speter 869418334Speter /* First count the number of times each register is used. */ 869518334Speter bzero ((char *) counts, sizeof (int) * nreg); 869618334Speter for (insn = next_real_insn (insns); insn; insn = next_real_insn (insn)) 869718334Speter count_reg_usage (insn, counts, NULL_RTX, 1); 869818334Speter 869918334Speter /* Go from the last insn to the first and delete insns that only set unused 870018334Speter registers or copy a register to itself. As we delete an insn, remove 870118334Speter usage counts for registers it uses. */ 870218334Speter for (insn = prev_real_insn (get_last_insn ()); insn; insn = prev) 870318334Speter { 870418334Speter int live_insn = 0; 870518334Speter 870618334Speter prev = prev_real_insn (insn); 870718334Speter 870818334Speter /* Don't delete any insns that are part of a libcall block. 870918334Speter Flow or loop might get confused if we did that. Remember 871018334Speter that we are scanning backwards. */ 871118334Speter if (find_reg_note (insn, REG_RETVAL, NULL_RTX)) 871218334Speter in_libcall = 1; 871318334Speter 871418334Speter if (in_libcall) 871518334Speter live_insn = 1; 871618334Speter else if (GET_CODE (PATTERN (insn)) == SET) 871718334Speter { 871818334Speter if (GET_CODE (SET_DEST (PATTERN (insn))) == REG 871918334Speter && SET_DEST (PATTERN (insn)) == SET_SRC (PATTERN (insn))) 872018334Speter ; 872118334Speter 872218334Speter#ifdef HAVE_cc0 872318334Speter else if (GET_CODE (SET_DEST (PATTERN (insn))) == CC0 872418334Speter && ! side_effects_p (SET_SRC (PATTERN (insn))) 872518334Speter && ((tem = next_nonnote_insn (insn)) == 0 872618334Speter || GET_RTX_CLASS (GET_CODE (tem)) != 'i' 872718334Speter || ! reg_referenced_p (cc0_rtx, PATTERN (tem)))) 872818334Speter ; 872918334Speter#endif 873018334Speter else if (GET_CODE (SET_DEST (PATTERN (insn))) != REG 873118334Speter || REGNO (SET_DEST (PATTERN (insn))) < FIRST_PSEUDO_REGISTER 873218334Speter || counts[REGNO (SET_DEST (PATTERN (insn)))] != 0 873318334Speter || side_effects_p (SET_SRC (PATTERN (insn)))) 873418334Speter live_insn = 1; 873518334Speter } 873618334Speter else if (GET_CODE (PATTERN (insn)) == PARALLEL) 873718334Speter for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) 873818334Speter { 873918334Speter rtx elt = XVECEXP (PATTERN (insn), 0, i); 874018334Speter 874118334Speter if (GET_CODE (elt) == SET) 874218334Speter { 874318334Speter if (GET_CODE (SET_DEST (elt)) == REG 874418334Speter && SET_DEST (elt) == SET_SRC (elt)) 874518334Speter ; 874618334Speter 874718334Speter#ifdef HAVE_cc0 874818334Speter else if (GET_CODE (SET_DEST (elt)) == CC0 874918334Speter && ! side_effects_p (SET_SRC (elt)) 875018334Speter && ((tem = next_nonnote_insn (insn)) == 0 875118334Speter || GET_RTX_CLASS (GET_CODE (tem)) != 'i' 875218334Speter || ! reg_referenced_p (cc0_rtx, PATTERN (tem)))) 875318334Speter ; 875418334Speter#endif 875518334Speter else if (GET_CODE (SET_DEST (elt)) != REG 875618334Speter || REGNO (SET_DEST (elt)) < FIRST_PSEUDO_REGISTER 875718334Speter || counts[REGNO (SET_DEST (elt))] != 0 875818334Speter || side_effects_p (SET_SRC (elt))) 875918334Speter live_insn = 1; 876018334Speter } 876118334Speter else if (GET_CODE (elt) != CLOBBER && GET_CODE (elt) != USE) 876218334Speter live_insn = 1; 876318334Speter } 876418334Speter else 876518334Speter live_insn = 1; 876618334Speter 876718334Speter /* If this is a dead insn, delete it and show registers in it aren't 876818334Speter being used. */ 876918334Speter 877018334Speter if (! live_insn) 877118334Speter { 877218334Speter count_reg_usage (insn, counts, NULL_RTX, -1); 877318334Speter delete_insn (insn); 877418334Speter } 877518334Speter 877618334Speter if (find_reg_note (insn, REG_LIBCALL, NULL_RTX)) 877718334Speter in_libcall = 0; 877818334Speter } 877918334Speter} 8780