xref: /dragonfly/contrib/gcc-8.0/gcc/cse.c (revision 38fd1498)
1*38fd1498Szrj /* Common subexpression elimination for GNU compiler.
2*38fd1498Szrj    Copyright (C) 1987-2018 Free Software Foundation, Inc.
3*38fd1498Szrj 
4*38fd1498Szrj This file is part of GCC.
5*38fd1498Szrj 
6*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
7*38fd1498Szrj the terms of the GNU General Public License as published by the Free
8*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
9*38fd1498Szrj version.
10*38fd1498Szrj 
11*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*38fd1498Szrj for more details.
15*38fd1498Szrj 
16*38fd1498Szrj You should have received a copy of the GNU General Public License
17*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
18*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
19*38fd1498Szrj 
20*38fd1498Szrj #include "config.h"
21*38fd1498Szrj #include "system.h"
22*38fd1498Szrj #include "coretypes.h"
23*38fd1498Szrj #include "backend.h"
24*38fd1498Szrj #include "target.h"
25*38fd1498Szrj #include "rtl.h"
26*38fd1498Szrj #include "tree.h"
27*38fd1498Szrj #include "cfghooks.h"
28*38fd1498Szrj #include "df.h"
29*38fd1498Szrj #include "memmodel.h"
30*38fd1498Szrj #include "tm_p.h"
31*38fd1498Szrj #include "insn-config.h"
32*38fd1498Szrj #include "regs.h"
33*38fd1498Szrj #include "emit-rtl.h"
34*38fd1498Szrj #include "recog.h"
35*38fd1498Szrj #include "cfgrtl.h"
36*38fd1498Szrj #include "cfganal.h"
37*38fd1498Szrj #include "cfgcleanup.h"
38*38fd1498Szrj #include "alias.h"
39*38fd1498Szrj #include "toplev.h"
40*38fd1498Szrj #include "params.h"
41*38fd1498Szrj #include "rtlhooks-def.h"
42*38fd1498Szrj #include "tree-pass.h"
43*38fd1498Szrj #include "dbgcnt.h"
44*38fd1498Szrj #include "rtl-iter.h"
45*38fd1498Szrj 
46*38fd1498Szrj /* The basic idea of common subexpression elimination is to go
47*38fd1498Szrj    through the code, keeping a record of expressions that would
48*38fd1498Szrj    have the same value at the current scan point, and replacing
49*38fd1498Szrj    expressions encountered with the cheapest equivalent expression.
50*38fd1498Szrj 
51*38fd1498Szrj    It is too complicated to keep track of the different possibilities
52*38fd1498Szrj    when control paths merge in this code; so, at each label, we forget all
53*38fd1498Szrj    that is known and start fresh.  This can be described as processing each
54*38fd1498Szrj    extended basic block separately.  We have a separate pass to perform
55*38fd1498Szrj    global CSE.
56*38fd1498Szrj 
57*38fd1498Szrj    Note CSE can turn a conditional or computed jump into a nop or
58*38fd1498Szrj    an unconditional jump.  When this occurs we arrange to run the jump
59*38fd1498Szrj    optimizer after CSE to delete the unreachable code.
60*38fd1498Szrj 
61*38fd1498Szrj    We use two data structures to record the equivalent expressions:
62*38fd1498Szrj    a hash table for most expressions, and a vector of "quantity
63*38fd1498Szrj    numbers" to record equivalent (pseudo) registers.
64*38fd1498Szrj 
65*38fd1498Szrj    The use of the special data structure for registers is desirable
66*38fd1498Szrj    because it is faster.  It is possible because registers references
67*38fd1498Szrj    contain a fairly small number, the register number, taken from
68*38fd1498Szrj    a contiguously allocated series, and two register references are
69*38fd1498Szrj    identical if they have the same number.  General expressions
70*38fd1498Szrj    do not have any such thing, so the only way to retrieve the
71*38fd1498Szrj    information recorded on an expression other than a register
72*38fd1498Szrj    is to keep it in a hash table.
73*38fd1498Szrj 
74*38fd1498Szrj Registers and "quantity numbers":
75*38fd1498Szrj 
76*38fd1498Szrj    At the start of each basic block, all of the (hardware and pseudo)
77*38fd1498Szrj    registers used in the function are given distinct quantity
78*38fd1498Szrj    numbers to indicate their contents.  During scan, when the code
79*38fd1498Szrj    copies one register into another, we copy the quantity number.
80*38fd1498Szrj    When a register is loaded in any other way, we allocate a new
81*38fd1498Szrj    quantity number to describe the value generated by this operation.
82*38fd1498Szrj    `REG_QTY (N)' records what quantity register N is currently thought
83*38fd1498Szrj    of as containing.
84*38fd1498Szrj 
85*38fd1498Szrj    All real quantity numbers are greater than or equal to zero.
86*38fd1498Szrj    If register N has not been assigned a quantity, `REG_QTY (N)' will
87*38fd1498Szrj    equal -N - 1, which is always negative.
88*38fd1498Szrj 
89*38fd1498Szrj    Quantity numbers below zero do not exist and none of the `qty_table'
90*38fd1498Szrj    entries should be referenced with a negative index.
91*38fd1498Szrj 
92*38fd1498Szrj    We also maintain a bidirectional chain of registers for each
93*38fd1498Szrj    quantity number.  The `qty_table` members `first_reg' and `last_reg',
94*38fd1498Szrj    and `reg_eqv_table' members `next' and `prev' hold these chains.
95*38fd1498Szrj 
96*38fd1498Szrj    The first register in a chain is the one whose lifespan is least local.
97*38fd1498Szrj    Among equals, it is the one that was seen first.
98*38fd1498Szrj    We replace any equivalent register with that one.
99*38fd1498Szrj 
100*38fd1498Szrj    If two registers have the same quantity number, it must be true that
101*38fd1498Szrj    REG expressions with qty_table `mode' must be in the hash table for both
102*38fd1498Szrj    registers and must be in the same class.
103*38fd1498Szrj 
104*38fd1498Szrj    The converse is not true.  Since hard registers may be referenced in
105*38fd1498Szrj    any mode, two REG expressions might be equivalent in the hash table
106*38fd1498Szrj    but not have the same quantity number if the quantity number of one
107*38fd1498Szrj    of the registers is not the same mode as those expressions.
108*38fd1498Szrj 
109*38fd1498Szrj Constants and quantity numbers
110*38fd1498Szrj 
111*38fd1498Szrj    When a quantity has a known constant value, that value is stored
112*38fd1498Szrj    in the appropriate qty_table `const_rtx'.  This is in addition to
113*38fd1498Szrj    putting the constant in the hash table as is usual for non-regs.
114*38fd1498Szrj 
115*38fd1498Szrj    Whether a reg or a constant is preferred is determined by the configuration
116*38fd1498Szrj    macro CONST_COSTS and will often depend on the constant value.  In any
117*38fd1498Szrj    event, expressions containing constants can be simplified, by fold_rtx.
118*38fd1498Szrj 
119*38fd1498Szrj    When a quantity has a known nearly constant value (such as an address
120*38fd1498Szrj    of a stack slot), that value is stored in the appropriate qty_table
121*38fd1498Szrj    `const_rtx'.
122*38fd1498Szrj 
123*38fd1498Szrj    Integer constants don't have a machine mode.  However, cse
124*38fd1498Szrj    determines the intended machine mode from the destination
125*38fd1498Szrj    of the instruction that moves the constant.  The machine mode
126*38fd1498Szrj    is recorded in the hash table along with the actual RTL
127*38fd1498Szrj    constant expression so that different modes are kept separate.
128*38fd1498Szrj 
129*38fd1498Szrj Other expressions:
130*38fd1498Szrj 
131*38fd1498Szrj    To record known equivalences among expressions in general
132*38fd1498Szrj    we use a hash table called `table'.  It has a fixed number of buckets
133*38fd1498Szrj    that contain chains of `struct table_elt' elements for expressions.
134*38fd1498Szrj    These chains connect the elements whose expressions have the same
135*38fd1498Szrj    hash codes.
136*38fd1498Szrj 
137*38fd1498Szrj    Other chains through the same elements connect the elements which
138*38fd1498Szrj    currently have equivalent values.
139*38fd1498Szrj 
140*38fd1498Szrj    Register references in an expression are canonicalized before hashing
141*38fd1498Szrj    the expression.  This is done using `reg_qty' and qty_table `first_reg'.
142*38fd1498Szrj    The hash code of a register reference is computed using the quantity
143*38fd1498Szrj    number, not the register number.
144*38fd1498Szrj 
145*38fd1498Szrj    When the value of an expression changes, it is necessary to remove from the
146*38fd1498Szrj    hash table not just that expression but all expressions whose values
147*38fd1498Szrj    could be different as a result.
148*38fd1498Szrj 
149*38fd1498Szrj      1. If the value changing is in memory, except in special cases
150*38fd1498Szrj      ANYTHING referring to memory could be changed.  That is because
151*38fd1498Szrj      nobody knows where a pointer does not point.
152*38fd1498Szrj      The function `invalidate_memory' removes what is necessary.
153*38fd1498Szrj 
154*38fd1498Szrj      The special cases are when the address is constant or is
155*38fd1498Szrj      a constant plus a fixed register such as the frame pointer
156*38fd1498Szrj      or a static chain pointer.  When such addresses are stored in,
157*38fd1498Szrj      we can tell exactly which other such addresses must be invalidated
158*38fd1498Szrj      due to overlap.  `invalidate' does this.
159*38fd1498Szrj      All expressions that refer to non-constant
160*38fd1498Szrj      memory addresses are also invalidated.  `invalidate_memory' does this.
161*38fd1498Szrj 
162*38fd1498Szrj      2. If the value changing is a register, all expressions
163*38fd1498Szrj      containing references to that register, and only those,
164*38fd1498Szrj      must be removed.
165*38fd1498Szrj 
166*38fd1498Szrj    Because searching the entire hash table for expressions that contain
167*38fd1498Szrj    a register is very slow, we try to figure out when it isn't necessary.
168*38fd1498Szrj    Precisely, this is necessary only when expressions have been
169*38fd1498Szrj    entered in the hash table using this register, and then the value has
170*38fd1498Szrj    changed, and then another expression wants to be added to refer to
171*38fd1498Szrj    the register's new value.  This sequence of circumstances is rare
172*38fd1498Szrj    within any one basic block.
173*38fd1498Szrj 
174*38fd1498Szrj    `REG_TICK' and `REG_IN_TABLE', accessors for members of
175*38fd1498Szrj    cse_reg_info, are used to detect this case.  REG_TICK (i) is
176*38fd1498Szrj    incremented whenever a value is stored in register i.
177*38fd1498Szrj    REG_IN_TABLE (i) holds -1 if no references to register i have been
178*38fd1498Szrj    entered in the table; otherwise, it contains the value REG_TICK (i)
179*38fd1498Szrj    had when the references were entered.  If we want to enter a
180*38fd1498Szrj    reference and REG_IN_TABLE (i) != REG_TICK (i), we must scan and
181*38fd1498Szrj    remove old references.  Until we want to enter a new entry, the
182*38fd1498Szrj    mere fact that the two vectors don't match makes the entries be
183*38fd1498Szrj    ignored if anyone tries to match them.
184*38fd1498Szrj 
185*38fd1498Szrj    Registers themselves are entered in the hash table as well as in
186*38fd1498Szrj    the equivalent-register chains.  However, `REG_TICK' and
187*38fd1498Szrj    `REG_IN_TABLE' do not apply to expressions which are simple
188*38fd1498Szrj    register references.  These expressions are removed from the table
189*38fd1498Szrj    immediately when they become invalid, and this can be done even if
190*38fd1498Szrj    we do not immediately search for all the expressions that refer to
191*38fd1498Szrj    the register.
192*38fd1498Szrj 
193*38fd1498Szrj    A CLOBBER rtx in an instruction invalidates its operand for further
194*38fd1498Szrj    reuse.  A CLOBBER or SET rtx whose operand is a MEM:BLK
195*38fd1498Szrj    invalidates everything that resides in memory.
196*38fd1498Szrj 
197*38fd1498Szrj Related expressions:
198*38fd1498Szrj 
199*38fd1498Szrj    Constant expressions that differ only by an additive integer
200*38fd1498Szrj    are called related.  When a constant expression is put in
201*38fd1498Szrj    the table, the related expression with no constant term
202*38fd1498Szrj    is also entered.  These are made to point at each other
203*38fd1498Szrj    so that it is possible to find out if there exists any
204*38fd1498Szrj    register equivalent to an expression related to a given expression.  */
205*38fd1498Szrj 
206*38fd1498Szrj /* Length of qty_table vector.  We know in advance we will not need
207*38fd1498Szrj    a quantity number this big.  */
208*38fd1498Szrj 
209*38fd1498Szrj static int max_qty;
210*38fd1498Szrj 
211*38fd1498Szrj /* Next quantity number to be allocated.
212*38fd1498Szrj    This is 1 + the largest number needed so far.  */
213*38fd1498Szrj 
214*38fd1498Szrj static int next_qty;
215*38fd1498Szrj 
216*38fd1498Szrj /* Per-qty information tracking.
217*38fd1498Szrj 
218*38fd1498Szrj    `first_reg' and `last_reg' track the head and tail of the
219*38fd1498Szrj    chain of registers which currently contain this quantity.
220*38fd1498Szrj 
221*38fd1498Szrj    `mode' contains the machine mode of this quantity.
222*38fd1498Szrj 
223*38fd1498Szrj    `const_rtx' holds the rtx of the constant value of this
224*38fd1498Szrj    quantity, if known.  A summations of the frame/arg pointer
225*38fd1498Szrj    and a constant can also be entered here.  When this holds
226*38fd1498Szrj    a known value, `const_insn' is the insn which stored the
227*38fd1498Szrj    constant value.
228*38fd1498Szrj 
229*38fd1498Szrj    `comparison_{code,const,qty}' are used to track when a
230*38fd1498Szrj    comparison between a quantity and some constant or register has
231*38fd1498Szrj    been passed.  In such a case, we know the results of the comparison
232*38fd1498Szrj    in case we see it again.  These members record a comparison that
233*38fd1498Szrj    is known to be true.  `comparison_code' holds the rtx code of such
234*38fd1498Szrj    a comparison, else it is set to UNKNOWN and the other two
235*38fd1498Szrj    comparison members are undefined.  `comparison_const' holds
236*38fd1498Szrj    the constant being compared against, or zero if the comparison
237*38fd1498Szrj    is not against a constant.  `comparison_qty' holds the quantity
238*38fd1498Szrj    being compared against when the result is known.  If the comparison
239*38fd1498Szrj    is not with a register, `comparison_qty' is -1.  */
240*38fd1498Szrj 
241*38fd1498Szrj struct qty_table_elem
242*38fd1498Szrj {
243*38fd1498Szrj   rtx const_rtx;
244*38fd1498Szrj   rtx_insn *const_insn;
245*38fd1498Szrj   rtx comparison_const;
246*38fd1498Szrj   int comparison_qty;
247*38fd1498Szrj   unsigned int first_reg, last_reg;
248*38fd1498Szrj   /* The sizes of these fields should match the sizes of the
249*38fd1498Szrj      code and mode fields of struct rtx_def (see rtl.h).  */
250*38fd1498Szrj   ENUM_BITFIELD(rtx_code) comparison_code : 16;
251*38fd1498Szrj   ENUM_BITFIELD(machine_mode) mode : 8;
252*38fd1498Szrj };
253*38fd1498Szrj 
254*38fd1498Szrj /* The table of all qtys, indexed by qty number.  */
255*38fd1498Szrj static struct qty_table_elem *qty_table;
256*38fd1498Szrj 
257*38fd1498Szrj /* For machines that have a CC0, we do not record its value in the hash
258*38fd1498Szrj    table since its use is guaranteed to be the insn immediately following
259*38fd1498Szrj    its definition and any other insn is presumed to invalidate it.
260*38fd1498Szrj 
261*38fd1498Szrj    Instead, we store below the current and last value assigned to CC0.
262*38fd1498Szrj    If it should happen to be a constant, it is stored in preference
263*38fd1498Szrj    to the actual assigned value.  In case it is a constant, we store
264*38fd1498Szrj    the mode in which the constant should be interpreted.  */
265*38fd1498Szrj 
266*38fd1498Szrj static rtx this_insn_cc0, prev_insn_cc0;
267*38fd1498Szrj static machine_mode this_insn_cc0_mode, prev_insn_cc0_mode;
268*38fd1498Szrj 
269*38fd1498Szrj /* Insn being scanned.  */
270*38fd1498Szrj 
271*38fd1498Szrj static rtx_insn *this_insn;
272*38fd1498Szrj static bool optimize_this_for_speed_p;
273*38fd1498Szrj 
274*38fd1498Szrj /* Index by register number, gives the number of the next (or
275*38fd1498Szrj    previous) register in the chain of registers sharing the same
276*38fd1498Szrj    value.
277*38fd1498Szrj 
278*38fd1498Szrj    Or -1 if this register is at the end of the chain.
279*38fd1498Szrj 
280*38fd1498Szrj    If REG_QTY (N) == -N - 1, reg_eqv_table[N].next is undefined.  */
281*38fd1498Szrj 
282*38fd1498Szrj /* Per-register equivalence chain.  */
283*38fd1498Szrj struct reg_eqv_elem
284*38fd1498Szrj {
285*38fd1498Szrj   int next, prev;
286*38fd1498Szrj };
287*38fd1498Szrj 
288*38fd1498Szrj /* The table of all register equivalence chains.  */
289*38fd1498Szrj static struct reg_eqv_elem *reg_eqv_table;
290*38fd1498Szrj 
291*38fd1498Szrj struct cse_reg_info
292*38fd1498Szrj {
293*38fd1498Szrj   /* The timestamp at which this register is initialized.  */
294*38fd1498Szrj   unsigned int timestamp;
295*38fd1498Szrj 
296*38fd1498Szrj   /* The quantity number of the register's current contents.  */
297*38fd1498Szrj   int reg_qty;
298*38fd1498Szrj 
299*38fd1498Szrj   /* The number of times the register has been altered in the current
300*38fd1498Szrj      basic block.  */
301*38fd1498Szrj   int reg_tick;
302*38fd1498Szrj 
303*38fd1498Szrj   /* The REG_TICK value at which rtx's containing this register are
304*38fd1498Szrj      valid in the hash table.  If this does not equal the current
305*38fd1498Szrj      reg_tick value, such expressions existing in the hash table are
306*38fd1498Szrj      invalid.  */
307*38fd1498Szrj   int reg_in_table;
308*38fd1498Szrj 
309*38fd1498Szrj   /* The SUBREG that was set when REG_TICK was last incremented.  Set
310*38fd1498Szrj      to -1 if the last store was to the whole register, not a subreg.  */
311*38fd1498Szrj   unsigned int subreg_ticked;
312*38fd1498Szrj };
313*38fd1498Szrj 
314*38fd1498Szrj /* A table of cse_reg_info indexed by register numbers.  */
315*38fd1498Szrj static struct cse_reg_info *cse_reg_info_table;
316*38fd1498Szrj 
317*38fd1498Szrj /* The size of the above table.  */
318*38fd1498Szrj static unsigned int cse_reg_info_table_size;
319*38fd1498Szrj 
320*38fd1498Szrj /* The index of the first entry that has not been initialized.  */
321*38fd1498Szrj static unsigned int cse_reg_info_table_first_uninitialized;
322*38fd1498Szrj 
323*38fd1498Szrj /* The timestamp at the beginning of the current run of
324*38fd1498Szrj    cse_extended_basic_block.  We increment this variable at the beginning of
325*38fd1498Szrj    the current run of cse_extended_basic_block.  The timestamp field of a
326*38fd1498Szrj    cse_reg_info entry matches the value of this variable if and only
327*38fd1498Szrj    if the entry has been initialized during the current run of
328*38fd1498Szrj    cse_extended_basic_block.  */
329*38fd1498Szrj static unsigned int cse_reg_info_timestamp;
330*38fd1498Szrj 
331*38fd1498Szrj /* A HARD_REG_SET containing all the hard registers for which there is
332*38fd1498Szrj    currently a REG expression in the hash table.  Note the difference
333*38fd1498Szrj    from the above variables, which indicate if the REG is mentioned in some
334*38fd1498Szrj    expression in the table.  */
335*38fd1498Szrj 
336*38fd1498Szrj static HARD_REG_SET hard_regs_in_table;
337*38fd1498Szrj 
338*38fd1498Szrj /* True if CSE has altered the CFG.  */
339*38fd1498Szrj static bool cse_cfg_altered;
340*38fd1498Szrj 
341*38fd1498Szrj /* True if CSE has altered conditional jump insns in such a way
342*38fd1498Szrj    that jump optimization should be redone.  */
343*38fd1498Szrj static bool cse_jumps_altered;
344*38fd1498Szrj 
345*38fd1498Szrj /* True if we put a LABEL_REF into the hash table for an INSN
346*38fd1498Szrj    without a REG_LABEL_OPERAND, we have to rerun jump after CSE
347*38fd1498Szrj    to put in the note.  */
348*38fd1498Szrj static bool recorded_label_ref;
349*38fd1498Szrj 
350*38fd1498Szrj /* canon_hash stores 1 in do_not_record
351*38fd1498Szrj    if it notices a reference to CC0, PC, or some other volatile
352*38fd1498Szrj    subexpression.  */
353*38fd1498Szrj 
354*38fd1498Szrj static int do_not_record;
355*38fd1498Szrj 
356*38fd1498Szrj /* canon_hash stores 1 in hash_arg_in_memory
357*38fd1498Szrj    if it notices a reference to memory within the expression being hashed.  */
358*38fd1498Szrj 
359*38fd1498Szrj static int hash_arg_in_memory;
360*38fd1498Szrj 
361*38fd1498Szrj /* The hash table contains buckets which are chains of `struct table_elt's,
362*38fd1498Szrj    each recording one expression's information.
363*38fd1498Szrj    That expression is in the `exp' field.
364*38fd1498Szrj 
365*38fd1498Szrj    The canon_exp field contains a canonical (from the point of view of
366*38fd1498Szrj    alias analysis) version of the `exp' field.
367*38fd1498Szrj 
368*38fd1498Szrj    Those elements with the same hash code are chained in both directions
369*38fd1498Szrj    through the `next_same_hash' and `prev_same_hash' fields.
370*38fd1498Szrj 
371*38fd1498Szrj    Each set of expressions with equivalent values
372*38fd1498Szrj    are on a two-way chain through the `next_same_value'
373*38fd1498Szrj    and `prev_same_value' fields, and all point with
374*38fd1498Szrj    the `first_same_value' field at the first element in
375*38fd1498Szrj    that chain.  The chain is in order of increasing cost.
376*38fd1498Szrj    Each element's cost value is in its `cost' field.
377*38fd1498Szrj 
378*38fd1498Szrj    The `in_memory' field is nonzero for elements that
379*38fd1498Szrj    involve any reference to memory.  These elements are removed
380*38fd1498Szrj    whenever a write is done to an unidentified location in memory.
381*38fd1498Szrj    To be safe, we assume that a memory address is unidentified unless
382*38fd1498Szrj    the address is either a symbol constant or a constant plus
383*38fd1498Szrj    the frame pointer or argument pointer.
384*38fd1498Szrj 
385*38fd1498Szrj    The `related_value' field is used to connect related expressions
386*38fd1498Szrj    (that differ by adding an integer).
387*38fd1498Szrj    The related expressions are chained in a circular fashion.
388*38fd1498Szrj    `related_value' is zero for expressions for which this
389*38fd1498Szrj    chain is not useful.
390*38fd1498Szrj 
391*38fd1498Szrj    The `cost' field stores the cost of this element's expression.
392*38fd1498Szrj    The `regcost' field stores the value returned by approx_reg_cost for
393*38fd1498Szrj    this element's expression.
394*38fd1498Szrj 
395*38fd1498Szrj    The `is_const' flag is set if the element is a constant (including
396*38fd1498Szrj    a fixed address).
397*38fd1498Szrj 
398*38fd1498Szrj    The `flag' field is used as a temporary during some search routines.
399*38fd1498Szrj 
400*38fd1498Szrj    The `mode' field is usually the same as GET_MODE (`exp'), but
401*38fd1498Szrj    if `exp' is a CONST_INT and has no machine mode then the `mode'
402*38fd1498Szrj    field is the mode it was being used as.  Each constant is
403*38fd1498Szrj    recorded separately for each mode it is used with.  */
404*38fd1498Szrj 
405*38fd1498Szrj struct table_elt
406*38fd1498Szrj {
407*38fd1498Szrj   rtx exp;
408*38fd1498Szrj   rtx canon_exp;
409*38fd1498Szrj   struct table_elt *next_same_hash;
410*38fd1498Szrj   struct table_elt *prev_same_hash;
411*38fd1498Szrj   struct table_elt *next_same_value;
412*38fd1498Szrj   struct table_elt *prev_same_value;
413*38fd1498Szrj   struct table_elt *first_same_value;
414*38fd1498Szrj   struct table_elt *related_value;
415*38fd1498Szrj   int cost;
416*38fd1498Szrj   int regcost;
417*38fd1498Szrj   /* The size of this field should match the size
418*38fd1498Szrj      of the mode field of struct rtx_def (see rtl.h).  */
419*38fd1498Szrj   ENUM_BITFIELD(machine_mode) mode : 8;
420*38fd1498Szrj   char in_memory;
421*38fd1498Szrj   char is_const;
422*38fd1498Szrj   char flag;
423*38fd1498Szrj };
424*38fd1498Szrj 
425*38fd1498Szrj /* We don't want a lot of buckets, because we rarely have very many
426*38fd1498Szrj    things stored in the hash table, and a lot of buckets slows
427*38fd1498Szrj    down a lot of loops that happen frequently.  */
428*38fd1498Szrj #define HASH_SHIFT	5
429*38fd1498Szrj #define HASH_SIZE	(1 << HASH_SHIFT)
430*38fd1498Szrj #define HASH_MASK	(HASH_SIZE - 1)
431*38fd1498Szrj 
432*38fd1498Szrj /* Compute hash code of X in mode M.  Special-case case where X is a pseudo
433*38fd1498Szrj    register (hard registers may require `do_not_record' to be set).  */
434*38fd1498Szrj 
435*38fd1498Szrj #define HASH(X, M)	\
436*38fd1498Szrj  ((REG_P (X) && REGNO (X) >= FIRST_PSEUDO_REGISTER	\
437*38fd1498Szrj   ? (((unsigned) REG << 7) + (unsigned) REG_QTY (REGNO (X)))	\
438*38fd1498Szrj   : canon_hash (X, M)) & HASH_MASK)
439*38fd1498Szrj 
440*38fd1498Szrj /* Like HASH, but without side-effects.  */
441*38fd1498Szrj #define SAFE_HASH(X, M)	\
442*38fd1498Szrj  ((REG_P (X) && REGNO (X) >= FIRST_PSEUDO_REGISTER	\
443*38fd1498Szrj   ? (((unsigned) REG << 7) + (unsigned) REG_QTY (REGNO (X)))	\
444*38fd1498Szrj   : safe_hash (X, M)) & HASH_MASK)
445*38fd1498Szrj 
446*38fd1498Szrj /* Determine whether register number N is considered a fixed register for the
447*38fd1498Szrj    purpose of approximating register costs.
448*38fd1498Szrj    It is desirable to replace other regs with fixed regs, to reduce need for
449*38fd1498Szrj    non-fixed hard regs.
450*38fd1498Szrj    A reg wins if it is either the frame pointer or designated as fixed.  */
451*38fd1498Szrj #define FIXED_REGNO_P(N)  \
452*38fd1498Szrj   ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \
453*38fd1498Szrj    || fixed_regs[N] || global_regs[N])
454*38fd1498Szrj 
455*38fd1498Szrj /* Compute cost of X, as stored in the `cost' field of a table_elt.  Fixed
456*38fd1498Szrj    hard registers and pointers into the frame are the cheapest with a cost
457*38fd1498Szrj    of 0.  Next come pseudos with a cost of one and other hard registers with
458*38fd1498Szrj    a cost of 2.  Aside from these special cases, call `rtx_cost'.  */
459*38fd1498Szrj 
460*38fd1498Szrj #define CHEAP_REGNO(N)							\
461*38fd1498Szrj   (REGNO_PTR_FRAME_P (N)						\
462*38fd1498Szrj    || (HARD_REGISTER_NUM_P (N)						\
463*38fd1498Szrj        && FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS))
464*38fd1498Szrj 
465*38fd1498Szrj #define COST(X, MODE)							\
466*38fd1498Szrj   (REG_P (X) ? 0 : notreg_cost (X, MODE, SET, 1))
467*38fd1498Szrj #define COST_IN(X, MODE, OUTER, OPNO)					\
468*38fd1498Szrj   (REG_P (X) ? 0 : notreg_cost (X, MODE, OUTER, OPNO))
469*38fd1498Szrj 
470*38fd1498Szrj /* Get the number of times this register has been updated in this
471*38fd1498Szrj    basic block.  */
472*38fd1498Szrj 
473*38fd1498Szrj #define REG_TICK(N) (get_cse_reg_info (N)->reg_tick)
474*38fd1498Szrj 
475*38fd1498Szrj /* Get the point at which REG was recorded in the table.  */
476*38fd1498Szrj 
477*38fd1498Szrj #define REG_IN_TABLE(N) (get_cse_reg_info (N)->reg_in_table)
478*38fd1498Szrj 
479*38fd1498Szrj /* Get the SUBREG set at the last increment to REG_TICK (-1 if not a
480*38fd1498Szrj    SUBREG).  */
481*38fd1498Szrj 
482*38fd1498Szrj #define SUBREG_TICKED(N) (get_cse_reg_info (N)->subreg_ticked)
483*38fd1498Szrj 
484*38fd1498Szrj /* Get the quantity number for REG.  */
485*38fd1498Szrj 
486*38fd1498Szrj #define REG_QTY(N) (get_cse_reg_info (N)->reg_qty)
487*38fd1498Szrj 
488*38fd1498Szrj /* Determine if the quantity number for register X represents a valid index
489*38fd1498Szrj    into the qty_table.  */
490*38fd1498Szrj 
491*38fd1498Szrj #define REGNO_QTY_VALID_P(N) (REG_QTY (N) >= 0)
492*38fd1498Szrj 
493*38fd1498Szrj /* Compare table_elt X and Y and return true iff X is cheaper than Y.  */
494*38fd1498Szrj 
495*38fd1498Szrj #define CHEAPER(X, Y) \
496*38fd1498Szrj  (preferable ((X)->cost, (X)->regcost, (Y)->cost, (Y)->regcost) < 0)
497*38fd1498Szrj 
498*38fd1498Szrj static struct table_elt *table[HASH_SIZE];
499*38fd1498Szrj 
500*38fd1498Szrj /* Chain of `struct table_elt's made so far for this function
501*38fd1498Szrj    but currently removed from the table.  */
502*38fd1498Szrj 
503*38fd1498Szrj static struct table_elt *free_element_chain;
504*38fd1498Szrj 
505*38fd1498Szrj /* Set to the cost of a constant pool reference if one was found for a
506*38fd1498Szrj    symbolic constant.  If this was found, it means we should try to
507*38fd1498Szrj    convert constants into constant pool entries if they don't fit in
508*38fd1498Szrj    the insn.  */
509*38fd1498Szrj 
510*38fd1498Szrj static int constant_pool_entries_cost;
511*38fd1498Szrj static int constant_pool_entries_regcost;
512*38fd1498Szrj 
513*38fd1498Szrj /* Trace a patch through the CFG.  */
514*38fd1498Szrj 
515*38fd1498Szrj struct branch_path
516*38fd1498Szrj {
517*38fd1498Szrj   /* The basic block for this path entry.  */
518*38fd1498Szrj   basic_block bb;
519*38fd1498Szrj };
520*38fd1498Szrj 
521*38fd1498Szrj /* This data describes a block that will be processed by
522*38fd1498Szrj    cse_extended_basic_block.  */
523*38fd1498Szrj 
524*38fd1498Szrj struct cse_basic_block_data
525*38fd1498Szrj {
526*38fd1498Szrj   /* Total number of SETs in block.  */
527*38fd1498Szrj   int nsets;
528*38fd1498Szrj   /* Size of current branch path, if any.  */
529*38fd1498Szrj   int path_size;
530*38fd1498Szrj   /* Current path, indicating which basic_blocks will be processed.  */
531*38fd1498Szrj   struct branch_path *path;
532*38fd1498Szrj };
533*38fd1498Szrj 
534*38fd1498Szrj 
535*38fd1498Szrj /* Pointers to the live in/live out bitmaps for the boundaries of the
536*38fd1498Szrj    current EBB.  */
537*38fd1498Szrj static bitmap cse_ebb_live_in, cse_ebb_live_out;
538*38fd1498Szrj 
539*38fd1498Szrj /* A simple bitmap to track which basic blocks have been visited
540*38fd1498Szrj    already as part of an already processed extended basic block.  */
541*38fd1498Szrj static sbitmap cse_visited_basic_blocks;
542*38fd1498Szrj 
543*38fd1498Szrj static bool fixed_base_plus_p (rtx x);
544*38fd1498Szrj static int notreg_cost (rtx, machine_mode, enum rtx_code, int);
545*38fd1498Szrj static int preferable (int, int, int, int);
546*38fd1498Szrj static void new_basic_block (void);
547*38fd1498Szrj static void make_new_qty (unsigned int, machine_mode);
548*38fd1498Szrj static void make_regs_eqv (unsigned int, unsigned int);
549*38fd1498Szrj static void delete_reg_equiv (unsigned int);
550*38fd1498Szrj static int mention_regs (rtx);
551*38fd1498Szrj static int insert_regs (rtx, struct table_elt *, int);
552*38fd1498Szrj static void remove_from_table (struct table_elt *, unsigned);
553*38fd1498Szrj static void remove_pseudo_from_table (rtx, unsigned);
554*38fd1498Szrj static struct table_elt *lookup (rtx, unsigned, machine_mode);
555*38fd1498Szrj static struct table_elt *lookup_for_remove (rtx, unsigned, machine_mode);
556*38fd1498Szrj static rtx lookup_as_function (rtx, enum rtx_code);
557*38fd1498Szrj static struct table_elt *insert_with_costs (rtx, struct table_elt *, unsigned,
558*38fd1498Szrj 					    machine_mode, int, int);
559*38fd1498Szrj static struct table_elt *insert (rtx, struct table_elt *, unsigned,
560*38fd1498Szrj 				 machine_mode);
561*38fd1498Szrj static void merge_equiv_classes (struct table_elt *, struct table_elt *);
562*38fd1498Szrj static void invalidate (rtx, machine_mode);
563*38fd1498Szrj static void remove_invalid_refs (unsigned int);
564*38fd1498Szrj static void remove_invalid_subreg_refs (unsigned int, poly_uint64,
565*38fd1498Szrj 					machine_mode);
566*38fd1498Szrj static void rehash_using_reg (rtx);
567*38fd1498Szrj static void invalidate_memory (void);
568*38fd1498Szrj static void invalidate_for_call (void);
569*38fd1498Szrj static rtx use_related_value (rtx, struct table_elt *);
570*38fd1498Szrj 
571*38fd1498Szrj static inline unsigned canon_hash (rtx, machine_mode);
572*38fd1498Szrj static inline unsigned safe_hash (rtx, machine_mode);
573*38fd1498Szrj static inline unsigned hash_rtx_string (const char *);
574*38fd1498Szrj 
575*38fd1498Szrj static rtx canon_reg (rtx, rtx_insn *);
576*38fd1498Szrj static enum rtx_code find_comparison_args (enum rtx_code, rtx *, rtx *,
577*38fd1498Szrj 					   machine_mode *,
578*38fd1498Szrj 					   machine_mode *);
579*38fd1498Szrj static rtx fold_rtx (rtx, rtx_insn *);
580*38fd1498Szrj static rtx equiv_constant (rtx);
581*38fd1498Szrj static void record_jump_equiv (rtx_insn *, bool);
582*38fd1498Szrj static void record_jump_cond (enum rtx_code, machine_mode, rtx, rtx,
583*38fd1498Szrj 			      int);
584*38fd1498Szrj static void cse_insn (rtx_insn *);
585*38fd1498Szrj static void cse_prescan_path (struct cse_basic_block_data *);
586*38fd1498Szrj static void invalidate_from_clobbers (rtx_insn *);
587*38fd1498Szrj static void invalidate_from_sets_and_clobbers (rtx_insn *);
588*38fd1498Szrj static rtx cse_process_notes (rtx, rtx, bool *);
589*38fd1498Szrj static void cse_extended_basic_block (struct cse_basic_block_data *);
590*38fd1498Szrj extern void dump_class (struct table_elt*);
591*38fd1498Szrj static void get_cse_reg_info_1 (unsigned int regno);
592*38fd1498Szrj static struct cse_reg_info * get_cse_reg_info (unsigned int regno);
593*38fd1498Szrj 
594*38fd1498Szrj static void flush_hash_table (void);
595*38fd1498Szrj static bool insn_live_p (rtx_insn *, int *);
596*38fd1498Szrj static bool set_live_p (rtx, rtx_insn *, int *);
597*38fd1498Szrj static void cse_change_cc_mode_insn (rtx_insn *, rtx);
598*38fd1498Szrj static void cse_change_cc_mode_insns (rtx_insn *, rtx_insn *, rtx);
599*38fd1498Szrj static machine_mode cse_cc_succs (basic_block, basic_block, rtx, rtx,
600*38fd1498Szrj 				       bool);
601*38fd1498Szrj 
602*38fd1498Szrj 
603*38fd1498Szrj #undef RTL_HOOKS_GEN_LOWPART
604*38fd1498Szrj #define RTL_HOOKS_GEN_LOWPART		gen_lowpart_if_possible
605*38fd1498Szrj 
606*38fd1498Szrj static const struct rtl_hooks cse_rtl_hooks = RTL_HOOKS_INITIALIZER;
607*38fd1498Szrj 
608*38fd1498Szrj /* Nonzero if X has the form (PLUS frame-pointer integer).  */
609*38fd1498Szrj 
610*38fd1498Szrj static bool
fixed_base_plus_p(rtx x)611*38fd1498Szrj fixed_base_plus_p (rtx x)
612*38fd1498Szrj {
613*38fd1498Szrj   switch (GET_CODE (x))
614*38fd1498Szrj     {
615*38fd1498Szrj     case REG:
616*38fd1498Szrj       if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx)
617*38fd1498Szrj 	return true;
618*38fd1498Szrj       if (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM])
619*38fd1498Szrj 	return true;
620*38fd1498Szrj       return false;
621*38fd1498Szrj 
622*38fd1498Szrj     case PLUS:
623*38fd1498Szrj       if (!CONST_INT_P (XEXP (x, 1)))
624*38fd1498Szrj 	return false;
625*38fd1498Szrj       return fixed_base_plus_p (XEXP (x, 0));
626*38fd1498Szrj 
627*38fd1498Szrj     default:
628*38fd1498Szrj       return false;
629*38fd1498Szrj     }
630*38fd1498Szrj }
631*38fd1498Szrj 
632*38fd1498Szrj /* Dump the expressions in the equivalence class indicated by CLASSP.
633*38fd1498Szrj    This function is used only for debugging.  */
634*38fd1498Szrj DEBUG_FUNCTION void
dump_class(struct table_elt * classp)635*38fd1498Szrj dump_class (struct table_elt *classp)
636*38fd1498Szrj {
637*38fd1498Szrj   struct table_elt *elt;
638*38fd1498Szrj 
639*38fd1498Szrj   fprintf (stderr, "Equivalence chain for ");
640*38fd1498Szrj   print_rtl (stderr, classp->exp);
641*38fd1498Szrj   fprintf (stderr, ": \n");
642*38fd1498Szrj 
643*38fd1498Szrj   for (elt = classp->first_same_value; elt; elt = elt->next_same_value)
644*38fd1498Szrj     {
645*38fd1498Szrj       print_rtl (stderr, elt->exp);
646*38fd1498Szrj       fprintf (stderr, "\n");
647*38fd1498Szrj     }
648*38fd1498Szrj }
649*38fd1498Szrj 
650*38fd1498Szrj /* Return an estimate of the cost of the registers used in an rtx.
651*38fd1498Szrj    This is mostly the number of different REG expressions in the rtx;
652*38fd1498Szrj    however for some exceptions like fixed registers we use a cost of
653*38fd1498Szrj    0.  If any other hard register reference occurs, return MAX_COST.  */
654*38fd1498Szrj 
655*38fd1498Szrj static int
approx_reg_cost(const_rtx x)656*38fd1498Szrj approx_reg_cost (const_rtx x)
657*38fd1498Szrj {
658*38fd1498Szrj   int cost = 0;
659*38fd1498Szrj   subrtx_iterator::array_type array;
660*38fd1498Szrj   FOR_EACH_SUBRTX (iter, array, x, NONCONST)
661*38fd1498Szrj     {
662*38fd1498Szrj       const_rtx x = *iter;
663*38fd1498Szrj       if (REG_P (x))
664*38fd1498Szrj 	{
665*38fd1498Szrj 	  unsigned int regno = REGNO (x);
666*38fd1498Szrj 	  if (!CHEAP_REGNO (regno))
667*38fd1498Szrj 	    {
668*38fd1498Szrj 	      if (regno < FIRST_PSEUDO_REGISTER)
669*38fd1498Szrj 		{
670*38fd1498Szrj 		  if (targetm.small_register_classes_for_mode_p (GET_MODE (x)))
671*38fd1498Szrj 		    return MAX_COST;
672*38fd1498Szrj 		  cost += 2;
673*38fd1498Szrj 		}
674*38fd1498Szrj 	      else
675*38fd1498Szrj 		cost += 1;
676*38fd1498Szrj 	    }
677*38fd1498Szrj 	}
678*38fd1498Szrj     }
679*38fd1498Szrj   return cost;
680*38fd1498Szrj }
681*38fd1498Szrj 
682*38fd1498Szrj /* Return a negative value if an rtx A, whose costs are given by COST_A
683*38fd1498Szrj    and REGCOST_A, is more desirable than an rtx B.
684*38fd1498Szrj    Return a positive value if A is less desirable, or 0 if the two are
685*38fd1498Szrj    equally good.  */
686*38fd1498Szrj static int
preferable(int cost_a,int regcost_a,int cost_b,int regcost_b)687*38fd1498Szrj preferable (int cost_a, int regcost_a, int cost_b, int regcost_b)
688*38fd1498Szrj {
689*38fd1498Szrj   /* First, get rid of cases involving expressions that are entirely
690*38fd1498Szrj      unwanted.  */
691*38fd1498Szrj   if (cost_a != cost_b)
692*38fd1498Szrj     {
693*38fd1498Szrj       if (cost_a == MAX_COST)
694*38fd1498Szrj 	return 1;
695*38fd1498Szrj       if (cost_b == MAX_COST)
696*38fd1498Szrj 	return -1;
697*38fd1498Szrj     }
698*38fd1498Szrj 
699*38fd1498Szrj   /* Avoid extending lifetimes of hardregs.  */
700*38fd1498Szrj   if (regcost_a != regcost_b)
701*38fd1498Szrj     {
702*38fd1498Szrj       if (regcost_a == MAX_COST)
703*38fd1498Szrj 	return 1;
704*38fd1498Szrj       if (regcost_b == MAX_COST)
705*38fd1498Szrj 	return -1;
706*38fd1498Szrj     }
707*38fd1498Szrj 
708*38fd1498Szrj   /* Normal operation costs take precedence.  */
709*38fd1498Szrj   if (cost_a != cost_b)
710*38fd1498Szrj     return cost_a - cost_b;
711*38fd1498Szrj   /* Only if these are identical consider effects on register pressure.  */
712*38fd1498Szrj   if (regcost_a != regcost_b)
713*38fd1498Szrj     return regcost_a - regcost_b;
714*38fd1498Szrj   return 0;
715*38fd1498Szrj }
716*38fd1498Szrj 
717*38fd1498Szrj /* Internal function, to compute cost when X is not a register; called
718*38fd1498Szrj    from COST macro to keep it simple.  */
719*38fd1498Szrj 
720*38fd1498Szrj static int
notreg_cost(rtx x,machine_mode mode,enum rtx_code outer,int opno)721*38fd1498Szrj notreg_cost (rtx x, machine_mode mode, enum rtx_code outer, int opno)
722*38fd1498Szrj {
723*38fd1498Szrj   scalar_int_mode int_mode, inner_mode;
724*38fd1498Szrj   return ((GET_CODE (x) == SUBREG
725*38fd1498Szrj 	   && REG_P (SUBREG_REG (x))
726*38fd1498Szrj 	   && is_int_mode (mode, &int_mode)
727*38fd1498Szrj 	   && is_int_mode (GET_MODE (SUBREG_REG (x)), &inner_mode)
728*38fd1498Szrj 	   && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
729*38fd1498Szrj 	   && subreg_lowpart_p (x)
730*38fd1498Szrj 	   && TRULY_NOOP_TRUNCATION_MODES_P (int_mode, inner_mode))
731*38fd1498Szrj 	  ? 0
732*38fd1498Szrj 	  : rtx_cost (x, mode, outer, opno, optimize_this_for_speed_p) * 2);
733*38fd1498Szrj }
734*38fd1498Szrj 
735*38fd1498Szrj 
736*38fd1498Szrj /* Initialize CSE_REG_INFO_TABLE.  */
737*38fd1498Szrj 
738*38fd1498Szrj static void
init_cse_reg_info(unsigned int nregs)739*38fd1498Szrj init_cse_reg_info (unsigned int nregs)
740*38fd1498Szrj {
741*38fd1498Szrj   /* Do we need to grow the table?  */
742*38fd1498Szrj   if (nregs > cse_reg_info_table_size)
743*38fd1498Szrj     {
744*38fd1498Szrj       unsigned int new_size;
745*38fd1498Szrj 
746*38fd1498Szrj       if (cse_reg_info_table_size < 2048)
747*38fd1498Szrj 	{
748*38fd1498Szrj 	  /* Compute a new size that is a power of 2 and no smaller
749*38fd1498Szrj 	     than the large of NREGS and 64.  */
750*38fd1498Szrj 	  new_size = (cse_reg_info_table_size
751*38fd1498Szrj 		      ? cse_reg_info_table_size : 64);
752*38fd1498Szrj 
753*38fd1498Szrj 	  while (new_size < nregs)
754*38fd1498Szrj 	    new_size *= 2;
755*38fd1498Szrj 	}
756*38fd1498Szrj       else
757*38fd1498Szrj 	{
758*38fd1498Szrj 	  /* If we need a big table, allocate just enough to hold
759*38fd1498Szrj 	     NREGS registers.  */
760*38fd1498Szrj 	  new_size = nregs;
761*38fd1498Szrj 	}
762*38fd1498Szrj 
763*38fd1498Szrj       /* Reallocate the table with NEW_SIZE entries.  */
764*38fd1498Szrj       free (cse_reg_info_table);
765*38fd1498Szrj       cse_reg_info_table = XNEWVEC (struct cse_reg_info, new_size);
766*38fd1498Szrj       cse_reg_info_table_size = new_size;
767*38fd1498Szrj       cse_reg_info_table_first_uninitialized = 0;
768*38fd1498Szrj     }
769*38fd1498Szrj 
770*38fd1498Szrj   /* Do we have all of the first NREGS entries initialized?  */
771*38fd1498Szrj   if (cse_reg_info_table_first_uninitialized < nregs)
772*38fd1498Szrj     {
773*38fd1498Szrj       unsigned int old_timestamp = cse_reg_info_timestamp - 1;
774*38fd1498Szrj       unsigned int i;
775*38fd1498Szrj 
776*38fd1498Szrj       /* Put the old timestamp on newly allocated entries so that they
777*38fd1498Szrj 	 will all be considered out of date.  We do not touch those
778*38fd1498Szrj 	 entries beyond the first NREGS entries to be nice to the
779*38fd1498Szrj 	 virtual memory.  */
780*38fd1498Szrj       for (i = cse_reg_info_table_first_uninitialized; i < nregs; i++)
781*38fd1498Szrj 	cse_reg_info_table[i].timestamp = old_timestamp;
782*38fd1498Szrj 
783*38fd1498Szrj       cse_reg_info_table_first_uninitialized = nregs;
784*38fd1498Szrj     }
785*38fd1498Szrj }
786*38fd1498Szrj 
787*38fd1498Szrj /* Given REGNO, initialize the cse_reg_info entry for REGNO.  */
788*38fd1498Szrj 
789*38fd1498Szrj static void
get_cse_reg_info_1(unsigned int regno)790*38fd1498Szrj get_cse_reg_info_1 (unsigned int regno)
791*38fd1498Szrj {
792*38fd1498Szrj   /* Set TIMESTAMP field to CSE_REG_INFO_TIMESTAMP so that this
793*38fd1498Szrj      entry will be considered to have been initialized.  */
794*38fd1498Szrj   cse_reg_info_table[regno].timestamp = cse_reg_info_timestamp;
795*38fd1498Szrj 
796*38fd1498Szrj   /* Initialize the rest of the entry.  */
797*38fd1498Szrj   cse_reg_info_table[regno].reg_tick = 1;
798*38fd1498Szrj   cse_reg_info_table[regno].reg_in_table = -1;
799*38fd1498Szrj   cse_reg_info_table[regno].subreg_ticked = -1;
800*38fd1498Szrj   cse_reg_info_table[regno].reg_qty = -regno - 1;
801*38fd1498Szrj }
802*38fd1498Szrj 
803*38fd1498Szrj /* Find a cse_reg_info entry for REGNO.  */
804*38fd1498Szrj 
805*38fd1498Szrj static inline struct cse_reg_info *
get_cse_reg_info(unsigned int regno)806*38fd1498Szrj get_cse_reg_info (unsigned int regno)
807*38fd1498Szrj {
808*38fd1498Szrj   struct cse_reg_info *p = &cse_reg_info_table[regno];
809*38fd1498Szrj 
810*38fd1498Szrj   /* If this entry has not been initialized, go ahead and initialize
811*38fd1498Szrj      it.  */
812*38fd1498Szrj   if (p->timestamp != cse_reg_info_timestamp)
813*38fd1498Szrj     get_cse_reg_info_1 (regno);
814*38fd1498Szrj 
815*38fd1498Szrj   return p;
816*38fd1498Szrj }
817*38fd1498Szrj 
818*38fd1498Szrj /* Clear the hash table and initialize each register with its own quantity,
819*38fd1498Szrj    for a new basic block.  */
820*38fd1498Szrj 
821*38fd1498Szrj static void
new_basic_block(void)822*38fd1498Szrj new_basic_block (void)
823*38fd1498Szrj {
824*38fd1498Szrj   int i;
825*38fd1498Szrj 
826*38fd1498Szrj   next_qty = 0;
827*38fd1498Szrj 
828*38fd1498Szrj   /* Invalidate cse_reg_info_table.  */
829*38fd1498Szrj   cse_reg_info_timestamp++;
830*38fd1498Szrj 
831*38fd1498Szrj   /* Clear out hash table state for this pass.  */
832*38fd1498Szrj   CLEAR_HARD_REG_SET (hard_regs_in_table);
833*38fd1498Szrj 
834*38fd1498Szrj   /* The per-quantity values used to be initialized here, but it is
835*38fd1498Szrj      much faster to initialize each as it is made in `make_new_qty'.  */
836*38fd1498Szrj 
837*38fd1498Szrj   for (i = 0; i < HASH_SIZE; i++)
838*38fd1498Szrj     {
839*38fd1498Szrj       struct table_elt *first;
840*38fd1498Szrj 
841*38fd1498Szrj       first = table[i];
842*38fd1498Szrj       if (first != NULL)
843*38fd1498Szrj 	{
844*38fd1498Szrj 	  struct table_elt *last = first;
845*38fd1498Szrj 
846*38fd1498Szrj 	  table[i] = NULL;
847*38fd1498Szrj 
848*38fd1498Szrj 	  while (last->next_same_hash != NULL)
849*38fd1498Szrj 	    last = last->next_same_hash;
850*38fd1498Szrj 
851*38fd1498Szrj 	  /* Now relink this hash entire chain into
852*38fd1498Szrj 	     the free element list.  */
853*38fd1498Szrj 
854*38fd1498Szrj 	  last->next_same_hash = free_element_chain;
855*38fd1498Szrj 	  free_element_chain = first;
856*38fd1498Szrj 	}
857*38fd1498Szrj     }
858*38fd1498Szrj 
859*38fd1498Szrj   prev_insn_cc0 = 0;
860*38fd1498Szrj }
861*38fd1498Szrj 
862*38fd1498Szrj /* Say that register REG contains a quantity in mode MODE not in any
863*38fd1498Szrj    register before and initialize that quantity.  */
864*38fd1498Szrj 
865*38fd1498Szrj static void
make_new_qty(unsigned int reg,machine_mode mode)866*38fd1498Szrj make_new_qty (unsigned int reg, machine_mode mode)
867*38fd1498Szrj {
868*38fd1498Szrj   int q;
869*38fd1498Szrj   struct qty_table_elem *ent;
870*38fd1498Szrj   struct reg_eqv_elem *eqv;
871*38fd1498Szrj 
872*38fd1498Szrj   gcc_assert (next_qty < max_qty);
873*38fd1498Szrj 
874*38fd1498Szrj   q = REG_QTY (reg) = next_qty++;
875*38fd1498Szrj   ent = &qty_table[q];
876*38fd1498Szrj   ent->first_reg = reg;
877*38fd1498Szrj   ent->last_reg = reg;
878*38fd1498Szrj   ent->mode = mode;
879*38fd1498Szrj   ent->const_rtx = ent->const_insn = NULL;
880*38fd1498Szrj   ent->comparison_code = UNKNOWN;
881*38fd1498Szrj 
882*38fd1498Szrj   eqv = &reg_eqv_table[reg];
883*38fd1498Szrj   eqv->next = eqv->prev = -1;
884*38fd1498Szrj }
885*38fd1498Szrj 
886*38fd1498Szrj /* Make reg NEW equivalent to reg OLD.
887*38fd1498Szrj    OLD is not changing; NEW is.  */
888*38fd1498Szrj 
889*38fd1498Szrj static void
make_regs_eqv(unsigned int new_reg,unsigned int old_reg)890*38fd1498Szrj make_regs_eqv (unsigned int new_reg, unsigned int old_reg)
891*38fd1498Szrj {
892*38fd1498Szrj   unsigned int lastr, firstr;
893*38fd1498Szrj   int q = REG_QTY (old_reg);
894*38fd1498Szrj   struct qty_table_elem *ent;
895*38fd1498Szrj 
896*38fd1498Szrj   ent = &qty_table[q];
897*38fd1498Szrj 
898*38fd1498Szrj   /* Nothing should become eqv until it has a "non-invalid" qty number.  */
899*38fd1498Szrj   gcc_assert (REGNO_QTY_VALID_P (old_reg));
900*38fd1498Szrj 
901*38fd1498Szrj   REG_QTY (new_reg) = q;
902*38fd1498Szrj   firstr = ent->first_reg;
903*38fd1498Szrj   lastr = ent->last_reg;
904*38fd1498Szrj 
905*38fd1498Szrj   /* Prefer fixed hard registers to anything.  Prefer pseudo regs to other
906*38fd1498Szrj      hard regs.  Among pseudos, if NEW will live longer than any other reg
907*38fd1498Szrj      of the same qty, and that is beyond the current basic block,
908*38fd1498Szrj      make it the new canonical replacement for this qty.  */
909*38fd1498Szrj   if (! (firstr < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (firstr))
910*38fd1498Szrj       /* Certain fixed registers might be of the class NO_REGS.  This means
911*38fd1498Szrj 	 that not only can they not be allocated by the compiler, but
912*38fd1498Szrj 	 they cannot be used in substitutions or canonicalizations
913*38fd1498Szrj 	 either.  */
914*38fd1498Szrj       && (new_reg >= FIRST_PSEUDO_REGISTER || REGNO_REG_CLASS (new_reg) != NO_REGS)
915*38fd1498Szrj       && ((new_reg < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (new_reg))
916*38fd1498Szrj 	  || (new_reg >= FIRST_PSEUDO_REGISTER
917*38fd1498Szrj 	      && (firstr < FIRST_PSEUDO_REGISTER
918*38fd1498Szrj 		  || (bitmap_bit_p (cse_ebb_live_out, new_reg)
919*38fd1498Szrj 		      && !bitmap_bit_p (cse_ebb_live_out, firstr))
920*38fd1498Szrj 		  || (bitmap_bit_p (cse_ebb_live_in, new_reg)
921*38fd1498Szrj 		      && !bitmap_bit_p (cse_ebb_live_in, firstr))))))
922*38fd1498Szrj     {
923*38fd1498Szrj       reg_eqv_table[firstr].prev = new_reg;
924*38fd1498Szrj       reg_eqv_table[new_reg].next = firstr;
925*38fd1498Szrj       reg_eqv_table[new_reg].prev = -1;
926*38fd1498Szrj       ent->first_reg = new_reg;
927*38fd1498Szrj     }
928*38fd1498Szrj   else
929*38fd1498Szrj     {
930*38fd1498Szrj       /* If NEW is a hard reg (known to be non-fixed), insert at end.
931*38fd1498Szrj 	 Otherwise, insert before any non-fixed hard regs that are at the
932*38fd1498Szrj 	 end.  Registers of class NO_REGS cannot be used as an
933*38fd1498Szrj 	 equivalent for anything.  */
934*38fd1498Szrj       while (lastr < FIRST_PSEUDO_REGISTER && reg_eqv_table[lastr].prev >= 0
935*38fd1498Szrj 	     && (REGNO_REG_CLASS (lastr) == NO_REGS || ! FIXED_REGNO_P (lastr))
936*38fd1498Szrj 	     && new_reg >= FIRST_PSEUDO_REGISTER)
937*38fd1498Szrj 	lastr = reg_eqv_table[lastr].prev;
938*38fd1498Szrj       reg_eqv_table[new_reg].next = reg_eqv_table[lastr].next;
939*38fd1498Szrj       if (reg_eqv_table[lastr].next >= 0)
940*38fd1498Szrj 	reg_eqv_table[reg_eqv_table[lastr].next].prev = new_reg;
941*38fd1498Szrj       else
942*38fd1498Szrj 	qty_table[q].last_reg = new_reg;
943*38fd1498Szrj       reg_eqv_table[lastr].next = new_reg;
944*38fd1498Szrj       reg_eqv_table[new_reg].prev = lastr;
945*38fd1498Szrj     }
946*38fd1498Szrj }
947*38fd1498Szrj 
948*38fd1498Szrj /* Remove REG from its equivalence class.  */
949*38fd1498Szrj 
950*38fd1498Szrj static void
delete_reg_equiv(unsigned int reg)951*38fd1498Szrj delete_reg_equiv (unsigned int reg)
952*38fd1498Szrj {
953*38fd1498Szrj   struct qty_table_elem *ent;
954*38fd1498Szrj   int q = REG_QTY (reg);
955*38fd1498Szrj   int p, n;
956*38fd1498Szrj 
957*38fd1498Szrj   /* If invalid, do nothing.  */
958*38fd1498Szrj   if (! REGNO_QTY_VALID_P (reg))
959*38fd1498Szrj     return;
960*38fd1498Szrj 
961*38fd1498Szrj   ent = &qty_table[q];
962*38fd1498Szrj 
963*38fd1498Szrj   p = reg_eqv_table[reg].prev;
964*38fd1498Szrj   n = reg_eqv_table[reg].next;
965*38fd1498Szrj 
966*38fd1498Szrj   if (n != -1)
967*38fd1498Szrj     reg_eqv_table[n].prev = p;
968*38fd1498Szrj   else
969*38fd1498Szrj     ent->last_reg = p;
970*38fd1498Szrj   if (p != -1)
971*38fd1498Szrj     reg_eqv_table[p].next = n;
972*38fd1498Szrj   else
973*38fd1498Szrj     ent->first_reg = n;
974*38fd1498Szrj 
975*38fd1498Szrj   REG_QTY (reg) = -reg - 1;
976*38fd1498Szrj }
977*38fd1498Szrj 
978*38fd1498Szrj /* Remove any invalid expressions from the hash table
979*38fd1498Szrj    that refer to any of the registers contained in expression X.
980*38fd1498Szrj 
981*38fd1498Szrj    Make sure that newly inserted references to those registers
982*38fd1498Szrj    as subexpressions will be considered valid.
983*38fd1498Szrj 
984*38fd1498Szrj    mention_regs is not called when a register itself
985*38fd1498Szrj    is being stored in the table.
986*38fd1498Szrj 
987*38fd1498Szrj    Return 1 if we have done something that may have changed the hash code
988*38fd1498Szrj    of X.  */
989*38fd1498Szrj 
990*38fd1498Szrj static int
mention_regs(rtx x)991*38fd1498Szrj mention_regs (rtx x)
992*38fd1498Szrj {
993*38fd1498Szrj   enum rtx_code code;
994*38fd1498Szrj   int i, j;
995*38fd1498Szrj   const char *fmt;
996*38fd1498Szrj   int changed = 0;
997*38fd1498Szrj 
998*38fd1498Szrj   if (x == 0)
999*38fd1498Szrj     return 0;
1000*38fd1498Szrj 
1001*38fd1498Szrj   code = GET_CODE (x);
1002*38fd1498Szrj   if (code == REG)
1003*38fd1498Szrj     {
1004*38fd1498Szrj       unsigned int regno = REGNO (x);
1005*38fd1498Szrj       unsigned int endregno = END_REGNO (x);
1006*38fd1498Szrj       unsigned int i;
1007*38fd1498Szrj 
1008*38fd1498Szrj       for (i = regno; i < endregno; i++)
1009*38fd1498Szrj 	{
1010*38fd1498Szrj 	  if (REG_IN_TABLE (i) >= 0 && REG_IN_TABLE (i) != REG_TICK (i))
1011*38fd1498Szrj 	    remove_invalid_refs (i);
1012*38fd1498Szrj 
1013*38fd1498Szrj 	  REG_IN_TABLE (i) = REG_TICK (i);
1014*38fd1498Szrj 	  SUBREG_TICKED (i) = -1;
1015*38fd1498Szrj 	}
1016*38fd1498Szrj 
1017*38fd1498Szrj       return 0;
1018*38fd1498Szrj     }
1019*38fd1498Szrj 
1020*38fd1498Szrj   /* If this is a SUBREG, we don't want to discard other SUBREGs of the same
1021*38fd1498Szrj      pseudo if they don't use overlapping words.  We handle only pseudos
1022*38fd1498Szrj      here for simplicity.  */
1023*38fd1498Szrj   if (code == SUBREG && REG_P (SUBREG_REG (x))
1024*38fd1498Szrj       && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
1025*38fd1498Szrj     {
1026*38fd1498Szrj       unsigned int i = REGNO (SUBREG_REG (x));
1027*38fd1498Szrj 
1028*38fd1498Szrj       if (REG_IN_TABLE (i) >= 0 && REG_IN_TABLE (i) != REG_TICK (i))
1029*38fd1498Szrj 	{
1030*38fd1498Szrj 	  /* If REG_IN_TABLE (i) differs from REG_TICK (i) by one, and
1031*38fd1498Szrj 	     the last store to this register really stored into this
1032*38fd1498Szrj 	     subreg, then remove the memory of this subreg.
1033*38fd1498Szrj 	     Otherwise, remove any memory of the entire register and
1034*38fd1498Szrj 	     all its subregs from the table.  */
1035*38fd1498Szrj 	  if (REG_TICK (i) - REG_IN_TABLE (i) > 1
1036*38fd1498Szrj 	      || SUBREG_TICKED (i) != REGNO (SUBREG_REG (x)))
1037*38fd1498Szrj 	    remove_invalid_refs (i);
1038*38fd1498Szrj 	  else
1039*38fd1498Szrj 	    remove_invalid_subreg_refs (i, SUBREG_BYTE (x), GET_MODE (x));
1040*38fd1498Szrj 	}
1041*38fd1498Szrj 
1042*38fd1498Szrj       REG_IN_TABLE (i) = REG_TICK (i);
1043*38fd1498Szrj       SUBREG_TICKED (i) = REGNO (SUBREG_REG (x));
1044*38fd1498Szrj       return 0;
1045*38fd1498Szrj     }
1046*38fd1498Szrj 
1047*38fd1498Szrj   /* If X is a comparison or a COMPARE and either operand is a register
1048*38fd1498Szrj      that does not have a quantity, give it one.  This is so that a later
1049*38fd1498Szrj      call to record_jump_equiv won't cause X to be assigned a different
1050*38fd1498Szrj      hash code and not found in the table after that call.
1051*38fd1498Szrj 
1052*38fd1498Szrj      It is not necessary to do this here, since rehash_using_reg can
1053*38fd1498Szrj      fix up the table later, but doing this here eliminates the need to
1054*38fd1498Szrj      call that expensive function in the most common case where the only
1055*38fd1498Szrj      use of the register is in the comparison.  */
1056*38fd1498Szrj 
1057*38fd1498Szrj   if (code == COMPARE || COMPARISON_P (x))
1058*38fd1498Szrj     {
1059*38fd1498Szrj       if (REG_P (XEXP (x, 0))
1060*38fd1498Szrj 	  && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))))
1061*38fd1498Szrj 	if (insert_regs (XEXP (x, 0), NULL, 0))
1062*38fd1498Szrj 	  {
1063*38fd1498Szrj 	    rehash_using_reg (XEXP (x, 0));
1064*38fd1498Szrj 	    changed = 1;
1065*38fd1498Szrj 	  }
1066*38fd1498Szrj 
1067*38fd1498Szrj       if (REG_P (XEXP (x, 1))
1068*38fd1498Szrj 	  && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))))
1069*38fd1498Szrj 	if (insert_regs (XEXP (x, 1), NULL, 0))
1070*38fd1498Szrj 	  {
1071*38fd1498Szrj 	    rehash_using_reg (XEXP (x, 1));
1072*38fd1498Szrj 	    changed = 1;
1073*38fd1498Szrj 	  }
1074*38fd1498Szrj     }
1075*38fd1498Szrj 
1076*38fd1498Szrj   fmt = GET_RTX_FORMAT (code);
1077*38fd1498Szrj   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1078*38fd1498Szrj     if (fmt[i] == 'e')
1079*38fd1498Szrj       changed |= mention_regs (XEXP (x, i));
1080*38fd1498Szrj     else if (fmt[i] == 'E')
1081*38fd1498Szrj       for (j = 0; j < XVECLEN (x, i); j++)
1082*38fd1498Szrj 	changed |= mention_regs (XVECEXP (x, i, j));
1083*38fd1498Szrj 
1084*38fd1498Szrj   return changed;
1085*38fd1498Szrj }
1086*38fd1498Szrj 
1087*38fd1498Szrj /* Update the register quantities for inserting X into the hash table
1088*38fd1498Szrj    with a value equivalent to CLASSP.
1089*38fd1498Szrj    (If the class does not contain a REG, it is irrelevant.)
1090*38fd1498Szrj    If MODIFIED is nonzero, X is a destination; it is being modified.
1091*38fd1498Szrj    Note that delete_reg_equiv should be called on a register
1092*38fd1498Szrj    before insert_regs is done on that register with MODIFIED != 0.
1093*38fd1498Szrj 
1094*38fd1498Szrj    Nonzero value means that elements of reg_qty have changed
1095*38fd1498Szrj    so X's hash code may be different.  */
1096*38fd1498Szrj 
1097*38fd1498Szrj static int
insert_regs(rtx x,struct table_elt * classp,int modified)1098*38fd1498Szrj insert_regs (rtx x, struct table_elt *classp, int modified)
1099*38fd1498Szrj {
1100*38fd1498Szrj   if (REG_P (x))
1101*38fd1498Szrj     {
1102*38fd1498Szrj       unsigned int regno = REGNO (x);
1103*38fd1498Szrj       int qty_valid;
1104*38fd1498Szrj 
1105*38fd1498Szrj       /* If REGNO is in the equivalence table already but is of the
1106*38fd1498Szrj 	 wrong mode for that equivalence, don't do anything here.  */
1107*38fd1498Szrj 
1108*38fd1498Szrj       qty_valid = REGNO_QTY_VALID_P (regno);
1109*38fd1498Szrj       if (qty_valid)
1110*38fd1498Szrj 	{
1111*38fd1498Szrj 	  struct qty_table_elem *ent = &qty_table[REG_QTY (regno)];
1112*38fd1498Szrj 
1113*38fd1498Szrj 	  if (ent->mode != GET_MODE (x))
1114*38fd1498Szrj 	    return 0;
1115*38fd1498Szrj 	}
1116*38fd1498Szrj 
1117*38fd1498Szrj       if (modified || ! qty_valid)
1118*38fd1498Szrj 	{
1119*38fd1498Szrj 	  if (classp)
1120*38fd1498Szrj 	    for (classp = classp->first_same_value;
1121*38fd1498Szrj 		 classp != 0;
1122*38fd1498Szrj 		 classp = classp->next_same_value)
1123*38fd1498Szrj 	      if (REG_P (classp->exp)
1124*38fd1498Szrj 		  && GET_MODE (classp->exp) == GET_MODE (x))
1125*38fd1498Szrj 		{
1126*38fd1498Szrj 		  unsigned c_regno = REGNO (classp->exp);
1127*38fd1498Szrj 
1128*38fd1498Szrj 		  gcc_assert (REGNO_QTY_VALID_P (c_regno));
1129*38fd1498Szrj 
1130*38fd1498Szrj 		  /* Suppose that 5 is hard reg and 100 and 101 are
1131*38fd1498Szrj 		     pseudos.  Consider
1132*38fd1498Szrj 
1133*38fd1498Szrj 		     (set (reg:si 100) (reg:si 5))
1134*38fd1498Szrj 		     (set (reg:si 5) (reg:si 100))
1135*38fd1498Szrj 		     (set (reg:di 101) (reg:di 5))
1136*38fd1498Szrj 
1137*38fd1498Szrj 		     We would now set REG_QTY (101) = REG_QTY (5), but the
1138*38fd1498Szrj 		     entry for 5 is in SImode.  When we use this later in
1139*38fd1498Szrj 		     copy propagation, we get the register in wrong mode.  */
1140*38fd1498Szrj 		  if (qty_table[REG_QTY (c_regno)].mode != GET_MODE (x))
1141*38fd1498Szrj 		    continue;
1142*38fd1498Szrj 
1143*38fd1498Szrj 		  make_regs_eqv (regno, c_regno);
1144*38fd1498Szrj 		  return 1;
1145*38fd1498Szrj 		}
1146*38fd1498Szrj 
1147*38fd1498Szrj 	  /* Mention_regs for a SUBREG checks if REG_TICK is exactly one larger
1148*38fd1498Szrj 	     than REG_IN_TABLE to find out if there was only a single preceding
1149*38fd1498Szrj 	     invalidation - for the SUBREG - or another one, which would be
1150*38fd1498Szrj 	     for the full register.  However, if we find here that REG_TICK
1151*38fd1498Szrj 	     indicates that the register is invalid, it means that it has
1152*38fd1498Szrj 	     been invalidated in a separate operation.  The SUBREG might be used
1153*38fd1498Szrj 	     now (then this is a recursive call), or we might use the full REG
1154*38fd1498Szrj 	     now and a SUBREG of it later.  So bump up REG_TICK so that
1155*38fd1498Szrj 	     mention_regs will do the right thing.  */
1156*38fd1498Szrj 	  if (! modified
1157*38fd1498Szrj 	      && REG_IN_TABLE (regno) >= 0
1158*38fd1498Szrj 	      && REG_TICK (regno) == REG_IN_TABLE (regno) + 1)
1159*38fd1498Szrj 	    REG_TICK (regno)++;
1160*38fd1498Szrj 	  make_new_qty (regno, GET_MODE (x));
1161*38fd1498Szrj 	  return 1;
1162*38fd1498Szrj 	}
1163*38fd1498Szrj 
1164*38fd1498Szrj       return 0;
1165*38fd1498Szrj     }
1166*38fd1498Szrj 
1167*38fd1498Szrj   /* If X is a SUBREG, we will likely be inserting the inner register in the
1168*38fd1498Szrj      table.  If that register doesn't have an assigned quantity number at
1169*38fd1498Szrj      this point but does later, the insertion that we will be doing now will
1170*38fd1498Szrj      not be accessible because its hash code will have changed.  So assign
1171*38fd1498Szrj      a quantity number now.  */
1172*38fd1498Szrj 
1173*38fd1498Szrj   else if (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
1174*38fd1498Szrj 	   && ! REGNO_QTY_VALID_P (REGNO (SUBREG_REG (x))))
1175*38fd1498Szrj     {
1176*38fd1498Szrj       insert_regs (SUBREG_REG (x), NULL, 0);
1177*38fd1498Szrj       mention_regs (x);
1178*38fd1498Szrj       return 1;
1179*38fd1498Szrj     }
1180*38fd1498Szrj   else
1181*38fd1498Szrj     return mention_regs (x);
1182*38fd1498Szrj }
1183*38fd1498Szrj 
1184*38fd1498Szrj 
1185*38fd1498Szrj /* Compute upper and lower anchors for CST.  Also compute the offset of CST
1186*38fd1498Szrj    from these anchors/bases such that *_BASE + *_OFFS = CST.  Return false iff
1187*38fd1498Szrj    CST is equal to an anchor.  */
1188*38fd1498Szrj 
1189*38fd1498Szrj static bool
compute_const_anchors(rtx cst,HOST_WIDE_INT * lower_base,HOST_WIDE_INT * lower_offs,HOST_WIDE_INT * upper_base,HOST_WIDE_INT * upper_offs)1190*38fd1498Szrj compute_const_anchors (rtx cst,
1191*38fd1498Szrj 		       HOST_WIDE_INT *lower_base, HOST_WIDE_INT *lower_offs,
1192*38fd1498Szrj 		       HOST_WIDE_INT *upper_base, HOST_WIDE_INT *upper_offs)
1193*38fd1498Szrj {
1194*38fd1498Szrj   HOST_WIDE_INT n = INTVAL (cst);
1195*38fd1498Szrj 
1196*38fd1498Szrj   *lower_base = n & ~(targetm.const_anchor - 1);
1197*38fd1498Szrj   if (*lower_base == n)
1198*38fd1498Szrj     return false;
1199*38fd1498Szrj 
1200*38fd1498Szrj   *upper_base =
1201*38fd1498Szrj     (n + (targetm.const_anchor - 1)) & ~(targetm.const_anchor - 1);
1202*38fd1498Szrj   *upper_offs = n - *upper_base;
1203*38fd1498Szrj   *lower_offs = n - *lower_base;
1204*38fd1498Szrj   return true;
1205*38fd1498Szrj }
1206*38fd1498Szrj 
1207*38fd1498Szrj /* Insert the equivalence between ANCHOR and (REG + OFF) in mode MODE.  */
1208*38fd1498Szrj 
1209*38fd1498Szrj static void
insert_const_anchor(HOST_WIDE_INT anchor,rtx reg,HOST_WIDE_INT offs,machine_mode mode)1210*38fd1498Szrj insert_const_anchor (HOST_WIDE_INT anchor, rtx reg, HOST_WIDE_INT offs,
1211*38fd1498Szrj 		     machine_mode mode)
1212*38fd1498Szrj {
1213*38fd1498Szrj   struct table_elt *elt;
1214*38fd1498Szrj   unsigned hash;
1215*38fd1498Szrj   rtx anchor_exp;
1216*38fd1498Szrj   rtx exp;
1217*38fd1498Szrj 
1218*38fd1498Szrj   anchor_exp = GEN_INT (anchor);
1219*38fd1498Szrj   hash = HASH (anchor_exp, mode);
1220*38fd1498Szrj   elt = lookup (anchor_exp, hash, mode);
1221*38fd1498Szrj   if (!elt)
1222*38fd1498Szrj     elt = insert (anchor_exp, NULL, hash, mode);
1223*38fd1498Szrj 
1224*38fd1498Szrj   exp = plus_constant (mode, reg, offs);
1225*38fd1498Szrj   /* REG has just been inserted and the hash codes recomputed.  */
1226*38fd1498Szrj   mention_regs (exp);
1227*38fd1498Szrj   hash = HASH (exp, mode);
1228*38fd1498Szrj 
1229*38fd1498Szrj   /* Use the cost of the register rather than the whole expression.  When
1230*38fd1498Szrj      looking up constant anchors we will further offset the corresponding
1231*38fd1498Szrj      expression therefore it does not make sense to prefer REGs over
1232*38fd1498Szrj      reg-immediate additions.  Prefer instead the oldest expression.  Also
1233*38fd1498Szrj      don't prefer pseudos over hard regs so that we derive constants in
1234*38fd1498Szrj      argument registers from other argument registers rather than from the
1235*38fd1498Szrj      original pseudo that was used to synthesize the constant.  */
1236*38fd1498Szrj   insert_with_costs (exp, elt, hash, mode, COST (reg, mode), 1);
1237*38fd1498Szrj }
1238*38fd1498Szrj 
1239*38fd1498Szrj /* The constant CST is equivalent to the register REG.  Create
1240*38fd1498Szrj    equivalences between the two anchors of CST and the corresponding
1241*38fd1498Szrj    register-offset expressions using REG.  */
1242*38fd1498Szrj 
1243*38fd1498Szrj static void
insert_const_anchors(rtx reg,rtx cst,machine_mode mode)1244*38fd1498Szrj insert_const_anchors (rtx reg, rtx cst, machine_mode mode)
1245*38fd1498Szrj {
1246*38fd1498Szrj   HOST_WIDE_INT lower_base, lower_offs, upper_base, upper_offs;
1247*38fd1498Szrj 
1248*38fd1498Szrj   if (!compute_const_anchors (cst, &lower_base, &lower_offs,
1249*38fd1498Szrj 			      &upper_base, &upper_offs))
1250*38fd1498Szrj       return;
1251*38fd1498Szrj 
1252*38fd1498Szrj   /* Ignore anchors of value 0.  Constants accessible from zero are
1253*38fd1498Szrj      simple.  */
1254*38fd1498Szrj   if (lower_base != 0)
1255*38fd1498Szrj     insert_const_anchor (lower_base, reg, -lower_offs, mode);
1256*38fd1498Szrj 
1257*38fd1498Szrj   if (upper_base != 0)
1258*38fd1498Szrj     insert_const_anchor (upper_base, reg, -upper_offs, mode);
1259*38fd1498Szrj }
1260*38fd1498Szrj 
1261*38fd1498Szrj /* We need to express ANCHOR_ELT->exp + OFFS.  Walk the equivalence list of
1262*38fd1498Szrj    ANCHOR_ELT and see if offsetting any of the entries by OFFS would create a
1263*38fd1498Szrj    valid expression.  Return the cheapest and oldest of such expressions.  In
1264*38fd1498Szrj    *OLD, return how old the resulting expression is compared to the other
1265*38fd1498Szrj    equivalent expressions.  */
1266*38fd1498Szrj 
1267*38fd1498Szrj static rtx
find_reg_offset_for_const(struct table_elt * anchor_elt,HOST_WIDE_INT offs,unsigned * old)1268*38fd1498Szrj find_reg_offset_for_const (struct table_elt *anchor_elt, HOST_WIDE_INT offs,
1269*38fd1498Szrj 			   unsigned *old)
1270*38fd1498Szrj {
1271*38fd1498Szrj   struct table_elt *elt;
1272*38fd1498Szrj   unsigned idx;
1273*38fd1498Szrj   struct table_elt *match_elt;
1274*38fd1498Szrj   rtx match;
1275*38fd1498Szrj 
1276*38fd1498Szrj   /* Find the cheapest and *oldest* expression to maximize the chance of
1277*38fd1498Szrj      reusing the same pseudo.  */
1278*38fd1498Szrj 
1279*38fd1498Szrj   match_elt = NULL;
1280*38fd1498Szrj   match = NULL_RTX;
1281*38fd1498Szrj   for (elt = anchor_elt->first_same_value, idx = 0;
1282*38fd1498Szrj        elt;
1283*38fd1498Szrj        elt = elt->next_same_value, idx++)
1284*38fd1498Szrj     {
1285*38fd1498Szrj       if (match_elt && CHEAPER (match_elt, elt))
1286*38fd1498Szrj 	return match;
1287*38fd1498Szrj 
1288*38fd1498Szrj       if (REG_P (elt->exp)
1289*38fd1498Szrj 	  || (GET_CODE (elt->exp) == PLUS
1290*38fd1498Szrj 	      && REG_P (XEXP (elt->exp, 0))
1291*38fd1498Szrj 	      && GET_CODE (XEXP (elt->exp, 1)) == CONST_INT))
1292*38fd1498Szrj 	{
1293*38fd1498Szrj 	  rtx x;
1294*38fd1498Szrj 
1295*38fd1498Szrj 	  /* Ignore expressions that are no longer valid.  */
1296*38fd1498Szrj 	  if (!REG_P (elt->exp) && !exp_equiv_p (elt->exp, elt->exp, 1, false))
1297*38fd1498Szrj 	    continue;
1298*38fd1498Szrj 
1299*38fd1498Szrj 	  x = plus_constant (GET_MODE (elt->exp), elt->exp, offs);
1300*38fd1498Szrj 	  if (REG_P (x)
1301*38fd1498Szrj 	      || (GET_CODE (x) == PLUS
1302*38fd1498Szrj 		  && IN_RANGE (INTVAL (XEXP (x, 1)),
1303*38fd1498Szrj 			       -targetm.const_anchor,
1304*38fd1498Szrj 			       targetm.const_anchor - 1)))
1305*38fd1498Szrj 	    {
1306*38fd1498Szrj 	      match = x;
1307*38fd1498Szrj 	      match_elt = elt;
1308*38fd1498Szrj 	      *old = idx;
1309*38fd1498Szrj 	    }
1310*38fd1498Szrj 	}
1311*38fd1498Szrj     }
1312*38fd1498Szrj 
1313*38fd1498Szrj   return match;
1314*38fd1498Szrj }
1315*38fd1498Szrj 
1316*38fd1498Szrj /* Try to express the constant SRC_CONST using a register+offset expression
1317*38fd1498Szrj    derived from a constant anchor.  Return it if successful or NULL_RTX,
1318*38fd1498Szrj    otherwise.  */
1319*38fd1498Szrj 
1320*38fd1498Szrj static rtx
try_const_anchors(rtx src_const,machine_mode mode)1321*38fd1498Szrj try_const_anchors (rtx src_const, machine_mode mode)
1322*38fd1498Szrj {
1323*38fd1498Szrj   struct table_elt *lower_elt, *upper_elt;
1324*38fd1498Szrj   HOST_WIDE_INT lower_base, lower_offs, upper_base, upper_offs;
1325*38fd1498Szrj   rtx lower_anchor_rtx, upper_anchor_rtx;
1326*38fd1498Szrj   rtx lower_exp = NULL_RTX, upper_exp = NULL_RTX;
1327*38fd1498Szrj   unsigned lower_old, upper_old;
1328*38fd1498Szrj 
1329*38fd1498Szrj   /* CONST_INT is used for CC modes, but we should leave those alone.  */
1330*38fd1498Szrj   if (GET_MODE_CLASS (mode) == MODE_CC)
1331*38fd1498Szrj     return NULL_RTX;
1332*38fd1498Szrj 
1333*38fd1498Szrj   gcc_assert (SCALAR_INT_MODE_P (mode));
1334*38fd1498Szrj   if (!compute_const_anchors (src_const, &lower_base, &lower_offs,
1335*38fd1498Szrj 			      &upper_base, &upper_offs))
1336*38fd1498Szrj     return NULL_RTX;
1337*38fd1498Szrj 
1338*38fd1498Szrj   lower_anchor_rtx = GEN_INT (lower_base);
1339*38fd1498Szrj   upper_anchor_rtx = GEN_INT (upper_base);
1340*38fd1498Szrj   lower_elt = lookup (lower_anchor_rtx, HASH (lower_anchor_rtx, mode), mode);
1341*38fd1498Szrj   upper_elt = lookup (upper_anchor_rtx, HASH (upper_anchor_rtx, mode), mode);
1342*38fd1498Szrj 
1343*38fd1498Szrj   if (lower_elt)
1344*38fd1498Szrj     lower_exp = find_reg_offset_for_const (lower_elt, lower_offs, &lower_old);
1345*38fd1498Szrj   if (upper_elt)
1346*38fd1498Szrj     upper_exp = find_reg_offset_for_const (upper_elt, upper_offs, &upper_old);
1347*38fd1498Szrj 
1348*38fd1498Szrj   if (!lower_exp)
1349*38fd1498Szrj     return upper_exp;
1350*38fd1498Szrj   if (!upper_exp)
1351*38fd1498Szrj     return lower_exp;
1352*38fd1498Szrj 
1353*38fd1498Szrj   /* Return the older expression.  */
1354*38fd1498Szrj   return (upper_old > lower_old ? upper_exp : lower_exp);
1355*38fd1498Szrj }
1356*38fd1498Szrj 
1357*38fd1498Szrj /* Look in or update the hash table.  */
1358*38fd1498Szrj 
1359*38fd1498Szrj /* Remove table element ELT from use in the table.
1360*38fd1498Szrj    HASH is its hash code, made using the HASH macro.
1361*38fd1498Szrj    It's an argument because often that is known in advance
1362*38fd1498Szrj    and we save much time not recomputing it.  */
1363*38fd1498Szrj 
1364*38fd1498Szrj static void
remove_from_table(struct table_elt * elt,unsigned int hash)1365*38fd1498Szrj remove_from_table (struct table_elt *elt, unsigned int hash)
1366*38fd1498Szrj {
1367*38fd1498Szrj   if (elt == 0)
1368*38fd1498Szrj     return;
1369*38fd1498Szrj 
1370*38fd1498Szrj   /* Mark this element as removed.  See cse_insn.  */
1371*38fd1498Szrj   elt->first_same_value = 0;
1372*38fd1498Szrj 
1373*38fd1498Szrj   /* Remove the table element from its equivalence class.  */
1374*38fd1498Szrj 
1375*38fd1498Szrj   {
1376*38fd1498Szrj     struct table_elt *prev = elt->prev_same_value;
1377*38fd1498Szrj     struct table_elt *next = elt->next_same_value;
1378*38fd1498Szrj 
1379*38fd1498Szrj     if (next)
1380*38fd1498Szrj       next->prev_same_value = prev;
1381*38fd1498Szrj 
1382*38fd1498Szrj     if (prev)
1383*38fd1498Szrj       prev->next_same_value = next;
1384*38fd1498Szrj     else
1385*38fd1498Szrj       {
1386*38fd1498Szrj 	struct table_elt *newfirst = next;
1387*38fd1498Szrj 	while (next)
1388*38fd1498Szrj 	  {
1389*38fd1498Szrj 	    next->first_same_value = newfirst;
1390*38fd1498Szrj 	    next = next->next_same_value;
1391*38fd1498Szrj 	  }
1392*38fd1498Szrj       }
1393*38fd1498Szrj   }
1394*38fd1498Szrj 
1395*38fd1498Szrj   /* Remove the table element from its hash bucket.  */
1396*38fd1498Szrj 
1397*38fd1498Szrj   {
1398*38fd1498Szrj     struct table_elt *prev = elt->prev_same_hash;
1399*38fd1498Szrj     struct table_elt *next = elt->next_same_hash;
1400*38fd1498Szrj 
1401*38fd1498Szrj     if (next)
1402*38fd1498Szrj       next->prev_same_hash = prev;
1403*38fd1498Szrj 
1404*38fd1498Szrj     if (prev)
1405*38fd1498Szrj       prev->next_same_hash = next;
1406*38fd1498Szrj     else if (table[hash] == elt)
1407*38fd1498Szrj       table[hash] = next;
1408*38fd1498Szrj     else
1409*38fd1498Szrj       {
1410*38fd1498Szrj 	/* This entry is not in the proper hash bucket.  This can happen
1411*38fd1498Szrj 	   when two classes were merged by `merge_equiv_classes'.  Search
1412*38fd1498Szrj 	   for the hash bucket that it heads.  This happens only very
1413*38fd1498Szrj 	   rarely, so the cost is acceptable.  */
1414*38fd1498Szrj 	for (hash = 0; hash < HASH_SIZE; hash++)
1415*38fd1498Szrj 	  if (table[hash] == elt)
1416*38fd1498Szrj 	    table[hash] = next;
1417*38fd1498Szrj       }
1418*38fd1498Szrj   }
1419*38fd1498Szrj 
1420*38fd1498Szrj   /* Remove the table element from its related-value circular chain.  */
1421*38fd1498Szrj 
1422*38fd1498Szrj   if (elt->related_value != 0 && elt->related_value != elt)
1423*38fd1498Szrj     {
1424*38fd1498Szrj       struct table_elt *p = elt->related_value;
1425*38fd1498Szrj 
1426*38fd1498Szrj       while (p->related_value != elt)
1427*38fd1498Szrj 	p = p->related_value;
1428*38fd1498Szrj       p->related_value = elt->related_value;
1429*38fd1498Szrj       if (p->related_value == p)
1430*38fd1498Szrj 	p->related_value = 0;
1431*38fd1498Szrj     }
1432*38fd1498Szrj 
1433*38fd1498Szrj   /* Now add it to the free element chain.  */
1434*38fd1498Szrj   elt->next_same_hash = free_element_chain;
1435*38fd1498Szrj   free_element_chain = elt;
1436*38fd1498Szrj }
1437*38fd1498Szrj 
1438*38fd1498Szrj /* Same as above, but X is a pseudo-register.  */
1439*38fd1498Szrj 
1440*38fd1498Szrj static void
remove_pseudo_from_table(rtx x,unsigned int hash)1441*38fd1498Szrj remove_pseudo_from_table (rtx x, unsigned int hash)
1442*38fd1498Szrj {
1443*38fd1498Szrj   struct table_elt *elt;
1444*38fd1498Szrj 
1445*38fd1498Szrj   /* Because a pseudo-register can be referenced in more than one
1446*38fd1498Szrj      mode, we might have to remove more than one table entry.  */
1447*38fd1498Szrj   while ((elt = lookup_for_remove (x, hash, VOIDmode)))
1448*38fd1498Szrj     remove_from_table (elt, hash);
1449*38fd1498Szrj }
1450*38fd1498Szrj 
1451*38fd1498Szrj /* Look up X in the hash table and return its table element,
1452*38fd1498Szrj    or 0 if X is not in the table.
1453*38fd1498Szrj 
1454*38fd1498Szrj    MODE is the machine-mode of X, or if X is an integer constant
1455*38fd1498Szrj    with VOIDmode then MODE is the mode with which X will be used.
1456*38fd1498Szrj 
1457*38fd1498Szrj    Here we are satisfied to find an expression whose tree structure
1458*38fd1498Szrj    looks like X.  */
1459*38fd1498Szrj 
1460*38fd1498Szrj static struct table_elt *
lookup(rtx x,unsigned int hash,machine_mode mode)1461*38fd1498Szrj lookup (rtx x, unsigned int hash, machine_mode mode)
1462*38fd1498Szrj {
1463*38fd1498Szrj   struct table_elt *p;
1464*38fd1498Szrj 
1465*38fd1498Szrj   for (p = table[hash]; p; p = p->next_same_hash)
1466*38fd1498Szrj     if (mode == p->mode && ((x == p->exp && REG_P (x))
1467*38fd1498Szrj 			    || exp_equiv_p (x, p->exp, !REG_P (x), false)))
1468*38fd1498Szrj       return p;
1469*38fd1498Szrj 
1470*38fd1498Szrj   return 0;
1471*38fd1498Szrj }
1472*38fd1498Szrj 
1473*38fd1498Szrj /* Like `lookup' but don't care whether the table element uses invalid regs.
1474*38fd1498Szrj    Also ignore discrepancies in the machine mode of a register.  */
1475*38fd1498Szrj 
1476*38fd1498Szrj static struct table_elt *
lookup_for_remove(rtx x,unsigned int hash,machine_mode mode)1477*38fd1498Szrj lookup_for_remove (rtx x, unsigned int hash, machine_mode mode)
1478*38fd1498Szrj {
1479*38fd1498Szrj   struct table_elt *p;
1480*38fd1498Szrj 
1481*38fd1498Szrj   if (REG_P (x))
1482*38fd1498Szrj     {
1483*38fd1498Szrj       unsigned int regno = REGNO (x);
1484*38fd1498Szrj 
1485*38fd1498Szrj       /* Don't check the machine mode when comparing registers;
1486*38fd1498Szrj 	 invalidating (REG:SI 0) also invalidates (REG:DF 0).  */
1487*38fd1498Szrj       for (p = table[hash]; p; p = p->next_same_hash)
1488*38fd1498Szrj 	if (REG_P (p->exp)
1489*38fd1498Szrj 	    && REGNO (p->exp) == regno)
1490*38fd1498Szrj 	  return p;
1491*38fd1498Szrj     }
1492*38fd1498Szrj   else
1493*38fd1498Szrj     {
1494*38fd1498Szrj       for (p = table[hash]; p; p = p->next_same_hash)
1495*38fd1498Szrj 	if (mode == p->mode
1496*38fd1498Szrj 	    && (x == p->exp || exp_equiv_p (x, p->exp, 0, false)))
1497*38fd1498Szrj 	  return p;
1498*38fd1498Szrj     }
1499*38fd1498Szrj 
1500*38fd1498Szrj   return 0;
1501*38fd1498Szrj }
1502*38fd1498Szrj 
1503*38fd1498Szrj /* Look for an expression equivalent to X and with code CODE.
1504*38fd1498Szrj    If one is found, return that expression.  */
1505*38fd1498Szrj 
1506*38fd1498Szrj static rtx
lookup_as_function(rtx x,enum rtx_code code)1507*38fd1498Szrj lookup_as_function (rtx x, enum rtx_code code)
1508*38fd1498Szrj {
1509*38fd1498Szrj   struct table_elt *p
1510*38fd1498Szrj     = lookup (x, SAFE_HASH (x, VOIDmode), GET_MODE (x));
1511*38fd1498Szrj 
1512*38fd1498Szrj   if (p == 0)
1513*38fd1498Szrj     return 0;
1514*38fd1498Szrj 
1515*38fd1498Szrj   for (p = p->first_same_value; p; p = p->next_same_value)
1516*38fd1498Szrj     if (GET_CODE (p->exp) == code
1517*38fd1498Szrj 	/* Make sure this is a valid entry in the table.  */
1518*38fd1498Szrj 	&& exp_equiv_p (p->exp, p->exp, 1, false))
1519*38fd1498Szrj       return p->exp;
1520*38fd1498Szrj 
1521*38fd1498Szrj   return 0;
1522*38fd1498Szrj }
1523*38fd1498Szrj 
1524*38fd1498Szrj /* Insert X in the hash table, assuming HASH is its hash code and
1525*38fd1498Szrj    CLASSP is an element of the class it should go in (or 0 if a new
1526*38fd1498Szrj    class should be made).  COST is the code of X and reg_cost is the
1527*38fd1498Szrj    cost of registers in X.  It is inserted at the proper position to
1528*38fd1498Szrj    keep the class in the order cheapest first.
1529*38fd1498Szrj 
1530*38fd1498Szrj    MODE is the machine-mode of X, or if X is an integer constant
1531*38fd1498Szrj    with VOIDmode then MODE is the mode with which X will be used.
1532*38fd1498Szrj 
1533*38fd1498Szrj    For elements of equal cheapness, the most recent one
1534*38fd1498Szrj    goes in front, except that the first element in the list
1535*38fd1498Szrj    remains first unless a cheaper element is added.  The order of
1536*38fd1498Szrj    pseudo-registers does not matter, as canon_reg will be called to
1537*38fd1498Szrj    find the cheapest when a register is retrieved from the table.
1538*38fd1498Szrj 
1539*38fd1498Szrj    The in_memory field in the hash table element is set to 0.
1540*38fd1498Szrj    The caller must set it nonzero if appropriate.
1541*38fd1498Szrj 
1542*38fd1498Szrj    You should call insert_regs (X, CLASSP, MODIFY) before calling here,
1543*38fd1498Szrj    and if insert_regs returns a nonzero value
1544*38fd1498Szrj    you must then recompute its hash code before calling here.
1545*38fd1498Szrj 
1546*38fd1498Szrj    If necessary, update table showing constant values of quantities.  */
1547*38fd1498Szrj 
1548*38fd1498Szrj static struct table_elt *
insert_with_costs(rtx x,struct table_elt * classp,unsigned int hash,machine_mode mode,int cost,int reg_cost)1549*38fd1498Szrj insert_with_costs (rtx x, struct table_elt *classp, unsigned int hash,
1550*38fd1498Szrj 		   machine_mode mode, int cost, int reg_cost)
1551*38fd1498Szrj {
1552*38fd1498Szrj   struct table_elt *elt;
1553*38fd1498Szrj 
1554*38fd1498Szrj   /* If X is a register and we haven't made a quantity for it,
1555*38fd1498Szrj      something is wrong.  */
1556*38fd1498Szrj   gcc_assert (!REG_P (x) || REGNO_QTY_VALID_P (REGNO (x)));
1557*38fd1498Szrj 
1558*38fd1498Szrj   /* If X is a hard register, show it is being put in the table.  */
1559*38fd1498Szrj   if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
1560*38fd1498Szrj     add_to_hard_reg_set (&hard_regs_in_table, GET_MODE (x), REGNO (x));
1561*38fd1498Szrj 
1562*38fd1498Szrj   /* Put an element for X into the right hash bucket.  */
1563*38fd1498Szrj 
1564*38fd1498Szrj   elt = free_element_chain;
1565*38fd1498Szrj   if (elt)
1566*38fd1498Szrj     free_element_chain = elt->next_same_hash;
1567*38fd1498Szrj   else
1568*38fd1498Szrj     elt = XNEW (struct table_elt);
1569*38fd1498Szrj 
1570*38fd1498Szrj   elt->exp = x;
1571*38fd1498Szrj   elt->canon_exp = NULL_RTX;
1572*38fd1498Szrj   elt->cost = cost;
1573*38fd1498Szrj   elt->regcost = reg_cost;
1574*38fd1498Szrj   elt->next_same_value = 0;
1575*38fd1498Szrj   elt->prev_same_value = 0;
1576*38fd1498Szrj   elt->next_same_hash = table[hash];
1577*38fd1498Szrj   elt->prev_same_hash = 0;
1578*38fd1498Szrj   elt->related_value = 0;
1579*38fd1498Szrj   elt->in_memory = 0;
1580*38fd1498Szrj   elt->mode = mode;
1581*38fd1498Szrj   elt->is_const = (CONSTANT_P (x) || fixed_base_plus_p (x));
1582*38fd1498Szrj 
1583*38fd1498Szrj   if (table[hash])
1584*38fd1498Szrj     table[hash]->prev_same_hash = elt;
1585*38fd1498Szrj   table[hash] = elt;
1586*38fd1498Szrj 
1587*38fd1498Szrj   /* Put it into the proper value-class.  */
1588*38fd1498Szrj   if (classp)
1589*38fd1498Szrj     {
1590*38fd1498Szrj       classp = classp->first_same_value;
1591*38fd1498Szrj       if (CHEAPER (elt, classp))
1592*38fd1498Szrj 	/* Insert at the head of the class.  */
1593*38fd1498Szrj 	{
1594*38fd1498Szrj 	  struct table_elt *p;
1595*38fd1498Szrj 	  elt->next_same_value = classp;
1596*38fd1498Szrj 	  classp->prev_same_value = elt;
1597*38fd1498Szrj 	  elt->first_same_value = elt;
1598*38fd1498Szrj 
1599*38fd1498Szrj 	  for (p = classp; p; p = p->next_same_value)
1600*38fd1498Szrj 	    p->first_same_value = elt;
1601*38fd1498Szrj 	}
1602*38fd1498Szrj       else
1603*38fd1498Szrj 	{
1604*38fd1498Szrj 	  /* Insert not at head of the class.  */
1605*38fd1498Szrj 	  /* Put it after the last element cheaper than X.  */
1606*38fd1498Szrj 	  struct table_elt *p, *next;
1607*38fd1498Szrj 
1608*38fd1498Szrj 	  for (p = classp;
1609*38fd1498Szrj 	       (next = p->next_same_value) && CHEAPER (next, elt);
1610*38fd1498Szrj 	       p = next)
1611*38fd1498Szrj 	    ;
1612*38fd1498Szrj 
1613*38fd1498Szrj 	  /* Put it after P and before NEXT.  */
1614*38fd1498Szrj 	  elt->next_same_value = next;
1615*38fd1498Szrj 	  if (next)
1616*38fd1498Szrj 	    next->prev_same_value = elt;
1617*38fd1498Szrj 
1618*38fd1498Szrj 	  elt->prev_same_value = p;
1619*38fd1498Szrj 	  p->next_same_value = elt;
1620*38fd1498Szrj 	  elt->first_same_value = classp;
1621*38fd1498Szrj 	}
1622*38fd1498Szrj     }
1623*38fd1498Szrj   else
1624*38fd1498Szrj     elt->first_same_value = elt;
1625*38fd1498Szrj 
1626*38fd1498Szrj   /* If this is a constant being set equivalent to a register or a register
1627*38fd1498Szrj      being set equivalent to a constant, note the constant equivalence.
1628*38fd1498Szrj 
1629*38fd1498Szrj      If this is a constant, it cannot be equivalent to a different constant,
1630*38fd1498Szrj      and a constant is the only thing that can be cheaper than a register.  So
1631*38fd1498Szrj      we know the register is the head of the class (before the constant was
1632*38fd1498Szrj      inserted).
1633*38fd1498Szrj 
1634*38fd1498Szrj      If this is a register that is not already known equivalent to a
1635*38fd1498Szrj      constant, we must check the entire class.
1636*38fd1498Szrj 
1637*38fd1498Szrj      If this is a register that is already known equivalent to an insn,
1638*38fd1498Szrj      update the qtys `const_insn' to show that `this_insn' is the latest
1639*38fd1498Szrj      insn making that quantity equivalent to the constant.  */
1640*38fd1498Szrj 
1641*38fd1498Szrj   if (elt->is_const && classp && REG_P (classp->exp)
1642*38fd1498Szrj       && !REG_P (x))
1643*38fd1498Szrj     {
1644*38fd1498Szrj       int exp_q = REG_QTY (REGNO (classp->exp));
1645*38fd1498Szrj       struct qty_table_elem *exp_ent = &qty_table[exp_q];
1646*38fd1498Szrj 
1647*38fd1498Szrj       exp_ent->const_rtx = gen_lowpart (exp_ent->mode, x);
1648*38fd1498Szrj       exp_ent->const_insn = this_insn;
1649*38fd1498Szrj     }
1650*38fd1498Szrj 
1651*38fd1498Szrj   else if (REG_P (x)
1652*38fd1498Szrj 	   && classp
1653*38fd1498Szrj 	   && ! qty_table[REG_QTY (REGNO (x))].const_rtx
1654*38fd1498Szrj 	   && ! elt->is_const)
1655*38fd1498Szrj     {
1656*38fd1498Szrj       struct table_elt *p;
1657*38fd1498Szrj 
1658*38fd1498Szrj       for (p = classp; p != 0; p = p->next_same_value)
1659*38fd1498Szrj 	{
1660*38fd1498Szrj 	  if (p->is_const && !REG_P (p->exp))
1661*38fd1498Szrj 	    {
1662*38fd1498Szrj 	      int x_q = REG_QTY (REGNO (x));
1663*38fd1498Szrj 	      struct qty_table_elem *x_ent = &qty_table[x_q];
1664*38fd1498Szrj 
1665*38fd1498Szrj 	      x_ent->const_rtx
1666*38fd1498Szrj 		= gen_lowpart (GET_MODE (x), p->exp);
1667*38fd1498Szrj 	      x_ent->const_insn = this_insn;
1668*38fd1498Szrj 	      break;
1669*38fd1498Szrj 	    }
1670*38fd1498Szrj 	}
1671*38fd1498Szrj     }
1672*38fd1498Szrj 
1673*38fd1498Szrj   else if (REG_P (x)
1674*38fd1498Szrj 	   && qty_table[REG_QTY (REGNO (x))].const_rtx
1675*38fd1498Szrj 	   && GET_MODE (x) == qty_table[REG_QTY (REGNO (x))].mode)
1676*38fd1498Szrj     qty_table[REG_QTY (REGNO (x))].const_insn = this_insn;
1677*38fd1498Szrj 
1678*38fd1498Szrj   /* If this is a constant with symbolic value,
1679*38fd1498Szrj      and it has a term with an explicit integer value,
1680*38fd1498Szrj      link it up with related expressions.  */
1681*38fd1498Szrj   if (GET_CODE (x) == CONST)
1682*38fd1498Szrj     {
1683*38fd1498Szrj       rtx subexp = get_related_value (x);
1684*38fd1498Szrj       unsigned subhash;
1685*38fd1498Szrj       struct table_elt *subelt, *subelt_prev;
1686*38fd1498Szrj 
1687*38fd1498Szrj       if (subexp != 0)
1688*38fd1498Szrj 	{
1689*38fd1498Szrj 	  /* Get the integer-free subexpression in the hash table.  */
1690*38fd1498Szrj 	  subhash = SAFE_HASH (subexp, mode);
1691*38fd1498Szrj 	  subelt = lookup (subexp, subhash, mode);
1692*38fd1498Szrj 	  if (subelt == 0)
1693*38fd1498Szrj 	    subelt = insert (subexp, NULL, subhash, mode);
1694*38fd1498Szrj 	  /* Initialize SUBELT's circular chain if it has none.  */
1695*38fd1498Szrj 	  if (subelt->related_value == 0)
1696*38fd1498Szrj 	    subelt->related_value = subelt;
1697*38fd1498Szrj 	  /* Find the element in the circular chain that precedes SUBELT.  */
1698*38fd1498Szrj 	  subelt_prev = subelt;
1699*38fd1498Szrj 	  while (subelt_prev->related_value != subelt)
1700*38fd1498Szrj 	    subelt_prev = subelt_prev->related_value;
1701*38fd1498Szrj 	  /* Put new ELT into SUBELT's circular chain just before SUBELT.
1702*38fd1498Szrj 	     This way the element that follows SUBELT is the oldest one.  */
1703*38fd1498Szrj 	  elt->related_value = subelt_prev->related_value;
1704*38fd1498Szrj 	  subelt_prev->related_value = elt;
1705*38fd1498Szrj 	}
1706*38fd1498Szrj     }
1707*38fd1498Szrj 
1708*38fd1498Szrj   return elt;
1709*38fd1498Szrj }
1710*38fd1498Szrj 
1711*38fd1498Szrj /* Wrap insert_with_costs by passing the default costs.  */
1712*38fd1498Szrj 
1713*38fd1498Szrj static struct table_elt *
insert(rtx x,struct table_elt * classp,unsigned int hash,machine_mode mode)1714*38fd1498Szrj insert (rtx x, struct table_elt *classp, unsigned int hash,
1715*38fd1498Szrj 	machine_mode mode)
1716*38fd1498Szrj {
1717*38fd1498Szrj   return insert_with_costs (x, classp, hash, mode,
1718*38fd1498Szrj 			    COST (x, mode), approx_reg_cost (x));
1719*38fd1498Szrj }
1720*38fd1498Szrj 
1721*38fd1498Szrj 
1722*38fd1498Szrj /* Given two equivalence classes, CLASS1 and CLASS2, put all the entries from
1723*38fd1498Szrj    CLASS2 into CLASS1.  This is done when we have reached an insn which makes
1724*38fd1498Szrj    the two classes equivalent.
1725*38fd1498Szrj 
1726*38fd1498Szrj    CLASS1 will be the surviving class; CLASS2 should not be used after this
1727*38fd1498Szrj    call.
1728*38fd1498Szrj 
1729*38fd1498Szrj    Any invalid entries in CLASS2 will not be copied.  */
1730*38fd1498Szrj 
1731*38fd1498Szrj static void
merge_equiv_classes(struct table_elt * class1,struct table_elt * class2)1732*38fd1498Szrj merge_equiv_classes (struct table_elt *class1, struct table_elt *class2)
1733*38fd1498Szrj {
1734*38fd1498Szrj   struct table_elt *elt, *next, *new_elt;
1735*38fd1498Szrj 
1736*38fd1498Szrj   /* Ensure we start with the head of the classes.  */
1737*38fd1498Szrj   class1 = class1->first_same_value;
1738*38fd1498Szrj   class2 = class2->first_same_value;
1739*38fd1498Szrj 
1740*38fd1498Szrj   /* If they were already equal, forget it.  */
1741*38fd1498Szrj   if (class1 == class2)
1742*38fd1498Szrj     return;
1743*38fd1498Szrj 
1744*38fd1498Szrj   for (elt = class2; elt; elt = next)
1745*38fd1498Szrj     {
1746*38fd1498Szrj       unsigned int hash;
1747*38fd1498Szrj       rtx exp = elt->exp;
1748*38fd1498Szrj       machine_mode mode = elt->mode;
1749*38fd1498Szrj 
1750*38fd1498Szrj       next = elt->next_same_value;
1751*38fd1498Szrj 
1752*38fd1498Szrj       /* Remove old entry, make a new one in CLASS1's class.
1753*38fd1498Szrj 	 Don't do this for invalid entries as we cannot find their
1754*38fd1498Szrj 	 hash code (it also isn't necessary).  */
1755*38fd1498Szrj       if (REG_P (exp) || exp_equiv_p (exp, exp, 1, false))
1756*38fd1498Szrj 	{
1757*38fd1498Szrj 	  bool need_rehash = false;
1758*38fd1498Szrj 
1759*38fd1498Szrj 	  hash_arg_in_memory = 0;
1760*38fd1498Szrj 	  hash = HASH (exp, mode);
1761*38fd1498Szrj 
1762*38fd1498Szrj 	  if (REG_P (exp))
1763*38fd1498Szrj 	    {
1764*38fd1498Szrj 	      need_rehash = REGNO_QTY_VALID_P (REGNO (exp));
1765*38fd1498Szrj 	      delete_reg_equiv (REGNO (exp));
1766*38fd1498Szrj 	    }
1767*38fd1498Szrj 
1768*38fd1498Szrj 	  if (REG_P (exp) && REGNO (exp) >= FIRST_PSEUDO_REGISTER)
1769*38fd1498Szrj 	    remove_pseudo_from_table (exp, hash);
1770*38fd1498Szrj 	  else
1771*38fd1498Szrj 	    remove_from_table (elt, hash);
1772*38fd1498Szrj 
1773*38fd1498Szrj 	  if (insert_regs (exp, class1, 0) || need_rehash)
1774*38fd1498Szrj 	    {
1775*38fd1498Szrj 	      rehash_using_reg (exp);
1776*38fd1498Szrj 	      hash = HASH (exp, mode);
1777*38fd1498Szrj 	    }
1778*38fd1498Szrj 	  new_elt = insert (exp, class1, hash, mode);
1779*38fd1498Szrj 	  new_elt->in_memory = hash_arg_in_memory;
1780*38fd1498Szrj 	  if (GET_CODE (exp) == ASM_OPERANDS && elt->cost == MAX_COST)
1781*38fd1498Szrj 	    new_elt->cost = MAX_COST;
1782*38fd1498Szrj 	}
1783*38fd1498Szrj     }
1784*38fd1498Szrj }
1785*38fd1498Szrj 
1786*38fd1498Szrj /* Flush the entire hash table.  */
1787*38fd1498Szrj 
1788*38fd1498Szrj static void
flush_hash_table(void)1789*38fd1498Szrj flush_hash_table (void)
1790*38fd1498Szrj {
1791*38fd1498Szrj   int i;
1792*38fd1498Szrj   struct table_elt *p;
1793*38fd1498Szrj 
1794*38fd1498Szrj   for (i = 0; i < HASH_SIZE; i++)
1795*38fd1498Szrj     for (p = table[i]; p; p = table[i])
1796*38fd1498Szrj       {
1797*38fd1498Szrj 	/* Note that invalidate can remove elements
1798*38fd1498Szrj 	   after P in the current hash chain.  */
1799*38fd1498Szrj 	if (REG_P (p->exp))
1800*38fd1498Szrj 	  invalidate (p->exp, VOIDmode);
1801*38fd1498Szrj 	else
1802*38fd1498Szrj 	  remove_from_table (p, i);
1803*38fd1498Szrj       }
1804*38fd1498Szrj }
1805*38fd1498Szrj 
1806*38fd1498Szrj /* Check whether an anti dependence exists between X and EXP.  MODE and
1807*38fd1498Szrj    ADDR are as for canon_anti_dependence.  */
1808*38fd1498Szrj 
1809*38fd1498Szrj static bool
check_dependence(const_rtx x,rtx exp,machine_mode mode,rtx addr)1810*38fd1498Szrj check_dependence (const_rtx x, rtx exp, machine_mode mode, rtx addr)
1811*38fd1498Szrj {
1812*38fd1498Szrj   subrtx_iterator::array_type array;
1813*38fd1498Szrj   FOR_EACH_SUBRTX (iter, array, x, NONCONST)
1814*38fd1498Szrj     {
1815*38fd1498Szrj       const_rtx x = *iter;
1816*38fd1498Szrj       if (MEM_P (x) && canon_anti_dependence (x, true, exp, mode, addr))
1817*38fd1498Szrj 	return true;
1818*38fd1498Szrj     }
1819*38fd1498Szrj   return false;
1820*38fd1498Szrj }
1821*38fd1498Szrj 
1822*38fd1498Szrj /* Remove from the hash table, or mark as invalid, all expressions whose
1823*38fd1498Szrj    values could be altered by storing in X.  X is a register, a subreg, or
1824*38fd1498Szrj    a memory reference with nonvarying address (because, when a memory
1825*38fd1498Szrj    reference with a varying address is stored in, all memory references are
1826*38fd1498Szrj    removed by invalidate_memory so specific invalidation is superfluous).
1827*38fd1498Szrj    FULL_MODE, if not VOIDmode, indicates that this much should be
1828*38fd1498Szrj    invalidated instead of just the amount indicated by the mode of X.  This
1829*38fd1498Szrj    is only used for bitfield stores into memory.
1830*38fd1498Szrj 
1831*38fd1498Szrj    A nonvarying address may be just a register or just a symbol reference,
1832*38fd1498Szrj    or it may be either of those plus a numeric offset.  */
1833*38fd1498Szrj 
1834*38fd1498Szrj static void
invalidate(rtx x,machine_mode full_mode)1835*38fd1498Szrj invalidate (rtx x, machine_mode full_mode)
1836*38fd1498Szrj {
1837*38fd1498Szrj   int i;
1838*38fd1498Szrj   struct table_elt *p;
1839*38fd1498Szrj   rtx addr;
1840*38fd1498Szrj 
1841*38fd1498Szrj   switch (GET_CODE (x))
1842*38fd1498Szrj     {
1843*38fd1498Szrj     case REG:
1844*38fd1498Szrj       {
1845*38fd1498Szrj 	/* If X is a register, dependencies on its contents are recorded
1846*38fd1498Szrj 	   through the qty number mechanism.  Just change the qty number of
1847*38fd1498Szrj 	   the register, mark it as invalid for expressions that refer to it,
1848*38fd1498Szrj 	   and remove it itself.  */
1849*38fd1498Szrj 	unsigned int regno = REGNO (x);
1850*38fd1498Szrj 	unsigned int hash = HASH (x, GET_MODE (x));
1851*38fd1498Szrj 
1852*38fd1498Szrj 	/* Remove REGNO from any quantity list it might be on and indicate
1853*38fd1498Szrj 	   that its value might have changed.  If it is a pseudo, remove its
1854*38fd1498Szrj 	   entry from the hash table.
1855*38fd1498Szrj 
1856*38fd1498Szrj 	   For a hard register, we do the first two actions above for any
1857*38fd1498Szrj 	   additional hard registers corresponding to X.  Then, if any of these
1858*38fd1498Szrj 	   registers are in the table, we must remove any REG entries that
1859*38fd1498Szrj 	   overlap these registers.  */
1860*38fd1498Szrj 
1861*38fd1498Szrj 	delete_reg_equiv (regno);
1862*38fd1498Szrj 	REG_TICK (regno)++;
1863*38fd1498Szrj 	SUBREG_TICKED (regno) = -1;
1864*38fd1498Szrj 
1865*38fd1498Szrj 	if (regno >= FIRST_PSEUDO_REGISTER)
1866*38fd1498Szrj 	  remove_pseudo_from_table (x, hash);
1867*38fd1498Szrj 	else
1868*38fd1498Szrj 	  {
1869*38fd1498Szrj 	    HOST_WIDE_INT in_table
1870*38fd1498Szrj 	      = TEST_HARD_REG_BIT (hard_regs_in_table, regno);
1871*38fd1498Szrj 	    unsigned int endregno = END_REGNO (x);
1872*38fd1498Szrj 	    unsigned int tregno, tendregno, rn;
1873*38fd1498Szrj 	    struct table_elt *p, *next;
1874*38fd1498Szrj 
1875*38fd1498Szrj 	    CLEAR_HARD_REG_BIT (hard_regs_in_table, regno);
1876*38fd1498Szrj 
1877*38fd1498Szrj 	    for (rn = regno + 1; rn < endregno; rn++)
1878*38fd1498Szrj 	      {
1879*38fd1498Szrj 		in_table |= TEST_HARD_REG_BIT (hard_regs_in_table, rn);
1880*38fd1498Szrj 		CLEAR_HARD_REG_BIT (hard_regs_in_table, rn);
1881*38fd1498Szrj 		delete_reg_equiv (rn);
1882*38fd1498Szrj 		REG_TICK (rn)++;
1883*38fd1498Szrj 		SUBREG_TICKED (rn) = -1;
1884*38fd1498Szrj 	      }
1885*38fd1498Szrj 
1886*38fd1498Szrj 	    if (in_table)
1887*38fd1498Szrj 	      for (hash = 0; hash < HASH_SIZE; hash++)
1888*38fd1498Szrj 		for (p = table[hash]; p; p = next)
1889*38fd1498Szrj 		  {
1890*38fd1498Szrj 		    next = p->next_same_hash;
1891*38fd1498Szrj 
1892*38fd1498Szrj 		    if (!REG_P (p->exp)
1893*38fd1498Szrj 			|| REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
1894*38fd1498Szrj 		      continue;
1895*38fd1498Szrj 
1896*38fd1498Szrj 		    tregno = REGNO (p->exp);
1897*38fd1498Szrj 		    tendregno = END_REGNO (p->exp);
1898*38fd1498Szrj 		    if (tendregno > regno && tregno < endregno)
1899*38fd1498Szrj 		      remove_from_table (p, hash);
1900*38fd1498Szrj 		  }
1901*38fd1498Szrj 	  }
1902*38fd1498Szrj       }
1903*38fd1498Szrj       return;
1904*38fd1498Szrj 
1905*38fd1498Szrj     case SUBREG:
1906*38fd1498Szrj       invalidate (SUBREG_REG (x), VOIDmode);
1907*38fd1498Szrj       return;
1908*38fd1498Szrj 
1909*38fd1498Szrj     case PARALLEL:
1910*38fd1498Szrj       for (i = XVECLEN (x, 0) - 1; i >= 0; --i)
1911*38fd1498Szrj 	invalidate (XVECEXP (x, 0, i), VOIDmode);
1912*38fd1498Szrj       return;
1913*38fd1498Szrj 
1914*38fd1498Szrj     case EXPR_LIST:
1915*38fd1498Szrj       /* This is part of a disjoint return value; extract the location in
1916*38fd1498Szrj 	 question ignoring the offset.  */
1917*38fd1498Szrj       invalidate (XEXP (x, 0), VOIDmode);
1918*38fd1498Szrj       return;
1919*38fd1498Szrj 
1920*38fd1498Szrj     case MEM:
1921*38fd1498Szrj       addr = canon_rtx (get_addr (XEXP (x, 0)));
1922*38fd1498Szrj       /* Calculate the canonical version of X here so that
1923*38fd1498Szrj 	 true_dependence doesn't generate new RTL for X on each call.  */
1924*38fd1498Szrj       x = canon_rtx (x);
1925*38fd1498Szrj 
1926*38fd1498Szrj       /* Remove all hash table elements that refer to overlapping pieces of
1927*38fd1498Szrj 	 memory.  */
1928*38fd1498Szrj       if (full_mode == VOIDmode)
1929*38fd1498Szrj 	full_mode = GET_MODE (x);
1930*38fd1498Szrj 
1931*38fd1498Szrj       for (i = 0; i < HASH_SIZE; i++)
1932*38fd1498Szrj 	{
1933*38fd1498Szrj 	  struct table_elt *next;
1934*38fd1498Szrj 
1935*38fd1498Szrj 	  for (p = table[i]; p; p = next)
1936*38fd1498Szrj 	    {
1937*38fd1498Szrj 	      next = p->next_same_hash;
1938*38fd1498Szrj 	      if (p->in_memory)
1939*38fd1498Szrj 		{
1940*38fd1498Szrj 		  /* Just canonicalize the expression once;
1941*38fd1498Szrj 		     otherwise each time we call invalidate
1942*38fd1498Szrj 		     true_dependence will canonicalize the
1943*38fd1498Szrj 		     expression again.  */
1944*38fd1498Szrj 		  if (!p->canon_exp)
1945*38fd1498Szrj 		    p->canon_exp = canon_rtx (p->exp);
1946*38fd1498Szrj 		  if (check_dependence (p->canon_exp, x, full_mode, addr))
1947*38fd1498Szrj 		    remove_from_table (p, i);
1948*38fd1498Szrj 		}
1949*38fd1498Szrj 	    }
1950*38fd1498Szrj 	}
1951*38fd1498Szrj       return;
1952*38fd1498Szrj 
1953*38fd1498Szrj     default:
1954*38fd1498Szrj       gcc_unreachable ();
1955*38fd1498Szrj     }
1956*38fd1498Szrj }
1957*38fd1498Szrj 
1958*38fd1498Szrj /* Invalidate DEST.  Used when DEST is not going to be added
1959*38fd1498Szrj    into the hash table for some reason, e.g. do_not_record
1960*38fd1498Szrj    flagged on it.  */
1961*38fd1498Szrj 
1962*38fd1498Szrj static void
invalidate_dest(rtx dest)1963*38fd1498Szrj invalidate_dest (rtx dest)
1964*38fd1498Szrj {
1965*38fd1498Szrj   if (REG_P (dest)
1966*38fd1498Szrj       || GET_CODE (dest) == SUBREG
1967*38fd1498Szrj       || MEM_P (dest))
1968*38fd1498Szrj     invalidate (dest, VOIDmode);
1969*38fd1498Szrj   else if (GET_CODE (dest) == STRICT_LOW_PART
1970*38fd1498Szrj 	   || GET_CODE (dest) == ZERO_EXTRACT)
1971*38fd1498Szrj     invalidate (XEXP (dest, 0), GET_MODE (dest));
1972*38fd1498Szrj }
1973*38fd1498Szrj 
1974*38fd1498Szrj /* Remove all expressions that refer to register REGNO,
1975*38fd1498Szrj    since they are already invalid, and we are about to
1976*38fd1498Szrj    mark that register valid again and don't want the old
1977*38fd1498Szrj    expressions to reappear as valid.  */
1978*38fd1498Szrj 
1979*38fd1498Szrj static void
remove_invalid_refs(unsigned int regno)1980*38fd1498Szrj remove_invalid_refs (unsigned int regno)
1981*38fd1498Szrj {
1982*38fd1498Szrj   unsigned int i;
1983*38fd1498Szrj   struct table_elt *p, *next;
1984*38fd1498Szrj 
1985*38fd1498Szrj   for (i = 0; i < HASH_SIZE; i++)
1986*38fd1498Szrj     for (p = table[i]; p; p = next)
1987*38fd1498Szrj       {
1988*38fd1498Szrj 	next = p->next_same_hash;
1989*38fd1498Szrj 	if (!REG_P (p->exp) && refers_to_regno_p (regno, p->exp))
1990*38fd1498Szrj 	  remove_from_table (p, i);
1991*38fd1498Szrj       }
1992*38fd1498Szrj }
1993*38fd1498Szrj 
1994*38fd1498Szrj /* Likewise for a subreg with subreg_reg REGNO, subreg_byte OFFSET,
1995*38fd1498Szrj    and mode MODE.  */
1996*38fd1498Szrj static void
remove_invalid_subreg_refs(unsigned int regno,poly_uint64 offset,machine_mode mode)1997*38fd1498Szrj remove_invalid_subreg_refs (unsigned int regno, poly_uint64 offset,
1998*38fd1498Szrj 			    machine_mode mode)
1999*38fd1498Szrj {
2000*38fd1498Szrj   unsigned int i;
2001*38fd1498Szrj   struct table_elt *p, *next;
2002*38fd1498Szrj 
2003*38fd1498Szrj   for (i = 0; i < HASH_SIZE; i++)
2004*38fd1498Szrj     for (p = table[i]; p; p = next)
2005*38fd1498Szrj       {
2006*38fd1498Szrj 	rtx exp = p->exp;
2007*38fd1498Szrj 	next = p->next_same_hash;
2008*38fd1498Szrj 
2009*38fd1498Szrj 	if (!REG_P (exp)
2010*38fd1498Szrj 	    && (GET_CODE (exp) != SUBREG
2011*38fd1498Szrj 		|| !REG_P (SUBREG_REG (exp))
2012*38fd1498Szrj 		|| REGNO (SUBREG_REG (exp)) != regno
2013*38fd1498Szrj 		|| ranges_maybe_overlap_p (SUBREG_BYTE (exp),
2014*38fd1498Szrj 					   GET_MODE_SIZE (GET_MODE (exp)),
2015*38fd1498Szrj 					   offset, GET_MODE_SIZE (mode)))
2016*38fd1498Szrj 	    && refers_to_regno_p (regno, p->exp))
2017*38fd1498Szrj 	  remove_from_table (p, i);
2018*38fd1498Szrj       }
2019*38fd1498Szrj }
2020*38fd1498Szrj 
2021*38fd1498Szrj /* Recompute the hash codes of any valid entries in the hash table that
2022*38fd1498Szrj    reference X, if X is a register, or SUBREG_REG (X) if X is a SUBREG.
2023*38fd1498Szrj 
2024*38fd1498Szrj    This is called when we make a jump equivalence.  */
2025*38fd1498Szrj 
2026*38fd1498Szrj static void
rehash_using_reg(rtx x)2027*38fd1498Szrj rehash_using_reg (rtx x)
2028*38fd1498Szrj {
2029*38fd1498Szrj   unsigned int i;
2030*38fd1498Szrj   struct table_elt *p, *next;
2031*38fd1498Szrj   unsigned hash;
2032*38fd1498Szrj 
2033*38fd1498Szrj   if (GET_CODE (x) == SUBREG)
2034*38fd1498Szrj     x = SUBREG_REG (x);
2035*38fd1498Szrj 
2036*38fd1498Szrj   /* If X is not a register or if the register is known not to be in any
2037*38fd1498Szrj      valid entries in the table, we have no work to do.  */
2038*38fd1498Szrj 
2039*38fd1498Szrj   if (!REG_P (x)
2040*38fd1498Szrj       || REG_IN_TABLE (REGNO (x)) < 0
2041*38fd1498Szrj       || REG_IN_TABLE (REGNO (x)) != REG_TICK (REGNO (x)))
2042*38fd1498Szrj     return;
2043*38fd1498Szrj 
2044*38fd1498Szrj   /* Scan all hash chains looking for valid entries that mention X.
2045*38fd1498Szrj      If we find one and it is in the wrong hash chain, move it.  */
2046*38fd1498Szrj 
2047*38fd1498Szrj   for (i = 0; i < HASH_SIZE; i++)
2048*38fd1498Szrj     for (p = table[i]; p; p = next)
2049*38fd1498Szrj       {
2050*38fd1498Szrj 	next = p->next_same_hash;
2051*38fd1498Szrj 	if (reg_mentioned_p (x, p->exp)
2052*38fd1498Szrj 	    && exp_equiv_p (p->exp, p->exp, 1, false)
2053*38fd1498Szrj 	    && i != (hash = SAFE_HASH (p->exp, p->mode)))
2054*38fd1498Szrj 	  {
2055*38fd1498Szrj 	    if (p->next_same_hash)
2056*38fd1498Szrj 	      p->next_same_hash->prev_same_hash = p->prev_same_hash;
2057*38fd1498Szrj 
2058*38fd1498Szrj 	    if (p->prev_same_hash)
2059*38fd1498Szrj 	      p->prev_same_hash->next_same_hash = p->next_same_hash;
2060*38fd1498Szrj 	    else
2061*38fd1498Szrj 	      table[i] = p->next_same_hash;
2062*38fd1498Szrj 
2063*38fd1498Szrj 	    p->next_same_hash = table[hash];
2064*38fd1498Szrj 	    p->prev_same_hash = 0;
2065*38fd1498Szrj 	    if (table[hash])
2066*38fd1498Szrj 	      table[hash]->prev_same_hash = p;
2067*38fd1498Szrj 	    table[hash] = p;
2068*38fd1498Szrj 	  }
2069*38fd1498Szrj       }
2070*38fd1498Szrj }
2071*38fd1498Szrj 
2072*38fd1498Szrj /* Remove from the hash table any expression that is a call-clobbered
2073*38fd1498Szrj    register.  Also update their TICK values.  */
2074*38fd1498Szrj 
2075*38fd1498Szrj static void
invalidate_for_call(void)2076*38fd1498Szrj invalidate_for_call (void)
2077*38fd1498Szrj {
2078*38fd1498Szrj   unsigned int regno, endregno;
2079*38fd1498Szrj   unsigned int i;
2080*38fd1498Szrj   unsigned hash;
2081*38fd1498Szrj   struct table_elt *p, *next;
2082*38fd1498Szrj   int in_table = 0;
2083*38fd1498Szrj   hard_reg_set_iterator hrsi;
2084*38fd1498Szrj 
2085*38fd1498Szrj   /* Go through all the hard registers.  For each that is clobbered in
2086*38fd1498Szrj      a CALL_INSN, remove the register from quantity chains and update
2087*38fd1498Szrj      reg_tick if defined.  Also see if any of these registers is currently
2088*38fd1498Szrj      in the table.  */
2089*38fd1498Szrj   EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, regno, hrsi)
2090*38fd1498Szrj     {
2091*38fd1498Szrj       delete_reg_equiv (regno);
2092*38fd1498Szrj       if (REG_TICK (regno) >= 0)
2093*38fd1498Szrj 	{
2094*38fd1498Szrj 	  REG_TICK (regno)++;
2095*38fd1498Szrj 	  SUBREG_TICKED (regno) = -1;
2096*38fd1498Szrj 	}
2097*38fd1498Szrj       in_table |= (TEST_HARD_REG_BIT (hard_regs_in_table, regno) != 0);
2098*38fd1498Szrj     }
2099*38fd1498Szrj 
2100*38fd1498Szrj   /* In the case where we have no call-clobbered hard registers in the
2101*38fd1498Szrj      table, we are done.  Otherwise, scan the table and remove any
2102*38fd1498Szrj      entry that overlaps a call-clobbered register.  */
2103*38fd1498Szrj 
2104*38fd1498Szrj   if (in_table)
2105*38fd1498Szrj     for (hash = 0; hash < HASH_SIZE; hash++)
2106*38fd1498Szrj       for (p = table[hash]; p; p = next)
2107*38fd1498Szrj 	{
2108*38fd1498Szrj 	  next = p->next_same_hash;
2109*38fd1498Szrj 
2110*38fd1498Szrj 	  if (!REG_P (p->exp)
2111*38fd1498Szrj 	      || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
2112*38fd1498Szrj 	    continue;
2113*38fd1498Szrj 
2114*38fd1498Szrj 	  regno = REGNO (p->exp);
2115*38fd1498Szrj 	  endregno = END_REGNO (p->exp);
2116*38fd1498Szrj 
2117*38fd1498Szrj 	  for (i = regno; i < endregno; i++)
2118*38fd1498Szrj 	    if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
2119*38fd1498Szrj 	      {
2120*38fd1498Szrj 		remove_from_table (p, hash);
2121*38fd1498Szrj 		break;
2122*38fd1498Szrj 	      }
2123*38fd1498Szrj 	}
2124*38fd1498Szrj }
2125*38fd1498Szrj 
2126*38fd1498Szrj /* Given an expression X of type CONST,
2127*38fd1498Szrj    and ELT which is its table entry (or 0 if it
2128*38fd1498Szrj    is not in the hash table),
2129*38fd1498Szrj    return an alternate expression for X as a register plus integer.
2130*38fd1498Szrj    If none can be found, return 0.  */
2131*38fd1498Szrj 
2132*38fd1498Szrj static rtx
use_related_value(rtx x,struct table_elt * elt)2133*38fd1498Szrj use_related_value (rtx x, struct table_elt *elt)
2134*38fd1498Szrj {
2135*38fd1498Szrj   struct table_elt *relt = 0;
2136*38fd1498Szrj   struct table_elt *p, *q;
2137*38fd1498Szrj   HOST_WIDE_INT offset;
2138*38fd1498Szrj 
2139*38fd1498Szrj   /* First, is there anything related known?
2140*38fd1498Szrj      If we have a table element, we can tell from that.
2141*38fd1498Szrj      Otherwise, must look it up.  */
2142*38fd1498Szrj 
2143*38fd1498Szrj   if (elt != 0 && elt->related_value != 0)
2144*38fd1498Szrj     relt = elt;
2145*38fd1498Szrj   else if (elt == 0 && GET_CODE (x) == CONST)
2146*38fd1498Szrj     {
2147*38fd1498Szrj       rtx subexp = get_related_value (x);
2148*38fd1498Szrj       if (subexp != 0)
2149*38fd1498Szrj 	relt = lookup (subexp,
2150*38fd1498Szrj 		       SAFE_HASH (subexp, GET_MODE (subexp)),
2151*38fd1498Szrj 		       GET_MODE (subexp));
2152*38fd1498Szrj     }
2153*38fd1498Szrj 
2154*38fd1498Szrj   if (relt == 0)
2155*38fd1498Szrj     return 0;
2156*38fd1498Szrj 
2157*38fd1498Szrj   /* Search all related table entries for one that has an
2158*38fd1498Szrj      equivalent register.  */
2159*38fd1498Szrj 
2160*38fd1498Szrj   p = relt;
2161*38fd1498Szrj   while (1)
2162*38fd1498Szrj     {
2163*38fd1498Szrj       /* This loop is strange in that it is executed in two different cases.
2164*38fd1498Szrj 	 The first is when X is already in the table.  Then it is searching
2165*38fd1498Szrj 	 the RELATED_VALUE list of X's class (RELT).  The second case is when
2166*38fd1498Szrj 	 X is not in the table.  Then RELT points to a class for the related
2167*38fd1498Szrj 	 value.
2168*38fd1498Szrj 
2169*38fd1498Szrj 	 Ensure that, whatever case we are in, that we ignore classes that have
2170*38fd1498Szrj 	 the same value as X.  */
2171*38fd1498Szrj 
2172*38fd1498Szrj       if (rtx_equal_p (x, p->exp))
2173*38fd1498Szrj 	q = 0;
2174*38fd1498Szrj       else
2175*38fd1498Szrj 	for (q = p->first_same_value; q; q = q->next_same_value)
2176*38fd1498Szrj 	  if (REG_P (q->exp))
2177*38fd1498Szrj 	    break;
2178*38fd1498Szrj 
2179*38fd1498Szrj       if (q)
2180*38fd1498Szrj 	break;
2181*38fd1498Szrj 
2182*38fd1498Szrj       p = p->related_value;
2183*38fd1498Szrj 
2184*38fd1498Szrj       /* We went all the way around, so there is nothing to be found.
2185*38fd1498Szrj 	 Alternatively, perhaps RELT was in the table for some other reason
2186*38fd1498Szrj 	 and it has no related values recorded.  */
2187*38fd1498Szrj       if (p == relt || p == 0)
2188*38fd1498Szrj 	break;
2189*38fd1498Szrj     }
2190*38fd1498Szrj 
2191*38fd1498Szrj   if (q == 0)
2192*38fd1498Szrj     return 0;
2193*38fd1498Szrj 
2194*38fd1498Szrj   offset = (get_integer_term (x) - get_integer_term (p->exp));
2195*38fd1498Szrj   /* Note: OFFSET may be 0 if P->xexp and X are related by commutativity.  */
2196*38fd1498Szrj   return plus_constant (q->mode, q->exp, offset);
2197*38fd1498Szrj }
2198*38fd1498Szrj 
2199*38fd1498Szrj 
2200*38fd1498Szrj /* Hash a string.  Just add its bytes up.  */
2201*38fd1498Szrj static inline unsigned
hash_rtx_string(const char * ps)2202*38fd1498Szrj hash_rtx_string (const char *ps)
2203*38fd1498Szrj {
2204*38fd1498Szrj   unsigned hash = 0;
2205*38fd1498Szrj   const unsigned char *p = (const unsigned char *) ps;
2206*38fd1498Szrj 
2207*38fd1498Szrj   if (p)
2208*38fd1498Szrj     while (*p)
2209*38fd1498Szrj       hash += *p++;
2210*38fd1498Szrj 
2211*38fd1498Szrj   return hash;
2212*38fd1498Szrj }
2213*38fd1498Szrj 
2214*38fd1498Szrj /* Same as hash_rtx, but call CB on each rtx if it is not NULL.
2215*38fd1498Szrj    When the callback returns true, we continue with the new rtx.  */
2216*38fd1498Szrj 
2217*38fd1498Szrj unsigned
hash_rtx_cb(const_rtx x,machine_mode mode,int * do_not_record_p,int * hash_arg_in_memory_p,bool have_reg_qty,hash_rtx_callback_function cb)2218*38fd1498Szrj hash_rtx_cb (const_rtx x, machine_mode mode,
2219*38fd1498Szrj              int *do_not_record_p, int *hash_arg_in_memory_p,
2220*38fd1498Szrj              bool have_reg_qty, hash_rtx_callback_function cb)
2221*38fd1498Szrj {
2222*38fd1498Szrj   int i, j;
2223*38fd1498Szrj   unsigned hash = 0;
2224*38fd1498Szrj   enum rtx_code code;
2225*38fd1498Szrj   const char *fmt;
2226*38fd1498Szrj   machine_mode newmode;
2227*38fd1498Szrj   rtx newx;
2228*38fd1498Szrj 
2229*38fd1498Szrj   /* Used to turn recursion into iteration.  We can't rely on GCC's
2230*38fd1498Szrj      tail-recursion elimination since we need to keep accumulating values
2231*38fd1498Szrj      in HASH.  */
2232*38fd1498Szrj  repeat:
2233*38fd1498Szrj   if (x == 0)
2234*38fd1498Szrj     return hash;
2235*38fd1498Szrj 
2236*38fd1498Szrj   /* Invoke the callback first.  */
2237*38fd1498Szrj   if (cb != NULL
2238*38fd1498Szrj       && ((*cb) (x, mode, &newx, &newmode)))
2239*38fd1498Szrj     {
2240*38fd1498Szrj       hash += hash_rtx_cb (newx, newmode, do_not_record_p,
2241*38fd1498Szrj                            hash_arg_in_memory_p, have_reg_qty, cb);
2242*38fd1498Szrj       return hash;
2243*38fd1498Szrj     }
2244*38fd1498Szrj 
2245*38fd1498Szrj   code = GET_CODE (x);
2246*38fd1498Szrj   switch (code)
2247*38fd1498Szrj     {
2248*38fd1498Szrj     case REG:
2249*38fd1498Szrj       {
2250*38fd1498Szrj 	unsigned int regno = REGNO (x);
2251*38fd1498Szrj 
2252*38fd1498Szrj 	if (do_not_record_p && !reload_completed)
2253*38fd1498Szrj 	  {
2254*38fd1498Szrj 	    /* On some machines, we can't record any non-fixed hard register,
2255*38fd1498Szrj 	       because extending its life will cause reload problems.  We
2256*38fd1498Szrj 	       consider ap, fp, sp, gp to be fixed for this purpose.
2257*38fd1498Szrj 
2258*38fd1498Szrj 	       We also consider CCmode registers to be fixed for this purpose;
2259*38fd1498Szrj 	       failure to do so leads to failure to simplify 0<100 type of
2260*38fd1498Szrj 	       conditionals.
2261*38fd1498Szrj 
2262*38fd1498Szrj 	       On all machines, we can't record any global registers.
2263*38fd1498Szrj 	       Nor should we record any register that is in a small
2264*38fd1498Szrj 	       class, as defined by TARGET_CLASS_LIKELY_SPILLED_P.  */
2265*38fd1498Szrj 	    bool record;
2266*38fd1498Szrj 
2267*38fd1498Szrj 	    if (regno >= FIRST_PSEUDO_REGISTER)
2268*38fd1498Szrj 	      record = true;
2269*38fd1498Szrj 	    else if (x == frame_pointer_rtx
2270*38fd1498Szrj 		     || x == hard_frame_pointer_rtx
2271*38fd1498Szrj 		     || x == arg_pointer_rtx
2272*38fd1498Szrj 		     || x == stack_pointer_rtx
2273*38fd1498Szrj 		     || x == pic_offset_table_rtx)
2274*38fd1498Szrj 	      record = true;
2275*38fd1498Szrj 	    else if (global_regs[regno])
2276*38fd1498Szrj 	      record = false;
2277*38fd1498Szrj 	    else if (fixed_regs[regno])
2278*38fd1498Szrj 	      record = true;
2279*38fd1498Szrj 	    else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC)
2280*38fd1498Szrj 	      record = true;
2281*38fd1498Szrj 	    else if (targetm.small_register_classes_for_mode_p (GET_MODE (x)))
2282*38fd1498Szrj 	      record = false;
2283*38fd1498Szrj 	    else if (targetm.class_likely_spilled_p (REGNO_REG_CLASS (regno)))
2284*38fd1498Szrj 	      record = false;
2285*38fd1498Szrj 	    else
2286*38fd1498Szrj 	      record = true;
2287*38fd1498Szrj 
2288*38fd1498Szrj 	    if (!record)
2289*38fd1498Szrj 	      {
2290*38fd1498Szrj 		*do_not_record_p = 1;
2291*38fd1498Szrj 		return 0;
2292*38fd1498Szrj 	      }
2293*38fd1498Szrj 	  }
2294*38fd1498Szrj 
2295*38fd1498Szrj 	hash += ((unsigned int) REG << 7);
2296*38fd1498Szrj         hash += (have_reg_qty ? (unsigned) REG_QTY (regno) : regno);
2297*38fd1498Szrj 	return hash;
2298*38fd1498Szrj       }
2299*38fd1498Szrj 
2300*38fd1498Szrj     /* We handle SUBREG of a REG specially because the underlying
2301*38fd1498Szrj        reg changes its hash value with every value change; we don't
2302*38fd1498Szrj        want to have to forget unrelated subregs when one subreg changes.  */
2303*38fd1498Szrj     case SUBREG:
2304*38fd1498Szrj       {
2305*38fd1498Szrj 	if (REG_P (SUBREG_REG (x)))
2306*38fd1498Szrj 	  {
2307*38fd1498Szrj 	    hash += (((unsigned int) SUBREG << 7)
2308*38fd1498Szrj 		     + REGNO (SUBREG_REG (x))
2309*38fd1498Szrj 		     + (constant_lower_bound (SUBREG_BYTE (x))
2310*38fd1498Szrj 			/ UNITS_PER_WORD));
2311*38fd1498Szrj 	    return hash;
2312*38fd1498Szrj 	  }
2313*38fd1498Szrj 	break;
2314*38fd1498Szrj       }
2315*38fd1498Szrj 
2316*38fd1498Szrj     case CONST_INT:
2317*38fd1498Szrj       hash += (((unsigned int) CONST_INT << 7) + (unsigned int) mode
2318*38fd1498Szrj                + (unsigned int) INTVAL (x));
2319*38fd1498Szrj       return hash;
2320*38fd1498Szrj 
2321*38fd1498Szrj     case CONST_WIDE_INT:
2322*38fd1498Szrj       for (i = 0; i < CONST_WIDE_INT_NUNITS (x); i++)
2323*38fd1498Szrj 	hash += CONST_WIDE_INT_ELT (x, i);
2324*38fd1498Szrj       return hash;
2325*38fd1498Szrj 
2326*38fd1498Szrj     case CONST_POLY_INT:
2327*38fd1498Szrj       {
2328*38fd1498Szrj 	inchash::hash h;
2329*38fd1498Szrj 	h.add_int (hash);
2330*38fd1498Szrj 	for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
2331*38fd1498Szrj 	  h.add_wide_int (CONST_POLY_INT_COEFFS (x)[i]);
2332*38fd1498Szrj 	return h.end ();
2333*38fd1498Szrj       }
2334*38fd1498Szrj 
2335*38fd1498Szrj     case CONST_DOUBLE:
2336*38fd1498Szrj       /* This is like the general case, except that it only counts
2337*38fd1498Szrj 	 the integers representing the constant.  */
2338*38fd1498Szrj       hash += (unsigned int) code + (unsigned int) GET_MODE (x);
2339*38fd1498Szrj       if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (x) == VOIDmode)
2340*38fd1498Szrj 	hash += ((unsigned int) CONST_DOUBLE_LOW (x)
2341*38fd1498Szrj 		 + (unsigned int) CONST_DOUBLE_HIGH (x));
2342*38fd1498Szrj       else
2343*38fd1498Szrj 	hash += real_hash (CONST_DOUBLE_REAL_VALUE (x));
2344*38fd1498Szrj       return hash;
2345*38fd1498Szrj 
2346*38fd1498Szrj     case CONST_FIXED:
2347*38fd1498Szrj       hash += (unsigned int) code + (unsigned int) GET_MODE (x);
2348*38fd1498Szrj       hash += fixed_hash (CONST_FIXED_VALUE (x));
2349*38fd1498Szrj       return hash;
2350*38fd1498Szrj 
2351*38fd1498Szrj     case CONST_VECTOR:
2352*38fd1498Szrj       {
2353*38fd1498Szrj 	int units;
2354*38fd1498Szrj 	rtx elt;
2355*38fd1498Szrj 
2356*38fd1498Szrj 	units = const_vector_encoded_nelts (x);
2357*38fd1498Szrj 
2358*38fd1498Szrj 	for (i = 0; i < units; ++i)
2359*38fd1498Szrj 	  {
2360*38fd1498Szrj 	    elt = CONST_VECTOR_ENCODED_ELT (x, i);
2361*38fd1498Szrj 	    hash += hash_rtx_cb (elt, GET_MODE (elt),
2362*38fd1498Szrj                                  do_not_record_p, hash_arg_in_memory_p,
2363*38fd1498Szrj                                  have_reg_qty, cb);
2364*38fd1498Szrj 	  }
2365*38fd1498Szrj 
2366*38fd1498Szrj 	return hash;
2367*38fd1498Szrj       }
2368*38fd1498Szrj 
2369*38fd1498Szrj       /* Assume there is only one rtx object for any given label.  */
2370*38fd1498Szrj     case LABEL_REF:
2371*38fd1498Szrj       /* We don't hash on the address of the CODE_LABEL to avoid bootstrap
2372*38fd1498Szrj 	 differences and differences between each stage's debugging dumps.  */
2373*38fd1498Szrj 	 hash += (((unsigned int) LABEL_REF << 7)
2374*38fd1498Szrj 		  + CODE_LABEL_NUMBER (label_ref_label (x)));
2375*38fd1498Szrj       return hash;
2376*38fd1498Szrj 
2377*38fd1498Szrj     case SYMBOL_REF:
2378*38fd1498Szrj       {
2379*38fd1498Szrj 	/* Don't hash on the symbol's address to avoid bootstrap differences.
2380*38fd1498Szrj 	   Different hash values may cause expressions to be recorded in
2381*38fd1498Szrj 	   different orders and thus different registers to be used in the
2382*38fd1498Szrj 	   final assembler.  This also avoids differences in the dump files
2383*38fd1498Szrj 	   between various stages.  */
2384*38fd1498Szrj 	unsigned int h = 0;
2385*38fd1498Szrj 	const unsigned char *p = (const unsigned char *) XSTR (x, 0);
2386*38fd1498Szrj 
2387*38fd1498Szrj 	while (*p)
2388*38fd1498Szrj 	  h += (h << 7) + *p++; /* ??? revisit */
2389*38fd1498Szrj 
2390*38fd1498Szrj 	hash += ((unsigned int) SYMBOL_REF << 7) + h;
2391*38fd1498Szrj 	return hash;
2392*38fd1498Szrj       }
2393*38fd1498Szrj 
2394*38fd1498Szrj     case MEM:
2395*38fd1498Szrj       /* We don't record if marked volatile or if BLKmode since we don't
2396*38fd1498Szrj 	 know the size of the move.  */
2397*38fd1498Szrj       if (do_not_record_p && (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode))
2398*38fd1498Szrj 	{
2399*38fd1498Szrj 	  *do_not_record_p = 1;
2400*38fd1498Szrj 	  return 0;
2401*38fd1498Szrj 	}
2402*38fd1498Szrj       if (hash_arg_in_memory_p && !MEM_READONLY_P (x))
2403*38fd1498Szrj 	*hash_arg_in_memory_p = 1;
2404*38fd1498Szrj 
2405*38fd1498Szrj       /* Now that we have already found this special case,
2406*38fd1498Szrj 	 might as well speed it up as much as possible.  */
2407*38fd1498Szrj       hash += (unsigned) MEM;
2408*38fd1498Szrj       x = XEXP (x, 0);
2409*38fd1498Szrj       goto repeat;
2410*38fd1498Szrj 
2411*38fd1498Szrj     case USE:
2412*38fd1498Szrj       /* A USE that mentions non-volatile memory needs special
2413*38fd1498Szrj 	 handling since the MEM may be BLKmode which normally
2414*38fd1498Szrj 	 prevents an entry from being made.  Pure calls are
2415*38fd1498Szrj 	 marked by a USE which mentions BLKmode memory.
2416*38fd1498Szrj 	 See calls.c:emit_call_1.  */
2417*38fd1498Szrj       if (MEM_P (XEXP (x, 0))
2418*38fd1498Szrj 	  && ! MEM_VOLATILE_P (XEXP (x, 0)))
2419*38fd1498Szrj 	{
2420*38fd1498Szrj 	  hash += (unsigned) USE;
2421*38fd1498Szrj 	  x = XEXP (x, 0);
2422*38fd1498Szrj 
2423*38fd1498Szrj 	  if (hash_arg_in_memory_p && !MEM_READONLY_P (x))
2424*38fd1498Szrj 	    *hash_arg_in_memory_p = 1;
2425*38fd1498Szrj 
2426*38fd1498Szrj 	  /* Now that we have already found this special case,
2427*38fd1498Szrj 	     might as well speed it up as much as possible.  */
2428*38fd1498Szrj 	  hash += (unsigned) MEM;
2429*38fd1498Szrj 	  x = XEXP (x, 0);
2430*38fd1498Szrj 	  goto repeat;
2431*38fd1498Szrj 	}
2432*38fd1498Szrj       break;
2433*38fd1498Szrj 
2434*38fd1498Szrj     case PRE_DEC:
2435*38fd1498Szrj     case PRE_INC:
2436*38fd1498Szrj     case POST_DEC:
2437*38fd1498Szrj     case POST_INC:
2438*38fd1498Szrj     case PRE_MODIFY:
2439*38fd1498Szrj     case POST_MODIFY:
2440*38fd1498Szrj     case PC:
2441*38fd1498Szrj     case CC0:
2442*38fd1498Szrj     case CALL:
2443*38fd1498Szrj     case UNSPEC_VOLATILE:
2444*38fd1498Szrj       if (do_not_record_p) {
2445*38fd1498Szrj         *do_not_record_p = 1;
2446*38fd1498Szrj         return 0;
2447*38fd1498Szrj       }
2448*38fd1498Szrj       else
2449*38fd1498Szrj         return hash;
2450*38fd1498Szrj       break;
2451*38fd1498Szrj 
2452*38fd1498Szrj     case ASM_OPERANDS:
2453*38fd1498Szrj       if (do_not_record_p && MEM_VOLATILE_P (x))
2454*38fd1498Szrj 	{
2455*38fd1498Szrj 	  *do_not_record_p = 1;
2456*38fd1498Szrj 	  return 0;
2457*38fd1498Szrj 	}
2458*38fd1498Szrj       else
2459*38fd1498Szrj 	{
2460*38fd1498Szrj 	  /* We don't want to take the filename and line into account.  */
2461*38fd1498Szrj 	  hash += (unsigned) code + (unsigned) GET_MODE (x)
2462*38fd1498Szrj 	    + hash_rtx_string (ASM_OPERANDS_TEMPLATE (x))
2463*38fd1498Szrj 	    + hash_rtx_string (ASM_OPERANDS_OUTPUT_CONSTRAINT (x))
2464*38fd1498Szrj 	    + (unsigned) ASM_OPERANDS_OUTPUT_IDX (x);
2465*38fd1498Szrj 
2466*38fd1498Szrj 	  if (ASM_OPERANDS_INPUT_LENGTH (x))
2467*38fd1498Szrj 	    {
2468*38fd1498Szrj 	      for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
2469*38fd1498Szrj 		{
2470*38fd1498Szrj 		  hash += (hash_rtx_cb (ASM_OPERANDS_INPUT (x, i),
2471*38fd1498Szrj                                         GET_MODE (ASM_OPERANDS_INPUT (x, i)),
2472*38fd1498Szrj                                         do_not_record_p, hash_arg_in_memory_p,
2473*38fd1498Szrj                                         have_reg_qty, cb)
2474*38fd1498Szrj 			   + hash_rtx_string
2475*38fd1498Szrj                            (ASM_OPERANDS_INPUT_CONSTRAINT (x, i)));
2476*38fd1498Szrj 		}
2477*38fd1498Szrj 
2478*38fd1498Szrj 	      hash += hash_rtx_string (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0));
2479*38fd1498Szrj 	      x = ASM_OPERANDS_INPUT (x, 0);
2480*38fd1498Szrj 	      mode = GET_MODE (x);
2481*38fd1498Szrj 	      goto repeat;
2482*38fd1498Szrj 	    }
2483*38fd1498Szrj 
2484*38fd1498Szrj 	  return hash;
2485*38fd1498Szrj 	}
2486*38fd1498Szrj       break;
2487*38fd1498Szrj 
2488*38fd1498Szrj     default:
2489*38fd1498Szrj       break;
2490*38fd1498Szrj     }
2491*38fd1498Szrj 
2492*38fd1498Szrj   i = GET_RTX_LENGTH (code) - 1;
2493*38fd1498Szrj   hash += (unsigned) code + (unsigned) GET_MODE (x);
2494*38fd1498Szrj   fmt = GET_RTX_FORMAT (code);
2495*38fd1498Szrj   for (; i >= 0; i--)
2496*38fd1498Szrj     {
2497*38fd1498Szrj       switch (fmt[i])
2498*38fd1498Szrj 	{
2499*38fd1498Szrj 	case 'e':
2500*38fd1498Szrj 	  /* If we are about to do the last recursive call
2501*38fd1498Szrj 	     needed at this level, change it into iteration.
2502*38fd1498Szrj 	     This function  is called enough to be worth it.  */
2503*38fd1498Szrj 	  if (i == 0)
2504*38fd1498Szrj 	    {
2505*38fd1498Szrj 	      x = XEXP (x, i);
2506*38fd1498Szrj 	      goto repeat;
2507*38fd1498Szrj 	    }
2508*38fd1498Szrj 
2509*38fd1498Szrj 	  hash += hash_rtx_cb (XEXP (x, i), VOIDmode, do_not_record_p,
2510*38fd1498Szrj                                hash_arg_in_memory_p,
2511*38fd1498Szrj                                have_reg_qty, cb);
2512*38fd1498Szrj 	  break;
2513*38fd1498Szrj 
2514*38fd1498Szrj 	case 'E':
2515*38fd1498Szrj 	  for (j = 0; j < XVECLEN (x, i); j++)
2516*38fd1498Szrj 	    hash += hash_rtx_cb (XVECEXP (x, i, j), VOIDmode, do_not_record_p,
2517*38fd1498Szrj                                  hash_arg_in_memory_p,
2518*38fd1498Szrj                                  have_reg_qty, cb);
2519*38fd1498Szrj 	  break;
2520*38fd1498Szrj 
2521*38fd1498Szrj 	case 's':
2522*38fd1498Szrj 	  hash += hash_rtx_string (XSTR (x, i));
2523*38fd1498Szrj 	  break;
2524*38fd1498Szrj 
2525*38fd1498Szrj 	case 'i':
2526*38fd1498Szrj 	  hash += (unsigned int) XINT (x, i);
2527*38fd1498Szrj 	  break;
2528*38fd1498Szrj 
2529*38fd1498Szrj 	case 'p':
2530*38fd1498Szrj 	  hash += constant_lower_bound (SUBREG_BYTE (x));
2531*38fd1498Szrj 	  break;
2532*38fd1498Szrj 
2533*38fd1498Szrj 	case '0': case 't':
2534*38fd1498Szrj 	  /* Unused.  */
2535*38fd1498Szrj 	  break;
2536*38fd1498Szrj 
2537*38fd1498Szrj 	default:
2538*38fd1498Szrj 	  gcc_unreachable ();
2539*38fd1498Szrj 	}
2540*38fd1498Szrj     }
2541*38fd1498Szrj 
2542*38fd1498Szrj   return hash;
2543*38fd1498Szrj }
2544*38fd1498Szrj 
2545*38fd1498Szrj /* Hash an rtx.  We are careful to make sure the value is never negative.
2546*38fd1498Szrj    Equivalent registers hash identically.
2547*38fd1498Szrj    MODE is used in hashing for CONST_INTs only;
2548*38fd1498Szrj    otherwise the mode of X is used.
2549*38fd1498Szrj 
2550*38fd1498Szrj    Store 1 in DO_NOT_RECORD_P if any subexpression is volatile.
2551*38fd1498Szrj 
2552*38fd1498Szrj    If HASH_ARG_IN_MEMORY_P is not NULL, store 1 in it if X contains
2553*38fd1498Szrj    a MEM rtx which does not have the MEM_READONLY_P flag set.
2554*38fd1498Szrj 
2555*38fd1498Szrj    Note that cse_insn knows that the hash code of a MEM expression
2556*38fd1498Szrj    is just (int) MEM plus the hash code of the address.  */
2557*38fd1498Szrj 
2558*38fd1498Szrj unsigned
hash_rtx(const_rtx x,machine_mode mode,int * do_not_record_p,int * hash_arg_in_memory_p,bool have_reg_qty)2559*38fd1498Szrj hash_rtx (const_rtx x, machine_mode mode, int *do_not_record_p,
2560*38fd1498Szrj 	  int *hash_arg_in_memory_p, bool have_reg_qty)
2561*38fd1498Szrj {
2562*38fd1498Szrj   return hash_rtx_cb (x, mode, do_not_record_p,
2563*38fd1498Szrj                       hash_arg_in_memory_p, have_reg_qty, NULL);
2564*38fd1498Szrj }
2565*38fd1498Szrj 
2566*38fd1498Szrj /* Hash an rtx X for cse via hash_rtx.
2567*38fd1498Szrj    Stores 1 in do_not_record if any subexpression is volatile.
2568*38fd1498Szrj    Stores 1 in hash_arg_in_memory if X contains a mem rtx which
2569*38fd1498Szrj    does not have the MEM_READONLY_P flag set.  */
2570*38fd1498Szrj 
2571*38fd1498Szrj static inline unsigned
canon_hash(rtx x,machine_mode mode)2572*38fd1498Szrj canon_hash (rtx x, machine_mode mode)
2573*38fd1498Szrj {
2574*38fd1498Szrj   return hash_rtx (x, mode, &do_not_record, &hash_arg_in_memory, true);
2575*38fd1498Szrj }
2576*38fd1498Szrj 
2577*38fd1498Szrj /* Like canon_hash but with no side effects, i.e. do_not_record
2578*38fd1498Szrj    and hash_arg_in_memory are not changed.  */
2579*38fd1498Szrj 
2580*38fd1498Szrj static inline unsigned
safe_hash(rtx x,machine_mode mode)2581*38fd1498Szrj safe_hash (rtx x, machine_mode mode)
2582*38fd1498Szrj {
2583*38fd1498Szrj   int dummy_do_not_record;
2584*38fd1498Szrj   return hash_rtx (x, mode, &dummy_do_not_record, NULL, true);
2585*38fd1498Szrj }
2586*38fd1498Szrj 
2587*38fd1498Szrj /* Return 1 iff X and Y would canonicalize into the same thing,
2588*38fd1498Szrj    without actually constructing the canonicalization of either one.
2589*38fd1498Szrj    If VALIDATE is nonzero,
2590*38fd1498Szrj    we assume X is an expression being processed from the rtl
2591*38fd1498Szrj    and Y was found in the hash table.  We check register refs
2592*38fd1498Szrj    in Y for being marked as valid.
2593*38fd1498Szrj 
2594*38fd1498Szrj    If FOR_GCSE is true, we compare X and Y for equivalence for GCSE.  */
2595*38fd1498Szrj 
2596*38fd1498Szrj int
exp_equiv_p(const_rtx x,const_rtx y,int validate,bool for_gcse)2597*38fd1498Szrj exp_equiv_p (const_rtx x, const_rtx y, int validate, bool for_gcse)
2598*38fd1498Szrj {
2599*38fd1498Szrj   int i, j;
2600*38fd1498Szrj   enum rtx_code code;
2601*38fd1498Szrj   const char *fmt;
2602*38fd1498Szrj 
2603*38fd1498Szrj   /* Note: it is incorrect to assume an expression is equivalent to itself
2604*38fd1498Szrj      if VALIDATE is nonzero.  */
2605*38fd1498Szrj   if (x == y && !validate)
2606*38fd1498Szrj     return 1;
2607*38fd1498Szrj 
2608*38fd1498Szrj   if (x == 0 || y == 0)
2609*38fd1498Szrj     return x == y;
2610*38fd1498Szrj 
2611*38fd1498Szrj   code = GET_CODE (x);
2612*38fd1498Szrj   if (code != GET_CODE (y))
2613*38fd1498Szrj     return 0;
2614*38fd1498Szrj 
2615*38fd1498Szrj   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
2616*38fd1498Szrj   if (GET_MODE (x) != GET_MODE (y))
2617*38fd1498Szrj     return 0;
2618*38fd1498Szrj 
2619*38fd1498Szrj   /* MEMs referring to different address space are not equivalent.  */
2620*38fd1498Szrj   if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
2621*38fd1498Szrj     return 0;
2622*38fd1498Szrj 
2623*38fd1498Szrj   switch (code)
2624*38fd1498Szrj     {
2625*38fd1498Szrj     case PC:
2626*38fd1498Szrj     case CC0:
2627*38fd1498Szrj     CASE_CONST_UNIQUE:
2628*38fd1498Szrj       return x == y;
2629*38fd1498Szrj 
2630*38fd1498Szrj     case LABEL_REF:
2631*38fd1498Szrj       return label_ref_label (x) == label_ref_label (y);
2632*38fd1498Szrj 
2633*38fd1498Szrj     case SYMBOL_REF:
2634*38fd1498Szrj       return XSTR (x, 0) == XSTR (y, 0);
2635*38fd1498Szrj 
2636*38fd1498Szrj     case REG:
2637*38fd1498Szrj       if (for_gcse)
2638*38fd1498Szrj 	return REGNO (x) == REGNO (y);
2639*38fd1498Szrj       else
2640*38fd1498Szrj 	{
2641*38fd1498Szrj 	  unsigned int regno = REGNO (y);
2642*38fd1498Szrj 	  unsigned int i;
2643*38fd1498Szrj 	  unsigned int endregno = END_REGNO (y);
2644*38fd1498Szrj 
2645*38fd1498Szrj 	  /* If the quantities are not the same, the expressions are not
2646*38fd1498Szrj 	     equivalent.  If there are and we are not to validate, they
2647*38fd1498Szrj 	     are equivalent.  Otherwise, ensure all regs are up-to-date.  */
2648*38fd1498Szrj 
2649*38fd1498Szrj 	  if (REG_QTY (REGNO (x)) != REG_QTY (regno))
2650*38fd1498Szrj 	    return 0;
2651*38fd1498Szrj 
2652*38fd1498Szrj 	  if (! validate)
2653*38fd1498Szrj 	    return 1;
2654*38fd1498Szrj 
2655*38fd1498Szrj 	  for (i = regno; i < endregno; i++)
2656*38fd1498Szrj 	    if (REG_IN_TABLE (i) != REG_TICK (i))
2657*38fd1498Szrj 	      return 0;
2658*38fd1498Szrj 
2659*38fd1498Szrj 	  return 1;
2660*38fd1498Szrj 	}
2661*38fd1498Szrj 
2662*38fd1498Szrj     case MEM:
2663*38fd1498Szrj       if (for_gcse)
2664*38fd1498Szrj 	{
2665*38fd1498Szrj 	  /* A volatile mem should not be considered equivalent to any
2666*38fd1498Szrj 	     other.  */
2667*38fd1498Szrj 	  if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
2668*38fd1498Szrj 	    return 0;
2669*38fd1498Szrj 
2670*38fd1498Szrj 	  /* Can't merge two expressions in different alias sets, since we
2671*38fd1498Szrj 	     can decide that the expression is transparent in a block when
2672*38fd1498Szrj 	     it isn't, due to it being set with the different alias set.
2673*38fd1498Szrj 
2674*38fd1498Szrj 	     Also, can't merge two expressions with different MEM_ATTRS.
2675*38fd1498Szrj 	     They could e.g. be two different entities allocated into the
2676*38fd1498Szrj 	     same space on the stack (see e.g. PR25130).  In that case, the
2677*38fd1498Szrj 	     MEM addresses can be the same, even though the two MEMs are
2678*38fd1498Szrj 	     absolutely not equivalent.
2679*38fd1498Szrj 
2680*38fd1498Szrj 	     But because really all MEM attributes should be the same for
2681*38fd1498Szrj 	     equivalent MEMs, we just use the invariant that MEMs that have
2682*38fd1498Szrj 	     the same attributes share the same mem_attrs data structure.  */
2683*38fd1498Szrj 	  if (!mem_attrs_eq_p (MEM_ATTRS (x), MEM_ATTRS (y)))
2684*38fd1498Szrj 	    return 0;
2685*38fd1498Szrj 
2686*38fd1498Szrj 	  /* If we are handling exceptions, we cannot consider two expressions
2687*38fd1498Szrj 	     with different trapping status as equivalent, because simple_mem
2688*38fd1498Szrj 	     might accept one and reject the other.  */
2689*38fd1498Szrj 	  if (cfun->can_throw_non_call_exceptions
2690*38fd1498Szrj 	      && (MEM_NOTRAP_P (x) != MEM_NOTRAP_P (y)))
2691*38fd1498Szrj 	    return 0;
2692*38fd1498Szrj 	}
2693*38fd1498Szrj       break;
2694*38fd1498Szrj 
2695*38fd1498Szrj     /*  For commutative operations, check both orders.  */
2696*38fd1498Szrj     case PLUS:
2697*38fd1498Szrj     case MULT:
2698*38fd1498Szrj     case AND:
2699*38fd1498Szrj     case IOR:
2700*38fd1498Szrj     case XOR:
2701*38fd1498Szrj     case NE:
2702*38fd1498Szrj     case EQ:
2703*38fd1498Szrj       return ((exp_equiv_p (XEXP (x, 0), XEXP (y, 0),
2704*38fd1498Szrj 			     validate, for_gcse)
2705*38fd1498Szrj 	       && exp_equiv_p (XEXP (x, 1), XEXP (y, 1),
2706*38fd1498Szrj 				validate, for_gcse))
2707*38fd1498Szrj 	      || (exp_equiv_p (XEXP (x, 0), XEXP (y, 1),
2708*38fd1498Szrj 				validate, for_gcse)
2709*38fd1498Szrj 		  && exp_equiv_p (XEXP (x, 1), XEXP (y, 0),
2710*38fd1498Szrj 				   validate, for_gcse)));
2711*38fd1498Szrj 
2712*38fd1498Szrj     case ASM_OPERANDS:
2713*38fd1498Szrj       /* We don't use the generic code below because we want to
2714*38fd1498Szrj 	 disregard filename and line numbers.  */
2715*38fd1498Szrj 
2716*38fd1498Szrj       /* A volatile asm isn't equivalent to any other.  */
2717*38fd1498Szrj       if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
2718*38fd1498Szrj 	return 0;
2719*38fd1498Szrj 
2720*38fd1498Szrj       if (GET_MODE (x) != GET_MODE (y)
2721*38fd1498Szrj 	  || strcmp (ASM_OPERANDS_TEMPLATE (x), ASM_OPERANDS_TEMPLATE (y))
2722*38fd1498Szrj 	  || strcmp (ASM_OPERANDS_OUTPUT_CONSTRAINT (x),
2723*38fd1498Szrj 		     ASM_OPERANDS_OUTPUT_CONSTRAINT (y))
2724*38fd1498Szrj 	  || ASM_OPERANDS_OUTPUT_IDX (x) != ASM_OPERANDS_OUTPUT_IDX (y)
2725*38fd1498Szrj 	  || ASM_OPERANDS_INPUT_LENGTH (x) != ASM_OPERANDS_INPUT_LENGTH (y))
2726*38fd1498Szrj 	return 0;
2727*38fd1498Szrj 
2728*38fd1498Szrj       if (ASM_OPERANDS_INPUT_LENGTH (x))
2729*38fd1498Szrj 	{
2730*38fd1498Szrj 	  for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
2731*38fd1498Szrj 	    if (! exp_equiv_p (ASM_OPERANDS_INPUT (x, i),
2732*38fd1498Szrj 			       ASM_OPERANDS_INPUT (y, i),
2733*38fd1498Szrj 			       validate, for_gcse)
2734*38fd1498Szrj 		|| strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i),
2735*38fd1498Szrj 			   ASM_OPERANDS_INPUT_CONSTRAINT (y, i)))
2736*38fd1498Szrj 	      return 0;
2737*38fd1498Szrj 	}
2738*38fd1498Szrj 
2739*38fd1498Szrj       return 1;
2740*38fd1498Szrj 
2741*38fd1498Szrj     default:
2742*38fd1498Szrj       break;
2743*38fd1498Szrj     }
2744*38fd1498Szrj 
2745*38fd1498Szrj   /* Compare the elements.  If any pair of corresponding elements
2746*38fd1498Szrj      fail to match, return 0 for the whole thing.  */
2747*38fd1498Szrj 
2748*38fd1498Szrj   fmt = GET_RTX_FORMAT (code);
2749*38fd1498Szrj   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2750*38fd1498Szrj     {
2751*38fd1498Szrj       switch (fmt[i])
2752*38fd1498Szrj 	{
2753*38fd1498Szrj 	case 'e':
2754*38fd1498Szrj 	  if (! exp_equiv_p (XEXP (x, i), XEXP (y, i),
2755*38fd1498Szrj 			      validate, for_gcse))
2756*38fd1498Szrj 	    return 0;
2757*38fd1498Szrj 	  break;
2758*38fd1498Szrj 
2759*38fd1498Szrj 	case 'E':
2760*38fd1498Szrj 	  if (XVECLEN (x, i) != XVECLEN (y, i))
2761*38fd1498Szrj 	    return 0;
2762*38fd1498Szrj 	  for (j = 0; j < XVECLEN (x, i); j++)
2763*38fd1498Szrj 	    if (! exp_equiv_p (XVECEXP (x, i, j), XVECEXP (y, i, j),
2764*38fd1498Szrj 				validate, for_gcse))
2765*38fd1498Szrj 	      return 0;
2766*38fd1498Szrj 	  break;
2767*38fd1498Szrj 
2768*38fd1498Szrj 	case 's':
2769*38fd1498Szrj 	  if (strcmp (XSTR (x, i), XSTR (y, i)))
2770*38fd1498Szrj 	    return 0;
2771*38fd1498Szrj 	  break;
2772*38fd1498Szrj 
2773*38fd1498Szrj 	case 'i':
2774*38fd1498Szrj 	  if (XINT (x, i) != XINT (y, i))
2775*38fd1498Szrj 	    return 0;
2776*38fd1498Szrj 	  break;
2777*38fd1498Szrj 
2778*38fd1498Szrj 	case 'w':
2779*38fd1498Szrj 	  if (XWINT (x, i) != XWINT (y, i))
2780*38fd1498Szrj 	    return 0;
2781*38fd1498Szrj 	  break;
2782*38fd1498Szrj 
2783*38fd1498Szrj 	case 'p':
2784*38fd1498Szrj 	  if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
2785*38fd1498Szrj 	    return 0;
2786*38fd1498Szrj 	  break;
2787*38fd1498Szrj 
2788*38fd1498Szrj 	case '0':
2789*38fd1498Szrj 	case 't':
2790*38fd1498Szrj 	  break;
2791*38fd1498Szrj 
2792*38fd1498Szrj 	default:
2793*38fd1498Szrj 	  gcc_unreachable ();
2794*38fd1498Szrj 	}
2795*38fd1498Szrj     }
2796*38fd1498Szrj 
2797*38fd1498Szrj   return 1;
2798*38fd1498Szrj }
2799*38fd1498Szrj 
2800*38fd1498Szrj /* Subroutine of canon_reg.  Pass *XLOC through canon_reg, and validate
2801*38fd1498Szrj    the result if necessary.  INSN is as for canon_reg.  */
2802*38fd1498Szrj 
2803*38fd1498Szrj static void
validate_canon_reg(rtx * xloc,rtx_insn * insn)2804*38fd1498Szrj validate_canon_reg (rtx *xloc, rtx_insn *insn)
2805*38fd1498Szrj {
2806*38fd1498Szrj   if (*xloc)
2807*38fd1498Szrj     {
2808*38fd1498Szrj       rtx new_rtx = canon_reg (*xloc, insn);
2809*38fd1498Szrj 
2810*38fd1498Szrj       /* If replacing pseudo with hard reg or vice versa, ensure the
2811*38fd1498Szrj          insn remains valid.  Likewise if the insn has MATCH_DUPs.  */
2812*38fd1498Szrj       gcc_assert (insn && new_rtx);
2813*38fd1498Szrj       validate_change (insn, xloc, new_rtx, 1);
2814*38fd1498Szrj     }
2815*38fd1498Szrj }
2816*38fd1498Szrj 
2817*38fd1498Szrj /* Canonicalize an expression:
2818*38fd1498Szrj    replace each register reference inside it
2819*38fd1498Szrj    with the "oldest" equivalent register.
2820*38fd1498Szrj 
2821*38fd1498Szrj    If INSN is nonzero validate_change is used to ensure that INSN remains valid
2822*38fd1498Szrj    after we make our substitution.  The calls are made with IN_GROUP nonzero
2823*38fd1498Szrj    so apply_change_group must be called upon the outermost return from this
2824*38fd1498Szrj    function (unless INSN is zero).  The result of apply_change_group can
2825*38fd1498Szrj    generally be discarded since the changes we are making are optional.  */
2826*38fd1498Szrj 
2827*38fd1498Szrj static rtx
canon_reg(rtx x,rtx_insn * insn)2828*38fd1498Szrj canon_reg (rtx x, rtx_insn *insn)
2829*38fd1498Szrj {
2830*38fd1498Szrj   int i;
2831*38fd1498Szrj   enum rtx_code code;
2832*38fd1498Szrj   const char *fmt;
2833*38fd1498Szrj 
2834*38fd1498Szrj   if (x == 0)
2835*38fd1498Szrj     return x;
2836*38fd1498Szrj 
2837*38fd1498Szrj   code = GET_CODE (x);
2838*38fd1498Szrj   switch (code)
2839*38fd1498Szrj     {
2840*38fd1498Szrj     case PC:
2841*38fd1498Szrj     case CC0:
2842*38fd1498Szrj     case CONST:
2843*38fd1498Szrj     CASE_CONST_ANY:
2844*38fd1498Szrj     case SYMBOL_REF:
2845*38fd1498Szrj     case LABEL_REF:
2846*38fd1498Szrj     case ADDR_VEC:
2847*38fd1498Szrj     case ADDR_DIFF_VEC:
2848*38fd1498Szrj       return x;
2849*38fd1498Szrj 
2850*38fd1498Szrj     case REG:
2851*38fd1498Szrj       {
2852*38fd1498Szrj 	int first;
2853*38fd1498Szrj 	int q;
2854*38fd1498Szrj 	struct qty_table_elem *ent;
2855*38fd1498Szrj 
2856*38fd1498Szrj 	/* Never replace a hard reg, because hard regs can appear
2857*38fd1498Szrj 	   in more than one machine mode, and we must preserve the mode
2858*38fd1498Szrj 	   of each occurrence.  Also, some hard regs appear in
2859*38fd1498Szrj 	   MEMs that are shared and mustn't be altered.  Don't try to
2860*38fd1498Szrj 	   replace any reg that maps to a reg of class NO_REGS.  */
2861*38fd1498Szrj 	if (REGNO (x) < FIRST_PSEUDO_REGISTER
2862*38fd1498Szrj 	    || ! REGNO_QTY_VALID_P (REGNO (x)))
2863*38fd1498Szrj 	  return x;
2864*38fd1498Szrj 
2865*38fd1498Szrj 	q = REG_QTY (REGNO (x));
2866*38fd1498Szrj 	ent = &qty_table[q];
2867*38fd1498Szrj 	first = ent->first_reg;
2868*38fd1498Szrj 	return (first >= FIRST_PSEUDO_REGISTER ? regno_reg_rtx[first]
2869*38fd1498Szrj 		: REGNO_REG_CLASS (first) == NO_REGS ? x
2870*38fd1498Szrj 		: gen_rtx_REG (ent->mode, first));
2871*38fd1498Szrj       }
2872*38fd1498Szrj 
2873*38fd1498Szrj     default:
2874*38fd1498Szrj       break;
2875*38fd1498Szrj     }
2876*38fd1498Szrj 
2877*38fd1498Szrj   fmt = GET_RTX_FORMAT (code);
2878*38fd1498Szrj   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2879*38fd1498Szrj     {
2880*38fd1498Szrj       int j;
2881*38fd1498Szrj 
2882*38fd1498Szrj       if (fmt[i] == 'e')
2883*38fd1498Szrj 	validate_canon_reg (&XEXP (x, i), insn);
2884*38fd1498Szrj       else if (fmt[i] == 'E')
2885*38fd1498Szrj 	for (j = 0; j < XVECLEN (x, i); j++)
2886*38fd1498Szrj 	  validate_canon_reg (&XVECEXP (x, i, j), insn);
2887*38fd1498Szrj     }
2888*38fd1498Szrj 
2889*38fd1498Szrj   return x;
2890*38fd1498Szrj }
2891*38fd1498Szrj 
2892*38fd1498Szrj /* Given an operation (CODE, *PARG1, *PARG2), where code is a comparison
2893*38fd1498Szrj    operation (EQ, NE, GT, etc.), follow it back through the hash table and
2894*38fd1498Szrj    what values are being compared.
2895*38fd1498Szrj 
2896*38fd1498Szrj    *PARG1 and *PARG2 are updated to contain the rtx representing the values
2897*38fd1498Szrj    actually being compared.  For example, if *PARG1 was (cc0) and *PARG2
2898*38fd1498Szrj    was (const_int 0), *PARG1 and *PARG2 will be set to the objects that were
2899*38fd1498Szrj    compared to produce cc0.
2900*38fd1498Szrj 
2901*38fd1498Szrj    The return value is the comparison operator and is either the code of
2902*38fd1498Szrj    A or the code corresponding to the inverse of the comparison.  */
2903*38fd1498Szrj 
2904*38fd1498Szrj static enum rtx_code
find_comparison_args(enum rtx_code code,rtx * parg1,rtx * parg2,machine_mode * pmode1,machine_mode * pmode2)2905*38fd1498Szrj find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
2906*38fd1498Szrj 		      machine_mode *pmode1, machine_mode *pmode2)
2907*38fd1498Szrj {
2908*38fd1498Szrj   rtx arg1, arg2;
2909*38fd1498Szrj   hash_set<rtx> *visited = NULL;
2910*38fd1498Szrj   /* Set nonzero when we find something of interest.  */
2911*38fd1498Szrj   rtx x = NULL;
2912*38fd1498Szrj 
2913*38fd1498Szrj   arg1 = *parg1, arg2 = *parg2;
2914*38fd1498Szrj 
2915*38fd1498Szrj   /* If ARG2 is const0_rtx, see what ARG1 is equivalent to.  */
2916*38fd1498Szrj 
2917*38fd1498Szrj   while (arg2 == CONST0_RTX (GET_MODE (arg1)))
2918*38fd1498Szrj     {
2919*38fd1498Szrj       int reverse_code = 0;
2920*38fd1498Szrj       struct table_elt *p = 0;
2921*38fd1498Szrj 
2922*38fd1498Szrj       /* Remember state from previous iteration.  */
2923*38fd1498Szrj       if (x)
2924*38fd1498Szrj 	{
2925*38fd1498Szrj 	  if (!visited)
2926*38fd1498Szrj 	    visited = new hash_set<rtx>;
2927*38fd1498Szrj 	  visited->add (x);
2928*38fd1498Szrj 	  x = 0;
2929*38fd1498Szrj 	}
2930*38fd1498Szrj 
2931*38fd1498Szrj       /* If arg1 is a COMPARE, extract the comparison arguments from it.
2932*38fd1498Szrj 	 On machines with CC0, this is the only case that can occur, since
2933*38fd1498Szrj 	 fold_rtx will return the COMPARE or item being compared with zero
2934*38fd1498Szrj 	 when given CC0.  */
2935*38fd1498Szrj 
2936*38fd1498Szrj       if (GET_CODE (arg1) == COMPARE && arg2 == const0_rtx)
2937*38fd1498Szrj 	x = arg1;
2938*38fd1498Szrj 
2939*38fd1498Szrj       /* If ARG1 is a comparison operator and CODE is testing for
2940*38fd1498Szrj 	 STORE_FLAG_VALUE, get the inner arguments.  */
2941*38fd1498Szrj 
2942*38fd1498Szrj       else if (COMPARISON_P (arg1))
2943*38fd1498Szrj 	{
2944*38fd1498Szrj #ifdef FLOAT_STORE_FLAG_VALUE
2945*38fd1498Szrj 	  REAL_VALUE_TYPE fsfv;
2946*38fd1498Szrj #endif
2947*38fd1498Szrj 
2948*38fd1498Szrj 	  if (code == NE
2949*38fd1498Szrj 	      || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_INT
2950*38fd1498Szrj 		  && code == LT && STORE_FLAG_VALUE == -1)
2951*38fd1498Szrj #ifdef FLOAT_STORE_FLAG_VALUE
2952*38fd1498Szrj 	      || (SCALAR_FLOAT_MODE_P (GET_MODE (arg1))
2953*38fd1498Szrj 		  && (fsfv = FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)),
2954*38fd1498Szrj 		      REAL_VALUE_NEGATIVE (fsfv)))
2955*38fd1498Szrj #endif
2956*38fd1498Szrj 	      )
2957*38fd1498Szrj 	    x = arg1;
2958*38fd1498Szrj 	  else if (code == EQ
2959*38fd1498Szrj 		   || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_INT
2960*38fd1498Szrj 		       && code == GE && STORE_FLAG_VALUE == -1)
2961*38fd1498Szrj #ifdef FLOAT_STORE_FLAG_VALUE
2962*38fd1498Szrj 		   || (SCALAR_FLOAT_MODE_P (GET_MODE (arg1))
2963*38fd1498Szrj 		       && (fsfv = FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)),
2964*38fd1498Szrj 			   REAL_VALUE_NEGATIVE (fsfv)))
2965*38fd1498Szrj #endif
2966*38fd1498Szrj 		   )
2967*38fd1498Szrj 	    x = arg1, reverse_code = 1;
2968*38fd1498Szrj 	}
2969*38fd1498Szrj 
2970*38fd1498Szrj       /* ??? We could also check for
2971*38fd1498Szrj 
2972*38fd1498Szrj 	 (ne (and (eq (...) (const_int 1))) (const_int 0))
2973*38fd1498Szrj 
2974*38fd1498Szrj 	 and related forms, but let's wait until we see them occurring.  */
2975*38fd1498Szrj 
2976*38fd1498Szrj       if (x == 0)
2977*38fd1498Szrj 	/* Look up ARG1 in the hash table and see if it has an equivalence
2978*38fd1498Szrj 	   that lets us see what is being compared.  */
2979*38fd1498Szrj 	p = lookup (arg1, SAFE_HASH (arg1, GET_MODE (arg1)), GET_MODE (arg1));
2980*38fd1498Szrj       if (p)
2981*38fd1498Szrj 	{
2982*38fd1498Szrj 	  p = p->first_same_value;
2983*38fd1498Szrj 
2984*38fd1498Szrj 	  /* If what we compare is already known to be constant, that is as
2985*38fd1498Szrj 	     good as it gets.
2986*38fd1498Szrj 	     We need to break the loop in this case, because otherwise we
2987*38fd1498Szrj 	     can have an infinite loop when looking at a reg that is known
2988*38fd1498Szrj 	     to be a constant which is the same as a comparison of a reg
2989*38fd1498Szrj 	     against zero which appears later in the insn stream, which in
2990*38fd1498Szrj 	     turn is constant and the same as the comparison of the first reg
2991*38fd1498Szrj 	     against zero...  */
2992*38fd1498Szrj 	  if (p->is_const)
2993*38fd1498Szrj 	    break;
2994*38fd1498Szrj 	}
2995*38fd1498Szrj 
2996*38fd1498Szrj       for (; p; p = p->next_same_value)
2997*38fd1498Szrj 	{
2998*38fd1498Szrj 	  machine_mode inner_mode = GET_MODE (p->exp);
2999*38fd1498Szrj #ifdef FLOAT_STORE_FLAG_VALUE
3000*38fd1498Szrj 	  REAL_VALUE_TYPE fsfv;
3001*38fd1498Szrj #endif
3002*38fd1498Szrj 
3003*38fd1498Szrj 	  /* If the entry isn't valid, skip it.  */
3004*38fd1498Szrj 	  if (! exp_equiv_p (p->exp, p->exp, 1, false))
3005*38fd1498Szrj 	    continue;
3006*38fd1498Szrj 
3007*38fd1498Szrj 	  /* If it's a comparison we've used before, skip it.  */
3008*38fd1498Szrj 	  if (visited && visited->contains (p->exp))
3009*38fd1498Szrj 	    continue;
3010*38fd1498Szrj 
3011*38fd1498Szrj 	  if (GET_CODE (p->exp) == COMPARE
3012*38fd1498Szrj 	      /* Another possibility is that this machine has a compare insn
3013*38fd1498Szrj 		 that includes the comparison code.  In that case, ARG1 would
3014*38fd1498Szrj 		 be equivalent to a comparison operation that would set ARG1 to
3015*38fd1498Szrj 		 either STORE_FLAG_VALUE or zero.  If this is an NE operation,
3016*38fd1498Szrj 		 ORIG_CODE is the actual comparison being done; if it is an EQ,
3017*38fd1498Szrj 		 we must reverse ORIG_CODE.  On machine with a negative value
3018*38fd1498Szrj 		 for STORE_FLAG_VALUE, also look at LT and GE operations.  */
3019*38fd1498Szrj 	      || ((code == NE
3020*38fd1498Szrj 		   || (code == LT
3021*38fd1498Szrj 		       && val_signbit_known_set_p (inner_mode,
3022*38fd1498Szrj 						   STORE_FLAG_VALUE))
3023*38fd1498Szrj #ifdef FLOAT_STORE_FLAG_VALUE
3024*38fd1498Szrj 		   || (code == LT
3025*38fd1498Szrj 		       && SCALAR_FLOAT_MODE_P (inner_mode)
3026*38fd1498Szrj 		       && (fsfv = FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)),
3027*38fd1498Szrj 			   REAL_VALUE_NEGATIVE (fsfv)))
3028*38fd1498Szrj #endif
3029*38fd1498Szrj 		   )
3030*38fd1498Szrj 		  && COMPARISON_P (p->exp)))
3031*38fd1498Szrj 	    {
3032*38fd1498Szrj 	      x = p->exp;
3033*38fd1498Szrj 	      break;
3034*38fd1498Szrj 	    }
3035*38fd1498Szrj 	  else if ((code == EQ
3036*38fd1498Szrj 		    || (code == GE
3037*38fd1498Szrj 			&& val_signbit_known_set_p (inner_mode,
3038*38fd1498Szrj 						    STORE_FLAG_VALUE))
3039*38fd1498Szrj #ifdef FLOAT_STORE_FLAG_VALUE
3040*38fd1498Szrj 		    || (code == GE
3041*38fd1498Szrj 			&& SCALAR_FLOAT_MODE_P (inner_mode)
3042*38fd1498Szrj 			&& (fsfv = FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)),
3043*38fd1498Szrj 			    REAL_VALUE_NEGATIVE (fsfv)))
3044*38fd1498Szrj #endif
3045*38fd1498Szrj 		    )
3046*38fd1498Szrj 		   && COMPARISON_P (p->exp))
3047*38fd1498Szrj 	    {
3048*38fd1498Szrj 	      reverse_code = 1;
3049*38fd1498Szrj 	      x = p->exp;
3050*38fd1498Szrj 	      break;
3051*38fd1498Szrj 	    }
3052*38fd1498Szrj 
3053*38fd1498Szrj 	  /* If this non-trapping address, e.g. fp + constant, the
3054*38fd1498Szrj 	     equivalent is a better operand since it may let us predict
3055*38fd1498Szrj 	     the value of the comparison.  */
3056*38fd1498Szrj 	  else if (!rtx_addr_can_trap_p (p->exp))
3057*38fd1498Szrj 	    {
3058*38fd1498Szrj 	      arg1 = p->exp;
3059*38fd1498Szrj 	      continue;
3060*38fd1498Szrj 	    }
3061*38fd1498Szrj 	}
3062*38fd1498Szrj 
3063*38fd1498Szrj       /* If we didn't find a useful equivalence for ARG1, we are done.
3064*38fd1498Szrj 	 Otherwise, set up for the next iteration.  */
3065*38fd1498Szrj       if (x == 0)
3066*38fd1498Szrj 	break;
3067*38fd1498Szrj 
3068*38fd1498Szrj       /* If we need to reverse the comparison, make sure that is
3069*38fd1498Szrj 	 possible -- we can't necessarily infer the value of GE from LT
3070*38fd1498Szrj 	 with floating-point operands.  */
3071*38fd1498Szrj       if (reverse_code)
3072*38fd1498Szrj 	{
3073*38fd1498Szrj 	  enum rtx_code reversed = reversed_comparison_code (x, NULL);
3074*38fd1498Szrj 	  if (reversed == UNKNOWN)
3075*38fd1498Szrj 	    break;
3076*38fd1498Szrj 	  else
3077*38fd1498Szrj 	    code = reversed;
3078*38fd1498Szrj 	}
3079*38fd1498Szrj       else if (COMPARISON_P (x))
3080*38fd1498Szrj 	code = GET_CODE (x);
3081*38fd1498Szrj       arg1 = XEXP (x, 0), arg2 = XEXP (x, 1);
3082*38fd1498Szrj     }
3083*38fd1498Szrj 
3084*38fd1498Szrj   /* Return our results.  Return the modes from before fold_rtx
3085*38fd1498Szrj      because fold_rtx might produce const_int, and then it's too late.  */
3086*38fd1498Szrj   *pmode1 = GET_MODE (arg1), *pmode2 = GET_MODE (arg2);
3087*38fd1498Szrj   *parg1 = fold_rtx (arg1, 0), *parg2 = fold_rtx (arg2, 0);
3088*38fd1498Szrj 
3089*38fd1498Szrj   if (visited)
3090*38fd1498Szrj     delete visited;
3091*38fd1498Szrj   return code;
3092*38fd1498Szrj }
3093*38fd1498Szrj 
3094*38fd1498Szrj /* If X is a nontrivial arithmetic operation on an argument for which
3095*38fd1498Szrj    a constant value can be determined, return the result of operating
3096*38fd1498Szrj    on that value, as a constant.  Otherwise, return X, possibly with
3097*38fd1498Szrj    one or more operands changed to a forward-propagated constant.
3098*38fd1498Szrj 
3099*38fd1498Szrj    If X is a register whose contents are known, we do NOT return
3100*38fd1498Szrj    those contents here; equiv_constant is called to perform that task.
3101*38fd1498Szrj    For SUBREGs and MEMs, we do that both here and in equiv_constant.
3102*38fd1498Szrj 
3103*38fd1498Szrj    INSN is the insn that we may be modifying.  If it is 0, make a copy
3104*38fd1498Szrj    of X before modifying it.  */
3105*38fd1498Szrj 
3106*38fd1498Szrj static rtx
fold_rtx(rtx x,rtx_insn * insn)3107*38fd1498Szrj fold_rtx (rtx x, rtx_insn *insn)
3108*38fd1498Szrj {
3109*38fd1498Szrj   enum rtx_code code;
3110*38fd1498Szrj   machine_mode mode;
3111*38fd1498Szrj   const char *fmt;
3112*38fd1498Szrj   int i;
3113*38fd1498Szrj   rtx new_rtx = 0;
3114*38fd1498Szrj   int changed = 0;
3115*38fd1498Szrj 
3116*38fd1498Szrj   /* Operands of X.  */
3117*38fd1498Szrj   /* Workaround -Wmaybe-uninitialized false positive during
3118*38fd1498Szrj      profiledbootstrap by initializing them.  */
3119*38fd1498Szrj   rtx folded_arg0 = NULL_RTX;
3120*38fd1498Szrj   rtx folded_arg1 = NULL_RTX;
3121*38fd1498Szrj 
3122*38fd1498Szrj   /* Constant equivalents of first three operands of X;
3123*38fd1498Szrj      0 when no such equivalent is known.  */
3124*38fd1498Szrj   rtx const_arg0;
3125*38fd1498Szrj   rtx const_arg1;
3126*38fd1498Szrj   rtx const_arg2;
3127*38fd1498Szrj 
3128*38fd1498Szrj   /* The mode of the first operand of X.  We need this for sign and zero
3129*38fd1498Szrj      extends.  */
3130*38fd1498Szrj   machine_mode mode_arg0;
3131*38fd1498Szrj 
3132*38fd1498Szrj   if (x == 0)
3133*38fd1498Szrj     return x;
3134*38fd1498Szrj 
3135*38fd1498Szrj   /* Try to perform some initial simplifications on X.  */
3136*38fd1498Szrj   code = GET_CODE (x);
3137*38fd1498Szrj   switch (code)
3138*38fd1498Szrj     {
3139*38fd1498Szrj     case MEM:
3140*38fd1498Szrj     case SUBREG:
3141*38fd1498Szrj     /* The first operand of a SIGN/ZERO_EXTRACT has a different meaning
3142*38fd1498Szrj        than it would in other contexts.  Basically its mode does not
3143*38fd1498Szrj        signify the size of the object read.  That information is carried
3144*38fd1498Szrj        by size operand.    If we happen to have a MEM of the appropriate
3145*38fd1498Szrj        mode in our tables with a constant value we could simplify the
3146*38fd1498Szrj        extraction incorrectly if we allowed substitution of that value
3147*38fd1498Szrj        for the MEM.   */
3148*38fd1498Szrj     case ZERO_EXTRACT:
3149*38fd1498Szrj     case SIGN_EXTRACT:
3150*38fd1498Szrj       if ((new_rtx = equiv_constant (x)) != NULL_RTX)
3151*38fd1498Szrj         return new_rtx;
3152*38fd1498Szrj       return x;
3153*38fd1498Szrj 
3154*38fd1498Szrj     case CONST:
3155*38fd1498Szrj     CASE_CONST_ANY:
3156*38fd1498Szrj     case SYMBOL_REF:
3157*38fd1498Szrj     case LABEL_REF:
3158*38fd1498Szrj     case REG:
3159*38fd1498Szrj     case PC:
3160*38fd1498Szrj       /* No use simplifying an EXPR_LIST
3161*38fd1498Szrj 	 since they are used only for lists of args
3162*38fd1498Szrj 	 in a function call's REG_EQUAL note.  */
3163*38fd1498Szrj     case EXPR_LIST:
3164*38fd1498Szrj       return x;
3165*38fd1498Szrj 
3166*38fd1498Szrj     case CC0:
3167*38fd1498Szrj       return prev_insn_cc0;
3168*38fd1498Szrj 
3169*38fd1498Szrj     case ASM_OPERANDS:
3170*38fd1498Szrj       if (insn)
3171*38fd1498Szrj 	{
3172*38fd1498Szrj 	  for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
3173*38fd1498Szrj 	    validate_change (insn, &ASM_OPERANDS_INPUT (x, i),
3174*38fd1498Szrj 			     fold_rtx (ASM_OPERANDS_INPUT (x, i), insn), 0);
3175*38fd1498Szrj 	}
3176*38fd1498Szrj       return x;
3177*38fd1498Szrj 
3178*38fd1498Szrj     case CALL:
3179*38fd1498Szrj       if (NO_FUNCTION_CSE && CONSTANT_P (XEXP (XEXP (x, 0), 0)))
3180*38fd1498Szrj 	return x;
3181*38fd1498Szrj       break;
3182*38fd1498Szrj 
3183*38fd1498Szrj     /* Anything else goes through the loop below.  */
3184*38fd1498Szrj     default:
3185*38fd1498Szrj       break;
3186*38fd1498Szrj     }
3187*38fd1498Szrj 
3188*38fd1498Szrj   mode = GET_MODE (x);
3189*38fd1498Szrj   const_arg0 = 0;
3190*38fd1498Szrj   const_arg1 = 0;
3191*38fd1498Szrj   const_arg2 = 0;
3192*38fd1498Szrj   mode_arg0 = VOIDmode;
3193*38fd1498Szrj 
3194*38fd1498Szrj   /* Try folding our operands.
3195*38fd1498Szrj      Then see which ones have constant values known.  */
3196*38fd1498Szrj 
3197*38fd1498Szrj   fmt = GET_RTX_FORMAT (code);
3198*38fd1498Szrj   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3199*38fd1498Szrj     if (fmt[i] == 'e')
3200*38fd1498Szrj       {
3201*38fd1498Szrj 	rtx folded_arg = XEXP (x, i), const_arg;
3202*38fd1498Szrj 	machine_mode mode_arg = GET_MODE (folded_arg);
3203*38fd1498Szrj 
3204*38fd1498Szrj 	switch (GET_CODE (folded_arg))
3205*38fd1498Szrj 	  {
3206*38fd1498Szrj 	  case MEM:
3207*38fd1498Szrj 	  case REG:
3208*38fd1498Szrj 	  case SUBREG:
3209*38fd1498Szrj 	    const_arg = equiv_constant (folded_arg);
3210*38fd1498Szrj 	    break;
3211*38fd1498Szrj 
3212*38fd1498Szrj 	  case CONST:
3213*38fd1498Szrj 	  CASE_CONST_ANY:
3214*38fd1498Szrj 	  case SYMBOL_REF:
3215*38fd1498Szrj 	  case LABEL_REF:
3216*38fd1498Szrj 	    const_arg = folded_arg;
3217*38fd1498Szrj 	    break;
3218*38fd1498Szrj 
3219*38fd1498Szrj 	  case CC0:
3220*38fd1498Szrj 	    /* The cc0-user and cc0-setter may be in different blocks if
3221*38fd1498Szrj 	       the cc0-setter potentially traps.  In that case PREV_INSN_CC0
3222*38fd1498Szrj 	       will have been cleared as we exited the block with the
3223*38fd1498Szrj 	       setter.
3224*38fd1498Szrj 
3225*38fd1498Szrj 	       While we could potentially track cc0 in this case, it just
3226*38fd1498Szrj 	       doesn't seem to be worth it given that cc0 targets are not
3227*38fd1498Szrj 	       terribly common or important these days and trapping math
3228*38fd1498Szrj 	       is rarely used.  The combination of those two conditions
3229*38fd1498Szrj 	       necessary to trip this situation is exceedingly rare in the
3230*38fd1498Szrj 	       real world.  */
3231*38fd1498Szrj 	    if (!prev_insn_cc0)
3232*38fd1498Szrj 	      {
3233*38fd1498Szrj 		const_arg = NULL_RTX;
3234*38fd1498Szrj 	      }
3235*38fd1498Szrj 	    else
3236*38fd1498Szrj 	      {
3237*38fd1498Szrj 		folded_arg = prev_insn_cc0;
3238*38fd1498Szrj 		mode_arg = prev_insn_cc0_mode;
3239*38fd1498Szrj 		const_arg = equiv_constant (folded_arg);
3240*38fd1498Szrj 	      }
3241*38fd1498Szrj 	    break;
3242*38fd1498Szrj 
3243*38fd1498Szrj 	  default:
3244*38fd1498Szrj 	    folded_arg = fold_rtx (folded_arg, insn);
3245*38fd1498Szrj 	    const_arg = equiv_constant (folded_arg);
3246*38fd1498Szrj 	    break;
3247*38fd1498Szrj 	  }
3248*38fd1498Szrj 
3249*38fd1498Szrj 	/* For the first three operands, see if the operand
3250*38fd1498Szrj 	   is constant or equivalent to a constant.  */
3251*38fd1498Szrj 	switch (i)
3252*38fd1498Szrj 	  {
3253*38fd1498Szrj 	  case 0:
3254*38fd1498Szrj 	    folded_arg0 = folded_arg;
3255*38fd1498Szrj 	    const_arg0 = const_arg;
3256*38fd1498Szrj 	    mode_arg0 = mode_arg;
3257*38fd1498Szrj 	    break;
3258*38fd1498Szrj 	  case 1:
3259*38fd1498Szrj 	    folded_arg1 = folded_arg;
3260*38fd1498Szrj 	    const_arg1 = const_arg;
3261*38fd1498Szrj 	    break;
3262*38fd1498Szrj 	  case 2:
3263*38fd1498Szrj 	    const_arg2 = const_arg;
3264*38fd1498Szrj 	    break;
3265*38fd1498Szrj 	  }
3266*38fd1498Szrj 
3267*38fd1498Szrj 	/* Pick the least expensive of the argument and an equivalent constant
3268*38fd1498Szrj 	   argument.  */
3269*38fd1498Szrj 	if (const_arg != 0
3270*38fd1498Szrj 	    && const_arg != folded_arg
3271*38fd1498Szrj 	    && (COST_IN (const_arg, mode_arg, code, i)
3272*38fd1498Szrj 		<= COST_IN (folded_arg, mode_arg, code, i))
3273*38fd1498Szrj 
3274*38fd1498Szrj 	    /* It's not safe to substitute the operand of a conversion
3275*38fd1498Szrj 	       operator with a constant, as the conversion's identity
3276*38fd1498Szrj 	       depends upon the mode of its operand.  This optimization
3277*38fd1498Szrj 	       is handled by the call to simplify_unary_operation.  */
3278*38fd1498Szrj 	    && (GET_RTX_CLASS (code) != RTX_UNARY
3279*38fd1498Szrj 		|| GET_MODE (const_arg) == mode_arg0
3280*38fd1498Szrj 		|| (code != ZERO_EXTEND
3281*38fd1498Szrj 		    && code != SIGN_EXTEND
3282*38fd1498Szrj 		    && code != TRUNCATE
3283*38fd1498Szrj 		    && code != FLOAT_TRUNCATE
3284*38fd1498Szrj 		    && code != FLOAT_EXTEND
3285*38fd1498Szrj 		    && code != FLOAT
3286*38fd1498Szrj 		    && code != FIX
3287*38fd1498Szrj 		    && code != UNSIGNED_FLOAT
3288*38fd1498Szrj 		    && code != UNSIGNED_FIX)))
3289*38fd1498Szrj 	  folded_arg = const_arg;
3290*38fd1498Szrj 
3291*38fd1498Szrj 	if (folded_arg == XEXP (x, i))
3292*38fd1498Szrj 	  continue;
3293*38fd1498Szrj 
3294*38fd1498Szrj 	if (insn == NULL_RTX && !changed)
3295*38fd1498Szrj 	  x = copy_rtx (x);
3296*38fd1498Szrj 	changed = 1;
3297*38fd1498Szrj 	validate_unshare_change (insn, &XEXP (x, i), folded_arg, 1);
3298*38fd1498Szrj       }
3299*38fd1498Szrj 
3300*38fd1498Szrj   if (changed)
3301*38fd1498Szrj     {
3302*38fd1498Szrj       /* Canonicalize X if necessary, and keep const_argN and folded_argN
3303*38fd1498Szrj 	 consistent with the order in X.  */
3304*38fd1498Szrj       if (canonicalize_change_group (insn, x))
3305*38fd1498Szrj 	{
3306*38fd1498Szrj 	  std::swap (const_arg0, const_arg1);
3307*38fd1498Szrj 	  std::swap (folded_arg0, folded_arg1);
3308*38fd1498Szrj 	}
3309*38fd1498Szrj 
3310*38fd1498Szrj       apply_change_group ();
3311*38fd1498Szrj     }
3312*38fd1498Szrj 
3313*38fd1498Szrj   /* If X is an arithmetic operation, see if we can simplify it.  */
3314*38fd1498Szrj 
3315*38fd1498Szrj   switch (GET_RTX_CLASS (code))
3316*38fd1498Szrj     {
3317*38fd1498Szrj     case RTX_UNARY:
3318*38fd1498Szrj       {
3319*38fd1498Szrj 	/* We can't simplify extension ops unless we know the
3320*38fd1498Szrj 	   original mode.  */
3321*38fd1498Szrj 	if ((code == ZERO_EXTEND || code == SIGN_EXTEND)
3322*38fd1498Szrj 	    && mode_arg0 == VOIDmode)
3323*38fd1498Szrj 	  break;
3324*38fd1498Szrj 
3325*38fd1498Szrj 	new_rtx = simplify_unary_operation (code, mode,
3326*38fd1498Szrj 					    const_arg0 ? const_arg0 : folded_arg0,
3327*38fd1498Szrj 					    mode_arg0);
3328*38fd1498Szrj       }
3329*38fd1498Szrj       break;
3330*38fd1498Szrj 
3331*38fd1498Szrj     case RTX_COMPARE:
3332*38fd1498Szrj     case RTX_COMM_COMPARE:
3333*38fd1498Szrj       /* See what items are actually being compared and set FOLDED_ARG[01]
3334*38fd1498Szrj 	 to those values and CODE to the actual comparison code.  If any are
3335*38fd1498Szrj 	 constant, set CONST_ARG0 and CONST_ARG1 appropriately.  We needn't
3336*38fd1498Szrj 	 do anything if both operands are already known to be constant.  */
3337*38fd1498Szrj 
3338*38fd1498Szrj       /* ??? Vector mode comparisons are not supported yet.  */
3339*38fd1498Szrj       if (VECTOR_MODE_P (mode))
3340*38fd1498Szrj 	break;
3341*38fd1498Szrj 
3342*38fd1498Szrj       if (const_arg0 == 0 || const_arg1 == 0)
3343*38fd1498Szrj 	{
3344*38fd1498Szrj 	  struct table_elt *p0, *p1;
3345*38fd1498Szrj 	  rtx true_rtx, false_rtx;
3346*38fd1498Szrj 	  machine_mode mode_arg1;
3347*38fd1498Szrj 
3348*38fd1498Szrj 	  if (SCALAR_FLOAT_MODE_P (mode))
3349*38fd1498Szrj 	    {
3350*38fd1498Szrj #ifdef FLOAT_STORE_FLAG_VALUE
3351*38fd1498Szrj 	      true_rtx = (const_double_from_real_value
3352*38fd1498Szrj 			  (FLOAT_STORE_FLAG_VALUE (mode), mode));
3353*38fd1498Szrj #else
3354*38fd1498Szrj 	      true_rtx = NULL_RTX;
3355*38fd1498Szrj #endif
3356*38fd1498Szrj 	      false_rtx = CONST0_RTX (mode);
3357*38fd1498Szrj 	    }
3358*38fd1498Szrj 	  else
3359*38fd1498Szrj 	    {
3360*38fd1498Szrj 	      true_rtx = const_true_rtx;
3361*38fd1498Szrj 	      false_rtx = const0_rtx;
3362*38fd1498Szrj 	    }
3363*38fd1498Szrj 
3364*38fd1498Szrj 	  code = find_comparison_args (code, &folded_arg0, &folded_arg1,
3365*38fd1498Szrj 				       &mode_arg0, &mode_arg1);
3366*38fd1498Szrj 
3367*38fd1498Szrj 	  /* If the mode is VOIDmode or a MODE_CC mode, we don't know
3368*38fd1498Szrj 	     what kinds of things are being compared, so we can't do
3369*38fd1498Szrj 	     anything with this comparison.  */
3370*38fd1498Szrj 
3371*38fd1498Szrj 	  if (mode_arg0 == VOIDmode || GET_MODE_CLASS (mode_arg0) == MODE_CC)
3372*38fd1498Szrj 	    break;
3373*38fd1498Szrj 
3374*38fd1498Szrj 	  const_arg0 = equiv_constant (folded_arg0);
3375*38fd1498Szrj 	  const_arg1 = equiv_constant (folded_arg1);
3376*38fd1498Szrj 
3377*38fd1498Szrj 	  /* If we do not now have two constants being compared, see
3378*38fd1498Szrj 	     if we can nevertheless deduce some things about the
3379*38fd1498Szrj 	     comparison.  */
3380*38fd1498Szrj 	  if (const_arg0 == 0 || const_arg1 == 0)
3381*38fd1498Szrj 	    {
3382*38fd1498Szrj 	      if (const_arg1 != NULL)
3383*38fd1498Szrj 		{
3384*38fd1498Szrj 		  rtx cheapest_simplification;
3385*38fd1498Szrj 		  int cheapest_cost;
3386*38fd1498Szrj 		  rtx simp_result;
3387*38fd1498Szrj 		  struct table_elt *p;
3388*38fd1498Szrj 
3389*38fd1498Szrj 		  /* See if we can find an equivalent of folded_arg0
3390*38fd1498Szrj 		     that gets us a cheaper expression, possibly a
3391*38fd1498Szrj 		     constant through simplifications.  */
3392*38fd1498Szrj 		  p = lookup (folded_arg0, SAFE_HASH (folded_arg0, mode_arg0),
3393*38fd1498Szrj 			      mode_arg0);
3394*38fd1498Szrj 
3395*38fd1498Szrj 		  if (p != NULL)
3396*38fd1498Szrj 		    {
3397*38fd1498Szrj 		      cheapest_simplification = x;
3398*38fd1498Szrj 		      cheapest_cost = COST (x, mode);
3399*38fd1498Szrj 
3400*38fd1498Szrj 		      for (p = p->first_same_value; p != NULL; p = p->next_same_value)
3401*38fd1498Szrj 			{
3402*38fd1498Szrj 			  int cost;
3403*38fd1498Szrj 
3404*38fd1498Szrj 			  /* If the entry isn't valid, skip it.  */
3405*38fd1498Szrj 			  if (! exp_equiv_p (p->exp, p->exp, 1, false))
3406*38fd1498Szrj 			    continue;
3407*38fd1498Szrj 
3408*38fd1498Szrj 			  /* Try to simplify using this equivalence.  */
3409*38fd1498Szrj 			  simp_result
3410*38fd1498Szrj 			    = simplify_relational_operation (code, mode,
3411*38fd1498Szrj 							     mode_arg0,
3412*38fd1498Szrj 							     p->exp,
3413*38fd1498Szrj 							     const_arg1);
3414*38fd1498Szrj 
3415*38fd1498Szrj 			  if (simp_result == NULL)
3416*38fd1498Szrj 			    continue;
3417*38fd1498Szrj 
3418*38fd1498Szrj 			  cost = COST (simp_result, mode);
3419*38fd1498Szrj 			  if (cost < cheapest_cost)
3420*38fd1498Szrj 			    {
3421*38fd1498Szrj 			      cheapest_cost = cost;
3422*38fd1498Szrj 			      cheapest_simplification = simp_result;
3423*38fd1498Szrj 			    }
3424*38fd1498Szrj 			}
3425*38fd1498Szrj 
3426*38fd1498Szrj 		      /* If we have a cheaper expression now, use that
3427*38fd1498Szrj 			 and try folding it further, from the top.  */
3428*38fd1498Szrj 		      if (cheapest_simplification != x)
3429*38fd1498Szrj 			return fold_rtx (copy_rtx (cheapest_simplification),
3430*38fd1498Szrj 					 insn);
3431*38fd1498Szrj 		    }
3432*38fd1498Szrj 		}
3433*38fd1498Szrj 
3434*38fd1498Szrj 	      /* See if the two operands are the same.  */
3435*38fd1498Szrj 
3436*38fd1498Szrj 	      if ((REG_P (folded_arg0)
3437*38fd1498Szrj 		   && REG_P (folded_arg1)
3438*38fd1498Szrj 		   && (REG_QTY (REGNO (folded_arg0))
3439*38fd1498Szrj 		       == REG_QTY (REGNO (folded_arg1))))
3440*38fd1498Szrj 		  || ((p0 = lookup (folded_arg0,
3441*38fd1498Szrj 				    SAFE_HASH (folded_arg0, mode_arg0),
3442*38fd1498Szrj 				    mode_arg0))
3443*38fd1498Szrj 		      && (p1 = lookup (folded_arg1,
3444*38fd1498Szrj 				       SAFE_HASH (folded_arg1, mode_arg0),
3445*38fd1498Szrj 				       mode_arg0))
3446*38fd1498Szrj 		      && p0->first_same_value == p1->first_same_value))
3447*38fd1498Szrj 		folded_arg1 = folded_arg0;
3448*38fd1498Szrj 
3449*38fd1498Szrj 	      /* If FOLDED_ARG0 is a register, see if the comparison we are
3450*38fd1498Szrj 		 doing now is either the same as we did before or the reverse
3451*38fd1498Szrj 		 (we only check the reverse if not floating-point).  */
3452*38fd1498Szrj 	      else if (REG_P (folded_arg0))
3453*38fd1498Szrj 		{
3454*38fd1498Szrj 		  int qty = REG_QTY (REGNO (folded_arg0));
3455*38fd1498Szrj 
3456*38fd1498Szrj 		  if (REGNO_QTY_VALID_P (REGNO (folded_arg0)))
3457*38fd1498Szrj 		    {
3458*38fd1498Szrj 		      struct qty_table_elem *ent = &qty_table[qty];
3459*38fd1498Szrj 
3460*38fd1498Szrj 		      if ((comparison_dominates_p (ent->comparison_code, code)
3461*38fd1498Szrj 			   || (! FLOAT_MODE_P (mode_arg0)
3462*38fd1498Szrj 			       && comparison_dominates_p (ent->comparison_code,
3463*38fd1498Szrj 						          reverse_condition (code))))
3464*38fd1498Szrj 			  && (rtx_equal_p (ent->comparison_const, folded_arg1)
3465*38fd1498Szrj 			      || (const_arg1
3466*38fd1498Szrj 				  && rtx_equal_p (ent->comparison_const,
3467*38fd1498Szrj 						  const_arg1))
3468*38fd1498Szrj 			      || (REG_P (folded_arg1)
3469*38fd1498Szrj 				  && (REG_QTY (REGNO (folded_arg1)) == ent->comparison_qty))))
3470*38fd1498Szrj 			{
3471*38fd1498Szrj 			  if (comparison_dominates_p (ent->comparison_code, code))
3472*38fd1498Szrj 			    {
3473*38fd1498Szrj 			      if (true_rtx)
3474*38fd1498Szrj 				return true_rtx;
3475*38fd1498Szrj 			      else
3476*38fd1498Szrj 				break;
3477*38fd1498Szrj 			    }
3478*38fd1498Szrj 			  else
3479*38fd1498Szrj 			    return false_rtx;
3480*38fd1498Szrj 			}
3481*38fd1498Szrj 		    }
3482*38fd1498Szrj 		}
3483*38fd1498Szrj 	    }
3484*38fd1498Szrj 	}
3485*38fd1498Szrj 
3486*38fd1498Szrj       /* If we are comparing against zero, see if the first operand is
3487*38fd1498Szrj 	 equivalent to an IOR with a constant.  If so, we may be able to
3488*38fd1498Szrj 	 determine the result of this comparison.  */
3489*38fd1498Szrj       if (const_arg1 == const0_rtx && !const_arg0)
3490*38fd1498Szrj 	{
3491*38fd1498Szrj 	  rtx y = lookup_as_function (folded_arg0, IOR);
3492*38fd1498Szrj 	  rtx inner_const;
3493*38fd1498Szrj 
3494*38fd1498Szrj 	  if (y != 0
3495*38fd1498Szrj 	      && (inner_const = equiv_constant (XEXP (y, 1))) != 0
3496*38fd1498Szrj 	      && CONST_INT_P (inner_const)
3497*38fd1498Szrj 	      && INTVAL (inner_const) != 0)
3498*38fd1498Szrj 	    folded_arg0 = gen_rtx_IOR (mode_arg0, XEXP (y, 0), inner_const);
3499*38fd1498Szrj 	}
3500*38fd1498Szrj 
3501*38fd1498Szrj       {
3502*38fd1498Szrj 	rtx op0 = const_arg0 ? const_arg0 : copy_rtx (folded_arg0);
3503*38fd1498Szrj 	rtx op1 = const_arg1 ? const_arg1 : copy_rtx (folded_arg1);
3504*38fd1498Szrj 	new_rtx = simplify_relational_operation (code, mode, mode_arg0,
3505*38fd1498Szrj 						 op0, op1);
3506*38fd1498Szrj       }
3507*38fd1498Szrj       break;
3508*38fd1498Szrj 
3509*38fd1498Szrj     case RTX_BIN_ARITH:
3510*38fd1498Szrj     case RTX_COMM_ARITH:
3511*38fd1498Szrj       switch (code)
3512*38fd1498Szrj 	{
3513*38fd1498Szrj 	case PLUS:
3514*38fd1498Szrj 	  /* If the second operand is a LABEL_REF, see if the first is a MINUS
3515*38fd1498Szrj 	     with that LABEL_REF as its second operand.  If so, the result is
3516*38fd1498Szrj 	     the first operand of that MINUS.  This handles switches with an
3517*38fd1498Szrj 	     ADDR_DIFF_VEC table.  */
3518*38fd1498Szrj 	  if (const_arg1 && GET_CODE (const_arg1) == LABEL_REF)
3519*38fd1498Szrj 	    {
3520*38fd1498Szrj 	      rtx y
3521*38fd1498Szrj 		= GET_CODE (folded_arg0) == MINUS ? folded_arg0
3522*38fd1498Szrj 		: lookup_as_function (folded_arg0, MINUS);
3523*38fd1498Szrj 
3524*38fd1498Szrj 	      if (y != 0 && GET_CODE (XEXP (y, 1)) == LABEL_REF
3525*38fd1498Szrj 		  && label_ref_label (XEXP (y, 1)) == label_ref_label (const_arg1))
3526*38fd1498Szrj 		return XEXP (y, 0);
3527*38fd1498Szrj 
3528*38fd1498Szrj 	      /* Now try for a CONST of a MINUS like the above.  */
3529*38fd1498Szrj 	      if ((y = (GET_CODE (folded_arg0) == CONST ? folded_arg0
3530*38fd1498Szrj 			: lookup_as_function (folded_arg0, CONST))) != 0
3531*38fd1498Szrj 		  && GET_CODE (XEXP (y, 0)) == MINUS
3532*38fd1498Szrj 		  && GET_CODE (XEXP (XEXP (y, 0), 1)) == LABEL_REF
3533*38fd1498Szrj 		  && label_ref_label (XEXP (XEXP (y, 0), 1)) == label_ref_label (const_arg1))
3534*38fd1498Szrj 		return XEXP (XEXP (y, 0), 0);
3535*38fd1498Szrj 	    }
3536*38fd1498Szrj 
3537*38fd1498Szrj 	  /* Likewise if the operands are in the other order.  */
3538*38fd1498Szrj 	  if (const_arg0 && GET_CODE (const_arg0) == LABEL_REF)
3539*38fd1498Szrj 	    {
3540*38fd1498Szrj 	      rtx y
3541*38fd1498Szrj 		= GET_CODE (folded_arg1) == MINUS ? folded_arg1
3542*38fd1498Szrj 		: lookup_as_function (folded_arg1, MINUS);
3543*38fd1498Szrj 
3544*38fd1498Szrj 	      if (y != 0 && GET_CODE (XEXP (y, 1)) == LABEL_REF
3545*38fd1498Szrj 		  && label_ref_label (XEXP (y, 1)) == label_ref_label (const_arg0))
3546*38fd1498Szrj 		return XEXP (y, 0);
3547*38fd1498Szrj 
3548*38fd1498Szrj 	      /* Now try for a CONST of a MINUS like the above.  */
3549*38fd1498Szrj 	      if ((y = (GET_CODE (folded_arg1) == CONST ? folded_arg1
3550*38fd1498Szrj 			: lookup_as_function (folded_arg1, CONST))) != 0
3551*38fd1498Szrj 		  && GET_CODE (XEXP (y, 0)) == MINUS
3552*38fd1498Szrj 		  && GET_CODE (XEXP (XEXP (y, 0), 1)) == LABEL_REF
3553*38fd1498Szrj 		  && label_ref_label (XEXP (XEXP (y, 0), 1)) == label_ref_label (const_arg0))
3554*38fd1498Szrj 		return XEXP (XEXP (y, 0), 0);
3555*38fd1498Szrj 	    }
3556*38fd1498Szrj 
3557*38fd1498Szrj 	  /* If second operand is a register equivalent to a negative
3558*38fd1498Szrj 	     CONST_INT, see if we can find a register equivalent to the
3559*38fd1498Szrj 	     positive constant.  Make a MINUS if so.  Don't do this for
3560*38fd1498Szrj 	     a non-negative constant since we might then alternate between
3561*38fd1498Szrj 	     choosing positive and negative constants.  Having the positive
3562*38fd1498Szrj 	     constant previously-used is the more common case.  Be sure
3563*38fd1498Szrj 	     the resulting constant is non-negative; if const_arg1 were
3564*38fd1498Szrj 	     the smallest negative number this would overflow: depending
3565*38fd1498Szrj 	     on the mode, this would either just be the same value (and
3566*38fd1498Szrj 	     hence not save anything) or be incorrect.  */
3567*38fd1498Szrj 	  if (const_arg1 != 0 && CONST_INT_P (const_arg1)
3568*38fd1498Szrj 	      && INTVAL (const_arg1) < 0
3569*38fd1498Szrj 	      /* This used to test
3570*38fd1498Szrj 
3571*38fd1498Szrj 	         -INTVAL (const_arg1) >= 0
3572*38fd1498Szrj 
3573*38fd1498Szrj 		 But The Sun V5.0 compilers mis-compiled that test.  So
3574*38fd1498Szrj 		 instead we test for the problematic value in a more direct
3575*38fd1498Szrj 		 manner and hope the Sun compilers get it correct.  */
3576*38fd1498Szrj 	      && INTVAL (const_arg1) !=
3577*38fd1498Szrj 	        (HOST_WIDE_INT_1 << (HOST_BITS_PER_WIDE_INT - 1))
3578*38fd1498Szrj 	      && REG_P (folded_arg1))
3579*38fd1498Szrj 	    {
3580*38fd1498Szrj 	      rtx new_const = GEN_INT (-INTVAL (const_arg1));
3581*38fd1498Szrj 	      struct table_elt *p
3582*38fd1498Szrj 		= lookup (new_const, SAFE_HASH (new_const, mode), mode);
3583*38fd1498Szrj 
3584*38fd1498Szrj 	      if (p)
3585*38fd1498Szrj 		for (p = p->first_same_value; p; p = p->next_same_value)
3586*38fd1498Szrj 		  if (REG_P (p->exp))
3587*38fd1498Szrj 		    return simplify_gen_binary (MINUS, mode, folded_arg0,
3588*38fd1498Szrj 						canon_reg (p->exp, NULL));
3589*38fd1498Szrj 	    }
3590*38fd1498Szrj 	  goto from_plus;
3591*38fd1498Szrj 
3592*38fd1498Szrj 	case MINUS:
3593*38fd1498Szrj 	  /* If we have (MINUS Y C), see if Y is known to be (PLUS Z C2).
3594*38fd1498Szrj 	     If so, produce (PLUS Z C2-C).  */
3595*38fd1498Szrj 	  if (const_arg1 != 0 && CONST_INT_P (const_arg1))
3596*38fd1498Szrj 	    {
3597*38fd1498Szrj 	      rtx y = lookup_as_function (XEXP (x, 0), PLUS);
3598*38fd1498Szrj 	      if (y && CONST_INT_P (XEXP (y, 1)))
3599*38fd1498Szrj 		return fold_rtx (plus_constant (mode, copy_rtx (y),
3600*38fd1498Szrj 						-INTVAL (const_arg1)),
3601*38fd1498Szrj 				 NULL);
3602*38fd1498Szrj 	    }
3603*38fd1498Szrj 
3604*38fd1498Szrj 	  /* Fall through.  */
3605*38fd1498Szrj 
3606*38fd1498Szrj 	from_plus:
3607*38fd1498Szrj 	case SMIN:    case SMAX:      case UMIN:    case UMAX:
3608*38fd1498Szrj 	case IOR:     case AND:       case XOR:
3609*38fd1498Szrj 	case MULT:
3610*38fd1498Szrj 	case ASHIFT:  case LSHIFTRT:  case ASHIFTRT:
3611*38fd1498Szrj 	  /* If we have (<op> <reg> <const_int>) for an associative OP and REG
3612*38fd1498Szrj 	     is known to be of similar form, we may be able to replace the
3613*38fd1498Szrj 	     operation with a combined operation.  This may eliminate the
3614*38fd1498Szrj 	     intermediate operation if every use is simplified in this way.
3615*38fd1498Szrj 	     Note that the similar optimization done by combine.c only works
3616*38fd1498Szrj 	     if the intermediate operation's result has only one reference.  */
3617*38fd1498Szrj 
3618*38fd1498Szrj 	  if (REG_P (folded_arg0)
3619*38fd1498Szrj 	      && const_arg1 && CONST_INT_P (const_arg1))
3620*38fd1498Szrj 	    {
3621*38fd1498Szrj 	      int is_shift
3622*38fd1498Szrj 		= (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT);
3623*38fd1498Szrj 	      rtx y, inner_const, new_const;
3624*38fd1498Szrj 	      rtx canon_const_arg1 = const_arg1;
3625*38fd1498Szrj 	      enum rtx_code associate_code;
3626*38fd1498Szrj 
3627*38fd1498Szrj 	      if (is_shift
3628*38fd1498Szrj 		  && (INTVAL (const_arg1) >= GET_MODE_UNIT_PRECISION (mode)
3629*38fd1498Szrj 		      || INTVAL (const_arg1) < 0))
3630*38fd1498Szrj 		{
3631*38fd1498Szrj 		  if (SHIFT_COUNT_TRUNCATED)
3632*38fd1498Szrj 		    canon_const_arg1 = gen_int_shift_amount
3633*38fd1498Szrj 		      (mode, (INTVAL (const_arg1)
3634*38fd1498Szrj 			      & (GET_MODE_UNIT_BITSIZE (mode) - 1)));
3635*38fd1498Szrj 		  else
3636*38fd1498Szrj 		    break;
3637*38fd1498Szrj 		}
3638*38fd1498Szrj 
3639*38fd1498Szrj 	      y = lookup_as_function (folded_arg0, code);
3640*38fd1498Szrj 	      if (y == 0)
3641*38fd1498Szrj 		break;
3642*38fd1498Szrj 
3643*38fd1498Szrj 	      /* If we have compiled a statement like
3644*38fd1498Szrj 		 "if (x == (x & mask1))", and now are looking at
3645*38fd1498Szrj 		 "x & mask2", we will have a case where the first operand
3646*38fd1498Szrj 		 of Y is the same as our first operand.  Unless we detect
3647*38fd1498Szrj 		 this case, an infinite loop will result.  */
3648*38fd1498Szrj 	      if (XEXP (y, 0) == folded_arg0)
3649*38fd1498Szrj 		break;
3650*38fd1498Szrj 
3651*38fd1498Szrj 	      inner_const = equiv_constant (fold_rtx (XEXP (y, 1), 0));
3652*38fd1498Szrj 	      if (!inner_const || !CONST_INT_P (inner_const))
3653*38fd1498Szrj 		break;
3654*38fd1498Szrj 
3655*38fd1498Szrj 	      /* Don't associate these operations if they are a PLUS with the
3656*38fd1498Szrj 		 same constant and it is a power of two.  These might be doable
3657*38fd1498Szrj 		 with a pre- or post-increment.  Similarly for two subtracts of
3658*38fd1498Szrj 		 identical powers of two with post decrement.  */
3659*38fd1498Szrj 
3660*38fd1498Szrj 	      if (code == PLUS && const_arg1 == inner_const
3661*38fd1498Szrj 		  && ((HAVE_PRE_INCREMENT
3662*38fd1498Szrj 			  && pow2p_hwi (INTVAL (const_arg1)))
3663*38fd1498Szrj 		      || (HAVE_POST_INCREMENT
3664*38fd1498Szrj 			  && pow2p_hwi (INTVAL (const_arg1)))
3665*38fd1498Szrj 		      || (HAVE_PRE_DECREMENT
3666*38fd1498Szrj 			  && pow2p_hwi (- INTVAL (const_arg1)))
3667*38fd1498Szrj 		      || (HAVE_POST_DECREMENT
3668*38fd1498Szrj 			  && pow2p_hwi (- INTVAL (const_arg1)))))
3669*38fd1498Szrj 		break;
3670*38fd1498Szrj 
3671*38fd1498Szrj 	      /* ??? Vector mode shifts by scalar
3672*38fd1498Szrj 		 shift operand are not supported yet.  */
3673*38fd1498Szrj 	      if (is_shift && VECTOR_MODE_P (mode))
3674*38fd1498Szrj                 break;
3675*38fd1498Szrj 
3676*38fd1498Szrj 	      if (is_shift
3677*38fd1498Szrj 		  && (INTVAL (inner_const) >= GET_MODE_UNIT_PRECISION (mode)
3678*38fd1498Szrj 		      || INTVAL (inner_const) < 0))
3679*38fd1498Szrj 		{
3680*38fd1498Szrj 		  if (SHIFT_COUNT_TRUNCATED)
3681*38fd1498Szrj 		    inner_const = gen_int_shift_amount
3682*38fd1498Szrj 		      (mode, (INTVAL (inner_const)
3683*38fd1498Szrj 			      & (GET_MODE_UNIT_BITSIZE (mode) - 1)));
3684*38fd1498Szrj 		  else
3685*38fd1498Szrj 		    break;
3686*38fd1498Szrj 		}
3687*38fd1498Szrj 
3688*38fd1498Szrj 	      /* Compute the code used to compose the constants.  For example,
3689*38fd1498Szrj 		 A-C1-C2 is A-(C1 + C2), so if CODE == MINUS, we want PLUS.  */
3690*38fd1498Szrj 
3691*38fd1498Szrj 	      associate_code = (is_shift || code == MINUS ? PLUS : code);
3692*38fd1498Szrj 
3693*38fd1498Szrj 	      new_const = simplify_binary_operation (associate_code, mode,
3694*38fd1498Szrj 						     canon_const_arg1,
3695*38fd1498Szrj 						     inner_const);
3696*38fd1498Szrj 
3697*38fd1498Szrj 	      if (new_const == 0)
3698*38fd1498Szrj 		break;
3699*38fd1498Szrj 
3700*38fd1498Szrj 	      /* If we are associating shift operations, don't let this
3701*38fd1498Szrj 		 produce a shift of the size of the object or larger.
3702*38fd1498Szrj 		 This could occur when we follow a sign-extend by a right
3703*38fd1498Szrj 		 shift on a machine that does a sign-extend as a pair
3704*38fd1498Szrj 		 of shifts.  */
3705*38fd1498Szrj 
3706*38fd1498Szrj 	      if (is_shift
3707*38fd1498Szrj 		  && CONST_INT_P (new_const)
3708*38fd1498Szrj 		  && INTVAL (new_const) >= GET_MODE_UNIT_PRECISION (mode))
3709*38fd1498Szrj 		{
3710*38fd1498Szrj 		  /* As an exception, we can turn an ASHIFTRT of this
3711*38fd1498Szrj 		     form into a shift of the number of bits - 1.  */
3712*38fd1498Szrj 		  if (code == ASHIFTRT)
3713*38fd1498Szrj 		    new_const = gen_int_shift_amount
3714*38fd1498Szrj 		      (mode, GET_MODE_UNIT_BITSIZE (mode) - 1);
3715*38fd1498Szrj 		  else if (!side_effects_p (XEXP (y, 0)))
3716*38fd1498Szrj 		    return CONST0_RTX (mode);
3717*38fd1498Szrj 		  else
3718*38fd1498Szrj 		    break;
3719*38fd1498Szrj 		}
3720*38fd1498Szrj 
3721*38fd1498Szrj 	      y = copy_rtx (XEXP (y, 0));
3722*38fd1498Szrj 
3723*38fd1498Szrj 	      /* If Y contains our first operand (the most common way this
3724*38fd1498Szrj 		 can happen is if Y is a MEM), we would do into an infinite
3725*38fd1498Szrj 		 loop if we tried to fold it.  So don't in that case.  */
3726*38fd1498Szrj 
3727*38fd1498Szrj 	      if (! reg_mentioned_p (folded_arg0, y))
3728*38fd1498Szrj 		y = fold_rtx (y, insn);
3729*38fd1498Szrj 
3730*38fd1498Szrj 	      return simplify_gen_binary (code, mode, y, new_const);
3731*38fd1498Szrj 	    }
3732*38fd1498Szrj 	  break;
3733*38fd1498Szrj 
3734*38fd1498Szrj 	case DIV:       case UDIV:
3735*38fd1498Szrj 	  /* ??? The associative optimization performed immediately above is
3736*38fd1498Szrj 	     also possible for DIV and UDIV using associate_code of MULT.
3737*38fd1498Szrj 	     However, we would need extra code to verify that the
3738*38fd1498Szrj 	     multiplication does not overflow, that is, there is no overflow
3739*38fd1498Szrj 	     in the calculation of new_const.  */
3740*38fd1498Szrj 	  break;
3741*38fd1498Szrj 
3742*38fd1498Szrj 	default:
3743*38fd1498Szrj 	  break;
3744*38fd1498Szrj 	}
3745*38fd1498Szrj 
3746*38fd1498Szrj       new_rtx = simplify_binary_operation (code, mode,
3747*38fd1498Szrj 				       const_arg0 ? const_arg0 : folded_arg0,
3748*38fd1498Szrj 				       const_arg1 ? const_arg1 : folded_arg1);
3749*38fd1498Szrj       break;
3750*38fd1498Szrj 
3751*38fd1498Szrj     case RTX_OBJ:
3752*38fd1498Szrj       /* (lo_sum (high X) X) is simply X.  */
3753*38fd1498Szrj       if (code == LO_SUM && const_arg0 != 0
3754*38fd1498Szrj 	  && GET_CODE (const_arg0) == HIGH
3755*38fd1498Szrj 	  && rtx_equal_p (XEXP (const_arg0, 0), const_arg1))
3756*38fd1498Szrj 	return const_arg1;
3757*38fd1498Szrj       break;
3758*38fd1498Szrj 
3759*38fd1498Szrj     case RTX_TERNARY:
3760*38fd1498Szrj     case RTX_BITFIELD_OPS:
3761*38fd1498Szrj       new_rtx = simplify_ternary_operation (code, mode, mode_arg0,
3762*38fd1498Szrj 					const_arg0 ? const_arg0 : folded_arg0,
3763*38fd1498Szrj 					const_arg1 ? const_arg1 : folded_arg1,
3764*38fd1498Szrj 					const_arg2 ? const_arg2 : XEXP (x, 2));
3765*38fd1498Szrj       break;
3766*38fd1498Szrj 
3767*38fd1498Szrj     default:
3768*38fd1498Szrj       break;
3769*38fd1498Szrj     }
3770*38fd1498Szrj 
3771*38fd1498Szrj   return new_rtx ? new_rtx : x;
3772*38fd1498Szrj }
3773*38fd1498Szrj 
3774*38fd1498Szrj /* Return a constant value currently equivalent to X.
3775*38fd1498Szrj    Return 0 if we don't know one.  */
3776*38fd1498Szrj 
3777*38fd1498Szrj static rtx
equiv_constant(rtx x)3778*38fd1498Szrj equiv_constant (rtx x)
3779*38fd1498Szrj {
3780*38fd1498Szrj   if (REG_P (x)
3781*38fd1498Szrj       && REGNO_QTY_VALID_P (REGNO (x)))
3782*38fd1498Szrj     {
3783*38fd1498Szrj       int x_q = REG_QTY (REGNO (x));
3784*38fd1498Szrj       struct qty_table_elem *x_ent = &qty_table[x_q];
3785*38fd1498Szrj 
3786*38fd1498Szrj       if (x_ent->const_rtx)
3787*38fd1498Szrj 	x = gen_lowpart (GET_MODE (x), x_ent->const_rtx);
3788*38fd1498Szrj     }
3789*38fd1498Szrj 
3790*38fd1498Szrj   if (x == 0 || CONSTANT_P (x))
3791*38fd1498Szrj     return x;
3792*38fd1498Szrj 
3793*38fd1498Szrj   if (GET_CODE (x) == SUBREG)
3794*38fd1498Szrj     {
3795*38fd1498Szrj       machine_mode mode = GET_MODE (x);
3796*38fd1498Szrj       machine_mode imode = GET_MODE (SUBREG_REG (x));
3797*38fd1498Szrj       rtx new_rtx;
3798*38fd1498Szrj 
3799*38fd1498Szrj       /* See if we previously assigned a constant value to this SUBREG.  */
3800*38fd1498Szrj       if ((new_rtx = lookup_as_function (x, CONST_INT)) != 0
3801*38fd1498Szrj 	  || (new_rtx = lookup_as_function (x, CONST_WIDE_INT)) != 0
3802*38fd1498Szrj 	  || (NUM_POLY_INT_COEFFS > 1
3803*38fd1498Szrj 	      && (new_rtx = lookup_as_function (x, CONST_POLY_INT)) != 0)
3804*38fd1498Szrj           || (new_rtx = lookup_as_function (x, CONST_DOUBLE)) != 0
3805*38fd1498Szrj           || (new_rtx = lookup_as_function (x, CONST_FIXED)) != 0)
3806*38fd1498Szrj         return new_rtx;
3807*38fd1498Szrj 
3808*38fd1498Szrj       /* If we didn't and if doing so makes sense, see if we previously
3809*38fd1498Szrj 	 assigned a constant value to the enclosing word mode SUBREG.  */
3810*38fd1498Szrj       if (known_lt (GET_MODE_SIZE (mode), UNITS_PER_WORD)
3811*38fd1498Szrj 	  && known_lt (UNITS_PER_WORD, GET_MODE_SIZE (imode)))
3812*38fd1498Szrj 	{
3813*38fd1498Szrj 	  poly_int64 byte = (SUBREG_BYTE (x)
3814*38fd1498Szrj 			     - subreg_lowpart_offset (mode, word_mode));
3815*38fd1498Szrj 	  if (known_ge (byte, 0) && multiple_p (byte, UNITS_PER_WORD))
3816*38fd1498Szrj 	    {
3817*38fd1498Szrj 	      rtx y = gen_rtx_SUBREG (word_mode, SUBREG_REG (x), byte);
3818*38fd1498Szrj 	      new_rtx = lookup_as_function (y, CONST_INT);
3819*38fd1498Szrj 	      if (new_rtx)
3820*38fd1498Szrj 		return gen_lowpart (mode, new_rtx);
3821*38fd1498Szrj 	    }
3822*38fd1498Szrj 	}
3823*38fd1498Szrj 
3824*38fd1498Szrj       /* Otherwise see if we already have a constant for the inner REG,
3825*38fd1498Szrj 	 and if that is enough to calculate an equivalent constant for
3826*38fd1498Szrj 	 the subreg.  Note that the upper bits of paradoxical subregs
3827*38fd1498Szrj 	 are undefined, so they cannot be said to equal anything.  */
3828*38fd1498Szrj       if (REG_P (SUBREG_REG (x))
3829*38fd1498Szrj 	  && !paradoxical_subreg_p (x)
3830*38fd1498Szrj 	  && (new_rtx = equiv_constant (SUBREG_REG (x))) != 0)
3831*38fd1498Szrj         return simplify_subreg (mode, new_rtx, imode, SUBREG_BYTE (x));
3832*38fd1498Szrj 
3833*38fd1498Szrj       return 0;
3834*38fd1498Szrj     }
3835*38fd1498Szrj 
3836*38fd1498Szrj   /* If X is a MEM, see if it is a constant-pool reference, or look it up in
3837*38fd1498Szrj      the hash table in case its value was seen before.  */
3838*38fd1498Szrj 
3839*38fd1498Szrj   if (MEM_P (x))
3840*38fd1498Szrj     {
3841*38fd1498Szrj       struct table_elt *elt;
3842*38fd1498Szrj 
3843*38fd1498Szrj       x = avoid_constant_pool_reference (x);
3844*38fd1498Szrj       if (CONSTANT_P (x))
3845*38fd1498Szrj 	return x;
3846*38fd1498Szrj 
3847*38fd1498Szrj       elt = lookup (x, SAFE_HASH (x, GET_MODE (x)), GET_MODE (x));
3848*38fd1498Szrj       if (elt == 0)
3849*38fd1498Szrj 	return 0;
3850*38fd1498Szrj 
3851*38fd1498Szrj       for (elt = elt->first_same_value; elt; elt = elt->next_same_value)
3852*38fd1498Szrj 	if (elt->is_const && CONSTANT_P (elt->exp))
3853*38fd1498Szrj 	  return elt->exp;
3854*38fd1498Szrj     }
3855*38fd1498Szrj 
3856*38fd1498Szrj   return 0;
3857*38fd1498Szrj }
3858*38fd1498Szrj 
3859*38fd1498Szrj /* Given INSN, a jump insn, TAKEN indicates if we are following the
3860*38fd1498Szrj    "taken" branch.
3861*38fd1498Szrj 
3862*38fd1498Szrj    In certain cases, this can cause us to add an equivalence.  For example,
3863*38fd1498Szrj    if we are following the taken case of
3864*38fd1498Szrj 	if (i == 2)
3865*38fd1498Szrj    we can add the fact that `i' and '2' are now equivalent.
3866*38fd1498Szrj 
3867*38fd1498Szrj    In any case, we can record that this comparison was passed.  If the same
3868*38fd1498Szrj    comparison is seen later, we will know its value.  */
3869*38fd1498Szrj 
3870*38fd1498Szrj static void
record_jump_equiv(rtx_insn * insn,bool taken)3871*38fd1498Szrj record_jump_equiv (rtx_insn *insn, bool taken)
3872*38fd1498Szrj {
3873*38fd1498Szrj   int cond_known_true;
3874*38fd1498Szrj   rtx op0, op1;
3875*38fd1498Szrj   rtx set;
3876*38fd1498Szrj   machine_mode mode, mode0, mode1;
3877*38fd1498Szrj   int reversed_nonequality = 0;
3878*38fd1498Szrj   enum rtx_code code;
3879*38fd1498Szrj 
3880*38fd1498Szrj   /* Ensure this is the right kind of insn.  */
3881*38fd1498Szrj   gcc_assert (any_condjump_p (insn));
3882*38fd1498Szrj 
3883*38fd1498Szrj   set = pc_set (insn);
3884*38fd1498Szrj 
3885*38fd1498Szrj   /* See if this jump condition is known true or false.  */
3886*38fd1498Szrj   if (taken)
3887*38fd1498Szrj     cond_known_true = (XEXP (SET_SRC (set), 2) == pc_rtx);
3888*38fd1498Szrj   else
3889*38fd1498Szrj     cond_known_true = (XEXP (SET_SRC (set), 1) == pc_rtx);
3890*38fd1498Szrj 
3891*38fd1498Szrj   /* Get the type of comparison being done and the operands being compared.
3892*38fd1498Szrj      If we had to reverse a non-equality condition, record that fact so we
3893*38fd1498Szrj      know that it isn't valid for floating-point.  */
3894*38fd1498Szrj   code = GET_CODE (XEXP (SET_SRC (set), 0));
3895*38fd1498Szrj   op0 = fold_rtx (XEXP (XEXP (SET_SRC (set), 0), 0), insn);
3896*38fd1498Szrj   op1 = fold_rtx (XEXP (XEXP (SET_SRC (set), 0), 1), insn);
3897*38fd1498Szrj 
3898*38fd1498Szrj   /* On a cc0 target the cc0-setter and cc0-user may end up in different
3899*38fd1498Szrj      blocks.  When that happens the tracking of the cc0-setter via
3900*38fd1498Szrj      PREV_INSN_CC0 is spoiled.  That means that fold_rtx may return
3901*38fd1498Szrj      NULL_RTX.  In those cases, there's nothing to record.  */
3902*38fd1498Szrj   if (op0 == NULL_RTX || op1 == NULL_RTX)
3903*38fd1498Szrj     return;
3904*38fd1498Szrj 
3905*38fd1498Szrj   code = find_comparison_args (code, &op0, &op1, &mode0, &mode1);
3906*38fd1498Szrj   if (! cond_known_true)
3907*38fd1498Szrj     {
3908*38fd1498Szrj       code = reversed_comparison_code_parts (code, op0, op1, insn);
3909*38fd1498Szrj 
3910*38fd1498Szrj       /* Don't remember if we can't find the inverse.  */
3911*38fd1498Szrj       if (code == UNKNOWN)
3912*38fd1498Szrj 	return;
3913*38fd1498Szrj     }
3914*38fd1498Szrj 
3915*38fd1498Szrj   /* The mode is the mode of the non-constant.  */
3916*38fd1498Szrj   mode = mode0;
3917*38fd1498Szrj   if (mode1 != VOIDmode)
3918*38fd1498Szrj     mode = mode1;
3919*38fd1498Szrj 
3920*38fd1498Szrj   record_jump_cond (code, mode, op0, op1, reversed_nonequality);
3921*38fd1498Szrj }
3922*38fd1498Szrj 
3923*38fd1498Szrj /* Yet another form of subreg creation.  In this case, we want something in
3924*38fd1498Szrj    MODE, and we should assume OP has MODE iff it is naturally modeless.  */
3925*38fd1498Szrj 
3926*38fd1498Szrj static rtx
record_jump_cond_subreg(machine_mode mode,rtx op)3927*38fd1498Szrj record_jump_cond_subreg (machine_mode mode, rtx op)
3928*38fd1498Szrj {
3929*38fd1498Szrj   machine_mode op_mode = GET_MODE (op);
3930*38fd1498Szrj   if (op_mode == mode || op_mode == VOIDmode)
3931*38fd1498Szrj     return op;
3932*38fd1498Szrj   return lowpart_subreg (mode, op, op_mode);
3933*38fd1498Szrj }
3934*38fd1498Szrj 
3935*38fd1498Szrj /* We know that comparison CODE applied to OP0 and OP1 in MODE is true.
3936*38fd1498Szrj    REVERSED_NONEQUALITY is nonzero if CODE had to be swapped.
3937*38fd1498Szrj    Make any useful entries we can with that information.  Called from
3938*38fd1498Szrj    above function and called recursively.  */
3939*38fd1498Szrj 
3940*38fd1498Szrj static void
record_jump_cond(enum rtx_code code,machine_mode mode,rtx op0,rtx op1,int reversed_nonequality)3941*38fd1498Szrj record_jump_cond (enum rtx_code code, machine_mode mode, rtx op0,
3942*38fd1498Szrj 		  rtx op1, int reversed_nonequality)
3943*38fd1498Szrj {
3944*38fd1498Szrj   unsigned op0_hash, op1_hash;
3945*38fd1498Szrj   int op0_in_memory, op1_in_memory;
3946*38fd1498Szrj   struct table_elt *op0_elt, *op1_elt;
3947*38fd1498Szrj 
3948*38fd1498Szrj   /* If OP0 and OP1 are known equal, and either is a paradoxical SUBREG,
3949*38fd1498Szrj      we know that they are also equal in the smaller mode (this is also
3950*38fd1498Szrj      true for all smaller modes whether or not there is a SUBREG, but
3951*38fd1498Szrj      is not worth testing for with no SUBREG).  */
3952*38fd1498Szrj 
3953*38fd1498Szrj   /* Note that GET_MODE (op0) may not equal MODE.  */
3954*38fd1498Szrj   if (code == EQ && paradoxical_subreg_p (op0))
3955*38fd1498Szrj     {
3956*38fd1498Szrj       machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
3957*38fd1498Szrj       rtx tem = record_jump_cond_subreg (inner_mode, op1);
3958*38fd1498Szrj       if (tem)
3959*38fd1498Szrj 	record_jump_cond (code, mode, SUBREG_REG (op0), tem,
3960*38fd1498Szrj 			  reversed_nonequality);
3961*38fd1498Szrj     }
3962*38fd1498Szrj 
3963*38fd1498Szrj   if (code == EQ && paradoxical_subreg_p (op1))
3964*38fd1498Szrj     {
3965*38fd1498Szrj       machine_mode inner_mode = GET_MODE (SUBREG_REG (op1));
3966*38fd1498Szrj       rtx tem = record_jump_cond_subreg (inner_mode, op0);
3967*38fd1498Szrj       if (tem)
3968*38fd1498Szrj 	record_jump_cond (code, mode, SUBREG_REG (op1), tem,
3969*38fd1498Szrj 			  reversed_nonequality);
3970*38fd1498Szrj     }
3971*38fd1498Szrj 
3972*38fd1498Szrj   /* Similarly, if this is an NE comparison, and either is a SUBREG
3973*38fd1498Szrj      making a smaller mode, we know the whole thing is also NE.  */
3974*38fd1498Szrj 
3975*38fd1498Szrj   /* Note that GET_MODE (op0) may not equal MODE;
3976*38fd1498Szrj      if we test MODE instead, we can get an infinite recursion
3977*38fd1498Szrj      alternating between two modes each wider than MODE.  */
3978*38fd1498Szrj 
3979*38fd1498Szrj   if (code == NE
3980*38fd1498Szrj       && partial_subreg_p (op0)
3981*38fd1498Szrj       && subreg_lowpart_p (op0))
3982*38fd1498Szrj     {
3983*38fd1498Szrj       machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
3984*38fd1498Szrj       rtx tem = record_jump_cond_subreg (inner_mode, op1);
3985*38fd1498Szrj       if (tem)
3986*38fd1498Szrj 	record_jump_cond (code, mode, SUBREG_REG (op0), tem,
3987*38fd1498Szrj 			  reversed_nonequality);
3988*38fd1498Szrj     }
3989*38fd1498Szrj 
3990*38fd1498Szrj   if (code == NE
3991*38fd1498Szrj       && partial_subreg_p (op1)
3992*38fd1498Szrj       && subreg_lowpart_p (op1))
3993*38fd1498Szrj     {
3994*38fd1498Szrj       machine_mode inner_mode = GET_MODE (SUBREG_REG (op1));
3995*38fd1498Szrj       rtx tem = record_jump_cond_subreg (inner_mode, op0);
3996*38fd1498Szrj       if (tem)
3997*38fd1498Szrj 	record_jump_cond (code, mode, SUBREG_REG (op1), tem,
3998*38fd1498Szrj 			  reversed_nonequality);
3999*38fd1498Szrj     }
4000*38fd1498Szrj 
4001*38fd1498Szrj   /* Hash both operands.  */
4002*38fd1498Szrj 
4003*38fd1498Szrj   do_not_record = 0;
4004*38fd1498Szrj   hash_arg_in_memory = 0;
4005*38fd1498Szrj   op0_hash = HASH (op0, mode);
4006*38fd1498Szrj   op0_in_memory = hash_arg_in_memory;
4007*38fd1498Szrj 
4008*38fd1498Szrj   if (do_not_record)
4009*38fd1498Szrj     return;
4010*38fd1498Szrj 
4011*38fd1498Szrj   do_not_record = 0;
4012*38fd1498Szrj   hash_arg_in_memory = 0;
4013*38fd1498Szrj   op1_hash = HASH (op1, mode);
4014*38fd1498Szrj   op1_in_memory = hash_arg_in_memory;
4015*38fd1498Szrj 
4016*38fd1498Szrj   if (do_not_record)
4017*38fd1498Szrj     return;
4018*38fd1498Szrj 
4019*38fd1498Szrj   /* Look up both operands.  */
4020*38fd1498Szrj   op0_elt = lookup (op0, op0_hash, mode);
4021*38fd1498Szrj   op1_elt = lookup (op1, op1_hash, mode);
4022*38fd1498Szrj 
4023*38fd1498Szrj   /* If both operands are already equivalent or if they are not in the
4024*38fd1498Szrj      table but are identical, do nothing.  */
4025*38fd1498Szrj   if ((op0_elt != 0 && op1_elt != 0
4026*38fd1498Szrj        && op0_elt->first_same_value == op1_elt->first_same_value)
4027*38fd1498Szrj       || op0 == op1 || rtx_equal_p (op0, op1))
4028*38fd1498Szrj     return;
4029*38fd1498Szrj 
4030*38fd1498Szrj   /* If we aren't setting two things equal all we can do is save this
4031*38fd1498Szrj      comparison.   Similarly if this is floating-point.  In the latter
4032*38fd1498Szrj      case, OP1 might be zero and both -0.0 and 0.0 are equal to it.
4033*38fd1498Szrj      If we record the equality, we might inadvertently delete code
4034*38fd1498Szrj      whose intent was to change -0 to +0.  */
4035*38fd1498Szrj 
4036*38fd1498Szrj   if (code != EQ || FLOAT_MODE_P (GET_MODE (op0)))
4037*38fd1498Szrj     {
4038*38fd1498Szrj       struct qty_table_elem *ent;
4039*38fd1498Szrj       int qty;
4040*38fd1498Szrj 
4041*38fd1498Szrj       /* If we reversed a floating-point comparison, if OP0 is not a
4042*38fd1498Szrj 	 register, or if OP1 is neither a register or constant, we can't
4043*38fd1498Szrj 	 do anything.  */
4044*38fd1498Szrj 
4045*38fd1498Szrj       if (!REG_P (op1))
4046*38fd1498Szrj 	op1 = equiv_constant (op1);
4047*38fd1498Szrj 
4048*38fd1498Szrj       if ((reversed_nonequality && FLOAT_MODE_P (mode))
4049*38fd1498Szrj 	  || !REG_P (op0) || op1 == 0)
4050*38fd1498Szrj 	return;
4051*38fd1498Szrj 
4052*38fd1498Szrj       /* Put OP0 in the hash table if it isn't already.  This gives it a
4053*38fd1498Szrj 	 new quantity number.  */
4054*38fd1498Szrj       if (op0_elt == 0)
4055*38fd1498Szrj 	{
4056*38fd1498Szrj 	  if (insert_regs (op0, NULL, 0))
4057*38fd1498Szrj 	    {
4058*38fd1498Szrj 	      rehash_using_reg (op0);
4059*38fd1498Szrj 	      op0_hash = HASH (op0, mode);
4060*38fd1498Szrj 
4061*38fd1498Szrj 	      /* If OP0 is contained in OP1, this changes its hash code
4062*38fd1498Szrj 		 as well.  Faster to rehash than to check, except
4063*38fd1498Szrj 		 for the simple case of a constant.  */
4064*38fd1498Szrj 	      if (! CONSTANT_P (op1))
4065*38fd1498Szrj 		op1_hash = HASH (op1,mode);
4066*38fd1498Szrj 	    }
4067*38fd1498Szrj 
4068*38fd1498Szrj 	  op0_elt = insert (op0, NULL, op0_hash, mode);
4069*38fd1498Szrj 	  op0_elt->in_memory = op0_in_memory;
4070*38fd1498Szrj 	}
4071*38fd1498Szrj 
4072*38fd1498Szrj       qty = REG_QTY (REGNO (op0));
4073*38fd1498Szrj       ent = &qty_table[qty];
4074*38fd1498Szrj 
4075*38fd1498Szrj       ent->comparison_code = code;
4076*38fd1498Szrj       if (REG_P (op1))
4077*38fd1498Szrj 	{
4078*38fd1498Szrj 	  /* Look it up again--in case op0 and op1 are the same.  */
4079*38fd1498Szrj 	  op1_elt = lookup (op1, op1_hash, mode);
4080*38fd1498Szrj 
4081*38fd1498Szrj 	  /* Put OP1 in the hash table so it gets a new quantity number.  */
4082*38fd1498Szrj 	  if (op1_elt == 0)
4083*38fd1498Szrj 	    {
4084*38fd1498Szrj 	      if (insert_regs (op1, NULL, 0))
4085*38fd1498Szrj 		{
4086*38fd1498Szrj 		  rehash_using_reg (op1);
4087*38fd1498Szrj 		  op1_hash = HASH (op1, mode);
4088*38fd1498Szrj 		}
4089*38fd1498Szrj 
4090*38fd1498Szrj 	      op1_elt = insert (op1, NULL, op1_hash, mode);
4091*38fd1498Szrj 	      op1_elt->in_memory = op1_in_memory;
4092*38fd1498Szrj 	    }
4093*38fd1498Szrj 
4094*38fd1498Szrj 	  ent->comparison_const = NULL_RTX;
4095*38fd1498Szrj 	  ent->comparison_qty = REG_QTY (REGNO (op1));
4096*38fd1498Szrj 	}
4097*38fd1498Szrj       else
4098*38fd1498Szrj 	{
4099*38fd1498Szrj 	  ent->comparison_const = op1;
4100*38fd1498Szrj 	  ent->comparison_qty = -1;
4101*38fd1498Szrj 	}
4102*38fd1498Szrj 
4103*38fd1498Szrj       return;
4104*38fd1498Szrj     }
4105*38fd1498Szrj 
4106*38fd1498Szrj   /* If either side is still missing an equivalence, make it now,
4107*38fd1498Szrj      then merge the equivalences.  */
4108*38fd1498Szrj 
4109*38fd1498Szrj   if (op0_elt == 0)
4110*38fd1498Szrj     {
4111*38fd1498Szrj       if (insert_regs (op0, NULL, 0))
4112*38fd1498Szrj 	{
4113*38fd1498Szrj 	  rehash_using_reg (op0);
4114*38fd1498Szrj 	  op0_hash = HASH (op0, mode);
4115*38fd1498Szrj 	}
4116*38fd1498Szrj 
4117*38fd1498Szrj       op0_elt = insert (op0, NULL, op0_hash, mode);
4118*38fd1498Szrj       op0_elt->in_memory = op0_in_memory;
4119*38fd1498Szrj     }
4120*38fd1498Szrj 
4121*38fd1498Szrj   if (op1_elt == 0)
4122*38fd1498Szrj     {
4123*38fd1498Szrj       if (insert_regs (op1, NULL, 0))
4124*38fd1498Szrj 	{
4125*38fd1498Szrj 	  rehash_using_reg (op1);
4126*38fd1498Szrj 	  op1_hash = HASH (op1, mode);
4127*38fd1498Szrj 	}
4128*38fd1498Szrj 
4129*38fd1498Szrj       op1_elt = insert (op1, NULL, op1_hash, mode);
4130*38fd1498Szrj       op1_elt->in_memory = op1_in_memory;
4131*38fd1498Szrj     }
4132*38fd1498Szrj 
4133*38fd1498Szrj   merge_equiv_classes (op0_elt, op1_elt);
4134*38fd1498Szrj }
4135*38fd1498Szrj 
4136*38fd1498Szrj /* CSE processing for one instruction.
4137*38fd1498Szrj 
4138*38fd1498Szrj    Most "true" common subexpressions are mostly optimized away in GIMPLE,
4139*38fd1498Szrj    but the few that "leak through" are cleaned up by cse_insn, and complex
4140*38fd1498Szrj    addressing modes are often formed here.
4141*38fd1498Szrj 
4142*38fd1498Szrj    The main function is cse_insn, and between here and that function
4143*38fd1498Szrj    a couple of helper functions is defined to keep the size of cse_insn
4144*38fd1498Szrj    within reasonable proportions.
4145*38fd1498Szrj 
4146*38fd1498Szrj    Data is shared between the main and helper functions via STRUCT SET,
4147*38fd1498Szrj    that contains all data related for every set in the instruction that
4148*38fd1498Szrj    is being processed.
4149*38fd1498Szrj 
4150*38fd1498Szrj    Note that cse_main processes all sets in the instruction.  Most
4151*38fd1498Szrj    passes in GCC only process simple SET insns or single_set insns, but
4152*38fd1498Szrj    CSE processes insns with multiple sets as well.  */
4153*38fd1498Szrj 
4154*38fd1498Szrj /* Data on one SET contained in the instruction.  */
4155*38fd1498Szrj 
4156*38fd1498Szrj struct set
4157*38fd1498Szrj {
4158*38fd1498Szrj   /* The SET rtx itself.  */
4159*38fd1498Szrj   rtx rtl;
4160*38fd1498Szrj   /* The SET_SRC of the rtx (the original value, if it is changing).  */
4161*38fd1498Szrj   rtx src;
4162*38fd1498Szrj   /* The hash-table element for the SET_SRC of the SET.  */
4163*38fd1498Szrj   struct table_elt *src_elt;
4164*38fd1498Szrj   /* Hash value for the SET_SRC.  */
4165*38fd1498Szrj   unsigned src_hash;
4166*38fd1498Szrj   /* Hash value for the SET_DEST.  */
4167*38fd1498Szrj   unsigned dest_hash;
4168*38fd1498Szrj   /* The SET_DEST, with SUBREG, etc., stripped.  */
4169*38fd1498Szrj   rtx inner_dest;
4170*38fd1498Szrj   /* Nonzero if the SET_SRC is in memory.  */
4171*38fd1498Szrj   char src_in_memory;
4172*38fd1498Szrj   /* Nonzero if the SET_SRC contains something
4173*38fd1498Szrj      whose value cannot be predicted and understood.  */
4174*38fd1498Szrj   char src_volatile;
4175*38fd1498Szrj   /* Original machine mode, in case it becomes a CONST_INT.
4176*38fd1498Szrj      The size of this field should match the size of the mode
4177*38fd1498Szrj      field of struct rtx_def (see rtl.h).  */
4178*38fd1498Szrj   ENUM_BITFIELD(machine_mode) mode : 8;
4179*38fd1498Szrj   /* Hash value of constant equivalent for SET_SRC.  */
4180*38fd1498Szrj   unsigned src_const_hash;
4181*38fd1498Szrj   /* A constant equivalent for SET_SRC, if any.  */
4182*38fd1498Szrj   rtx src_const;
4183*38fd1498Szrj   /* Table entry for constant equivalent for SET_SRC, if any.  */
4184*38fd1498Szrj   struct table_elt *src_const_elt;
4185*38fd1498Szrj   /* Table entry for the destination address.  */
4186*38fd1498Szrj   struct table_elt *dest_addr_elt;
4187*38fd1498Szrj };
4188*38fd1498Szrj 
4189*38fd1498Szrj /* Special handling for (set REG0 REG1) where REG0 is the
4190*38fd1498Szrj    "cheapest", cheaper than REG1.  After cse, REG1 will probably not
4191*38fd1498Szrj    be used in the sequel, so (if easily done) change this insn to
4192*38fd1498Szrj    (set REG1 REG0) and replace REG1 with REG0 in the previous insn
4193*38fd1498Szrj    that computed their value.  Then REG1 will become a dead store
4194*38fd1498Szrj    and won't cloud the situation for later optimizations.
4195*38fd1498Szrj 
4196*38fd1498Szrj    Do not make this change if REG1 is a hard register, because it will
4197*38fd1498Szrj    then be used in the sequel and we may be changing a two-operand insn
4198*38fd1498Szrj    into a three-operand insn.
4199*38fd1498Szrj 
4200*38fd1498Szrj    This is the last transformation that cse_insn will try to do.  */
4201*38fd1498Szrj 
4202*38fd1498Szrj static void
try_back_substitute_reg(rtx set,rtx_insn * insn)4203*38fd1498Szrj try_back_substitute_reg (rtx set, rtx_insn *insn)
4204*38fd1498Szrj {
4205*38fd1498Szrj   rtx dest = SET_DEST (set);
4206*38fd1498Szrj   rtx src = SET_SRC (set);
4207*38fd1498Szrj 
4208*38fd1498Szrj   if (REG_P (dest)
4209*38fd1498Szrj       && REG_P (src) && ! HARD_REGISTER_P (src)
4210*38fd1498Szrj       && REGNO_QTY_VALID_P (REGNO (src)))
4211*38fd1498Szrj     {
4212*38fd1498Szrj       int src_q = REG_QTY (REGNO (src));
4213*38fd1498Szrj       struct qty_table_elem *src_ent = &qty_table[src_q];
4214*38fd1498Szrj 
4215*38fd1498Szrj       if (src_ent->first_reg == REGNO (dest))
4216*38fd1498Szrj 	{
4217*38fd1498Szrj 	  /* Scan for the previous nonnote insn, but stop at a basic
4218*38fd1498Szrj 	     block boundary.  */
4219*38fd1498Szrj 	  rtx_insn *prev = insn;
4220*38fd1498Szrj 	  rtx_insn *bb_head = BB_HEAD (BLOCK_FOR_INSN (insn));
4221*38fd1498Szrj 	  do
4222*38fd1498Szrj 	    {
4223*38fd1498Szrj 	      prev = PREV_INSN (prev);
4224*38fd1498Szrj 	    }
4225*38fd1498Szrj 	  while (prev != bb_head && (NOTE_P (prev) || DEBUG_INSN_P (prev)));
4226*38fd1498Szrj 
4227*38fd1498Szrj 	  /* Do not swap the registers around if the previous instruction
4228*38fd1498Szrj 	     attaches a REG_EQUIV note to REG1.
4229*38fd1498Szrj 
4230*38fd1498Szrj 	     ??? It's not entirely clear whether we can transfer a REG_EQUIV
4231*38fd1498Szrj 	     from the pseudo that originally shadowed an incoming argument
4232*38fd1498Szrj 	     to another register.  Some uses of REG_EQUIV might rely on it
4233*38fd1498Szrj 	     being attached to REG1 rather than REG2.
4234*38fd1498Szrj 
4235*38fd1498Szrj 	     This section previously turned the REG_EQUIV into a REG_EQUAL
4236*38fd1498Szrj 	     note.  We cannot do that because REG_EQUIV may provide an
4237*38fd1498Szrj 	     uninitialized stack slot when REG_PARM_STACK_SPACE is used.  */
4238*38fd1498Szrj 	  if (NONJUMP_INSN_P (prev)
4239*38fd1498Szrj 	      && GET_CODE (PATTERN (prev)) == SET
4240*38fd1498Szrj 	      && SET_DEST (PATTERN (prev)) == src
4241*38fd1498Szrj 	      && ! find_reg_note (prev, REG_EQUIV, NULL_RTX))
4242*38fd1498Szrj 	    {
4243*38fd1498Szrj 	      rtx note;
4244*38fd1498Szrj 
4245*38fd1498Szrj 	      validate_change (prev, &SET_DEST (PATTERN (prev)), dest, 1);
4246*38fd1498Szrj 	      validate_change (insn, &SET_DEST (set), src, 1);
4247*38fd1498Szrj 	      validate_change (insn, &SET_SRC (set), dest, 1);
4248*38fd1498Szrj 	      apply_change_group ();
4249*38fd1498Szrj 
4250*38fd1498Szrj 	      /* If INSN has a REG_EQUAL note, and this note mentions
4251*38fd1498Szrj 		 REG0, then we must delete it, because the value in
4252*38fd1498Szrj 		 REG0 has changed.  If the note's value is REG1, we must
4253*38fd1498Szrj 		 also delete it because that is now this insn's dest.  */
4254*38fd1498Szrj 	      note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
4255*38fd1498Szrj 	      if (note != 0
4256*38fd1498Szrj 		  && (reg_mentioned_p (dest, XEXP (note, 0))
4257*38fd1498Szrj 		      || rtx_equal_p (src, XEXP (note, 0))))
4258*38fd1498Szrj 		remove_note (insn, note);
4259*38fd1498Szrj 
4260*38fd1498Szrj 	      /* If INSN has a REG_ARGS_SIZE note, move it to PREV.  */
4261*38fd1498Szrj 	      note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
4262*38fd1498Szrj 	      if (note != 0)
4263*38fd1498Szrj 		{
4264*38fd1498Szrj 		  remove_note (insn, note);
4265*38fd1498Szrj 		  gcc_assert (!find_reg_note (prev, REG_ARGS_SIZE, NULL_RTX));
4266*38fd1498Szrj 		  set_unique_reg_note (prev, REG_ARGS_SIZE, XEXP (note, 0));
4267*38fd1498Szrj 		}
4268*38fd1498Szrj 	    }
4269*38fd1498Szrj 	}
4270*38fd1498Szrj     }
4271*38fd1498Szrj }
4272*38fd1498Szrj 
4273*38fd1498Szrj /* Record all the SETs in this instruction into SETS_PTR,
4274*38fd1498Szrj    and return the number of recorded sets.  */
4275*38fd1498Szrj static int
find_sets_in_insn(rtx_insn * insn,struct set ** psets)4276*38fd1498Szrj find_sets_in_insn (rtx_insn *insn, struct set **psets)
4277*38fd1498Szrj {
4278*38fd1498Szrj   struct set *sets = *psets;
4279*38fd1498Szrj   int n_sets = 0;
4280*38fd1498Szrj   rtx x = PATTERN (insn);
4281*38fd1498Szrj 
4282*38fd1498Szrj   if (GET_CODE (x) == SET)
4283*38fd1498Szrj     {
4284*38fd1498Szrj       /* Ignore SETs that are unconditional jumps.
4285*38fd1498Szrj 	 They never need cse processing, so this does not hurt.
4286*38fd1498Szrj 	 The reason is not efficiency but rather
4287*38fd1498Szrj 	 so that we can test at the end for instructions
4288*38fd1498Szrj 	 that have been simplified to unconditional jumps
4289*38fd1498Szrj 	 and not be misled by unchanged instructions
4290*38fd1498Szrj 	 that were unconditional jumps to begin with.  */
4291*38fd1498Szrj       if (SET_DEST (x) == pc_rtx
4292*38fd1498Szrj 	  && GET_CODE (SET_SRC (x)) == LABEL_REF)
4293*38fd1498Szrj 	;
4294*38fd1498Szrj       /* Don't count call-insns, (set (reg 0) (call ...)), as a set.
4295*38fd1498Szrj 	 The hard function value register is used only once, to copy to
4296*38fd1498Szrj 	 someplace else, so it isn't worth cse'ing.  */
4297*38fd1498Szrj       else if (GET_CODE (SET_SRC (x)) == CALL)
4298*38fd1498Szrj 	;
4299*38fd1498Szrj       else
4300*38fd1498Szrj 	sets[n_sets++].rtl = x;
4301*38fd1498Szrj     }
4302*38fd1498Szrj   else if (GET_CODE (x) == PARALLEL)
4303*38fd1498Szrj     {
4304*38fd1498Szrj       int i, lim = XVECLEN (x, 0);
4305*38fd1498Szrj 
4306*38fd1498Szrj       /* Go over the expressions of the PARALLEL in forward order, to
4307*38fd1498Szrj 	 put them in the same order in the SETS array.  */
4308*38fd1498Szrj       for (i = 0; i < lim; i++)
4309*38fd1498Szrj 	{
4310*38fd1498Szrj 	  rtx y = XVECEXP (x, 0, i);
4311*38fd1498Szrj 	  if (GET_CODE (y) == SET)
4312*38fd1498Szrj 	    {
4313*38fd1498Szrj 	      /* As above, we ignore unconditional jumps and call-insns and
4314*38fd1498Szrj 		 ignore the result of apply_change_group.  */
4315*38fd1498Szrj 	      if (SET_DEST (y) == pc_rtx
4316*38fd1498Szrj 		  && GET_CODE (SET_SRC (y)) == LABEL_REF)
4317*38fd1498Szrj 		;
4318*38fd1498Szrj 	      else if (GET_CODE (SET_SRC (y)) == CALL)
4319*38fd1498Szrj 		;
4320*38fd1498Szrj 	      else
4321*38fd1498Szrj 		sets[n_sets++].rtl = y;
4322*38fd1498Szrj 	    }
4323*38fd1498Szrj 	}
4324*38fd1498Szrj     }
4325*38fd1498Szrj 
4326*38fd1498Szrj   return n_sets;
4327*38fd1498Szrj }
4328*38fd1498Szrj 
4329*38fd1498Szrj /* Subroutine of canonicalize_insn.  X is an ASM_OPERANDS in INSN.  */
4330*38fd1498Szrj 
4331*38fd1498Szrj static void
canon_asm_operands(rtx x,rtx_insn * insn)4332*38fd1498Szrj canon_asm_operands (rtx x, rtx_insn *insn)
4333*38fd1498Szrj {
4334*38fd1498Szrj   for (int i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
4335*38fd1498Szrj     {
4336*38fd1498Szrj       rtx input = ASM_OPERANDS_INPUT (x, i);
4337*38fd1498Szrj       if (!(REG_P (input) && HARD_REGISTER_P (input)))
4338*38fd1498Szrj 	{
4339*38fd1498Szrj 	  input = canon_reg (input, insn);
4340*38fd1498Szrj 	  validate_change (insn, &ASM_OPERANDS_INPUT (x, i), input, 1);
4341*38fd1498Szrj 	}
4342*38fd1498Szrj     }
4343*38fd1498Szrj }
4344*38fd1498Szrj 
4345*38fd1498Szrj /* Where possible, substitute every register reference in the N_SETS
4346*38fd1498Szrj    number of SETS in INSN with the canonical register.
4347*38fd1498Szrj 
4348*38fd1498Szrj    Register canonicalization propagatest the earliest register (i.e.
4349*38fd1498Szrj    one that is set before INSN) with the same value.  This is a very
4350*38fd1498Szrj    useful, simple form of CSE, to clean up warts from expanding GIMPLE
4351*38fd1498Szrj    to RTL.  For instance, a CONST for an address is usually expanded
4352*38fd1498Szrj    multiple times to loads into different registers, thus creating many
4353*38fd1498Szrj    subexpressions of the form:
4354*38fd1498Szrj 
4355*38fd1498Szrj    (set (reg1) (some_const))
4356*38fd1498Szrj    (set (mem (... reg1 ...) (thing)))
4357*38fd1498Szrj    (set (reg2) (some_const))
4358*38fd1498Szrj    (set (mem (... reg2 ...) (thing)))
4359*38fd1498Szrj 
4360*38fd1498Szrj    After canonicalizing, the code takes the following form:
4361*38fd1498Szrj 
4362*38fd1498Szrj    (set (reg1) (some_const))
4363*38fd1498Szrj    (set (mem (... reg1 ...) (thing)))
4364*38fd1498Szrj    (set (reg2) (some_const))
4365*38fd1498Szrj    (set (mem (... reg1 ...) (thing)))
4366*38fd1498Szrj 
4367*38fd1498Szrj    The set to reg2 is now trivially dead, and the memory reference (or
4368*38fd1498Szrj    address, or whatever) may be a candidate for further CSEing.
4369*38fd1498Szrj 
4370*38fd1498Szrj    In this function, the result of apply_change_group can be ignored;
4371*38fd1498Szrj    see canon_reg.  */
4372*38fd1498Szrj 
4373*38fd1498Szrj static void
canonicalize_insn(rtx_insn * insn,struct set ** psets,int n_sets)4374*38fd1498Szrj canonicalize_insn (rtx_insn *insn, struct set **psets, int n_sets)
4375*38fd1498Szrj {
4376*38fd1498Szrj   struct set *sets = *psets;
4377*38fd1498Szrj   rtx tem;
4378*38fd1498Szrj   rtx x = PATTERN (insn);
4379*38fd1498Szrj   int i;
4380*38fd1498Szrj 
4381*38fd1498Szrj   if (CALL_P (insn))
4382*38fd1498Szrj     {
4383*38fd1498Szrj       for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4384*38fd1498Szrj 	if (GET_CODE (XEXP (tem, 0)) != SET)
4385*38fd1498Szrj 	  XEXP (tem, 0) = canon_reg (XEXP (tem, 0), insn);
4386*38fd1498Szrj     }
4387*38fd1498Szrj 
4388*38fd1498Szrj   if (GET_CODE (x) == SET && GET_CODE (SET_SRC (x)) == CALL)
4389*38fd1498Szrj     {
4390*38fd1498Szrj       canon_reg (SET_SRC (x), insn);
4391*38fd1498Szrj       apply_change_group ();
4392*38fd1498Szrj       fold_rtx (SET_SRC (x), insn);
4393*38fd1498Szrj     }
4394*38fd1498Szrj   else if (GET_CODE (x) == CLOBBER)
4395*38fd1498Szrj     {
4396*38fd1498Szrj       /* If we clobber memory, canon the address.
4397*38fd1498Szrj 	 This does nothing when a register is clobbered
4398*38fd1498Szrj 	 because we have already invalidated the reg.  */
4399*38fd1498Szrj       if (MEM_P (XEXP (x, 0)))
4400*38fd1498Szrj 	canon_reg (XEXP (x, 0), insn);
4401*38fd1498Szrj     }
4402*38fd1498Szrj   else if (GET_CODE (x) == USE
4403*38fd1498Szrj 	   && ! (REG_P (XEXP (x, 0))
4404*38fd1498Szrj 		 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER))
4405*38fd1498Szrj     /* Canonicalize a USE of a pseudo register or memory location.  */
4406*38fd1498Szrj     canon_reg (x, insn);
4407*38fd1498Szrj   else if (GET_CODE (x) == ASM_OPERANDS)
4408*38fd1498Szrj     canon_asm_operands (x, insn);
4409*38fd1498Szrj   else if (GET_CODE (x) == CALL)
4410*38fd1498Szrj     {
4411*38fd1498Szrj       canon_reg (x, insn);
4412*38fd1498Szrj       apply_change_group ();
4413*38fd1498Szrj       fold_rtx (x, insn);
4414*38fd1498Szrj     }
4415*38fd1498Szrj   else if (DEBUG_INSN_P (insn))
4416*38fd1498Szrj     canon_reg (PATTERN (insn), insn);
4417*38fd1498Szrj   else if (GET_CODE (x) == PARALLEL)
4418*38fd1498Szrj     {
4419*38fd1498Szrj       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
4420*38fd1498Szrj 	{
4421*38fd1498Szrj 	  rtx y = XVECEXP (x, 0, i);
4422*38fd1498Szrj 	  if (GET_CODE (y) == SET && GET_CODE (SET_SRC (y)) == CALL)
4423*38fd1498Szrj 	    {
4424*38fd1498Szrj 	      canon_reg (SET_SRC (y), insn);
4425*38fd1498Szrj 	      apply_change_group ();
4426*38fd1498Szrj 	      fold_rtx (SET_SRC (y), insn);
4427*38fd1498Szrj 	    }
4428*38fd1498Szrj 	  else if (GET_CODE (y) == CLOBBER)
4429*38fd1498Szrj 	    {
4430*38fd1498Szrj 	      if (MEM_P (XEXP (y, 0)))
4431*38fd1498Szrj 		canon_reg (XEXP (y, 0), insn);
4432*38fd1498Szrj 	    }
4433*38fd1498Szrj 	  else if (GET_CODE (y) == USE
4434*38fd1498Szrj 		   && ! (REG_P (XEXP (y, 0))
4435*38fd1498Szrj 			 && REGNO (XEXP (y, 0)) < FIRST_PSEUDO_REGISTER))
4436*38fd1498Szrj 	    canon_reg (y, insn);
4437*38fd1498Szrj 	  else if (GET_CODE (y) == ASM_OPERANDS)
4438*38fd1498Szrj 	    canon_asm_operands (y, insn);
4439*38fd1498Szrj 	  else if (GET_CODE (y) == CALL)
4440*38fd1498Szrj 	    {
4441*38fd1498Szrj 	      canon_reg (y, insn);
4442*38fd1498Szrj 	      apply_change_group ();
4443*38fd1498Szrj 	      fold_rtx (y, insn);
4444*38fd1498Szrj 	    }
4445*38fd1498Szrj 	}
4446*38fd1498Szrj     }
4447*38fd1498Szrj 
4448*38fd1498Szrj   if (n_sets == 1 && REG_NOTES (insn) != 0
4449*38fd1498Szrj       && (tem = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
4450*38fd1498Szrj     {
4451*38fd1498Szrj       /* We potentially will process this insn many times.  Therefore,
4452*38fd1498Szrj 	 drop the REG_EQUAL note if it is equal to the SET_SRC of the
4453*38fd1498Szrj 	 unique set in INSN.
4454*38fd1498Szrj 
4455*38fd1498Szrj 	 Do not do so if the REG_EQUAL note is for a STRICT_LOW_PART,
4456*38fd1498Szrj 	 because cse_insn handles those specially.  */
4457*38fd1498Szrj       if (GET_CODE (SET_DEST (sets[0].rtl)) != STRICT_LOW_PART
4458*38fd1498Szrj 	  && rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl)))
4459*38fd1498Szrj 	remove_note (insn, tem);
4460*38fd1498Szrj       else
4461*38fd1498Szrj 	{
4462*38fd1498Szrj 	  canon_reg (XEXP (tem, 0), insn);
4463*38fd1498Szrj 	  apply_change_group ();
4464*38fd1498Szrj 	  XEXP (tem, 0) = fold_rtx (XEXP (tem, 0), insn);
4465*38fd1498Szrj 	  df_notes_rescan (insn);
4466*38fd1498Szrj 	}
4467*38fd1498Szrj     }
4468*38fd1498Szrj 
4469*38fd1498Szrj   /* Canonicalize sources and addresses of destinations.
4470*38fd1498Szrj      We do this in a separate pass to avoid problems when a MATCH_DUP is
4471*38fd1498Szrj      present in the insn pattern.  In that case, we want to ensure that
4472*38fd1498Szrj      we don't break the duplicate nature of the pattern.  So we will replace
4473*38fd1498Szrj      both operands at the same time.  Otherwise, we would fail to find an
4474*38fd1498Szrj      equivalent substitution in the loop calling validate_change below.
4475*38fd1498Szrj 
4476*38fd1498Szrj      We used to suppress canonicalization of DEST if it appears in SRC,
4477*38fd1498Szrj      but we don't do this any more.  */
4478*38fd1498Szrj 
4479*38fd1498Szrj   for (i = 0; i < n_sets; i++)
4480*38fd1498Szrj     {
4481*38fd1498Szrj       rtx dest = SET_DEST (sets[i].rtl);
4482*38fd1498Szrj       rtx src = SET_SRC (sets[i].rtl);
4483*38fd1498Szrj       rtx new_rtx = canon_reg (src, insn);
4484*38fd1498Szrj 
4485*38fd1498Szrj       validate_change (insn, &SET_SRC (sets[i].rtl), new_rtx, 1);
4486*38fd1498Szrj 
4487*38fd1498Szrj       if (GET_CODE (dest) == ZERO_EXTRACT)
4488*38fd1498Szrj 	{
4489*38fd1498Szrj 	  validate_change (insn, &XEXP (dest, 1),
4490*38fd1498Szrj 			   canon_reg (XEXP (dest, 1), insn), 1);
4491*38fd1498Szrj 	  validate_change (insn, &XEXP (dest, 2),
4492*38fd1498Szrj 			   canon_reg (XEXP (dest, 2), insn), 1);
4493*38fd1498Szrj 	}
4494*38fd1498Szrj 
4495*38fd1498Szrj       while (GET_CODE (dest) == SUBREG
4496*38fd1498Szrj 	     || GET_CODE (dest) == ZERO_EXTRACT
4497*38fd1498Szrj 	     || GET_CODE (dest) == STRICT_LOW_PART)
4498*38fd1498Szrj 	dest = XEXP (dest, 0);
4499*38fd1498Szrj 
4500*38fd1498Szrj       if (MEM_P (dest))
4501*38fd1498Szrj 	canon_reg (dest, insn);
4502*38fd1498Szrj     }
4503*38fd1498Szrj 
4504*38fd1498Szrj   /* Now that we have done all the replacements, we can apply the change
4505*38fd1498Szrj      group and see if they all work.  Note that this will cause some
4506*38fd1498Szrj      canonicalizations that would have worked individually not to be applied
4507*38fd1498Szrj      because some other canonicalization didn't work, but this should not
4508*38fd1498Szrj      occur often.
4509*38fd1498Szrj 
4510*38fd1498Szrj      The result of apply_change_group can be ignored; see canon_reg.  */
4511*38fd1498Szrj 
4512*38fd1498Szrj   apply_change_group ();
4513*38fd1498Szrj }
4514*38fd1498Szrj 
4515*38fd1498Szrj /* Main function of CSE.
4516*38fd1498Szrj    First simplify sources and addresses of all assignments
4517*38fd1498Szrj    in the instruction, using previously-computed equivalents values.
4518*38fd1498Szrj    Then install the new sources and destinations in the table
4519*38fd1498Szrj    of available values.  */
4520*38fd1498Szrj 
4521*38fd1498Szrj static void
cse_insn(rtx_insn * insn)4522*38fd1498Szrj cse_insn (rtx_insn *insn)
4523*38fd1498Szrj {
4524*38fd1498Szrj   rtx x = PATTERN (insn);
4525*38fd1498Szrj   int i;
4526*38fd1498Szrj   rtx tem;
4527*38fd1498Szrj   int n_sets = 0;
4528*38fd1498Szrj 
4529*38fd1498Szrj   rtx src_eqv = 0;
4530*38fd1498Szrj   struct table_elt *src_eqv_elt = 0;
4531*38fd1498Szrj   int src_eqv_volatile = 0;
4532*38fd1498Szrj   int src_eqv_in_memory = 0;
4533*38fd1498Szrj   unsigned src_eqv_hash = 0;
4534*38fd1498Szrj 
4535*38fd1498Szrj   struct set *sets = (struct set *) 0;
4536*38fd1498Szrj 
4537*38fd1498Szrj   if (GET_CODE (x) == SET)
4538*38fd1498Szrj     sets = XALLOCA (struct set);
4539*38fd1498Szrj   else if (GET_CODE (x) == PARALLEL)
4540*38fd1498Szrj     sets = XALLOCAVEC (struct set, XVECLEN (x, 0));
4541*38fd1498Szrj 
4542*38fd1498Szrj   this_insn = insn;
4543*38fd1498Szrj   /* Records what this insn does to set CC0.  */
4544*38fd1498Szrj   this_insn_cc0 = 0;
4545*38fd1498Szrj   this_insn_cc0_mode = VOIDmode;
4546*38fd1498Szrj 
4547*38fd1498Szrj   /* Find all regs explicitly clobbered in this insn,
4548*38fd1498Szrj      to ensure they are not replaced with any other regs
4549*38fd1498Szrj      elsewhere in this insn.  */
4550*38fd1498Szrj   invalidate_from_sets_and_clobbers (insn);
4551*38fd1498Szrj 
4552*38fd1498Szrj   /* Record all the SETs in this instruction.  */
4553*38fd1498Szrj   n_sets = find_sets_in_insn (insn, &sets);
4554*38fd1498Szrj 
4555*38fd1498Szrj   /* Substitute the canonical register where possible.  */
4556*38fd1498Szrj   canonicalize_insn (insn, &sets, n_sets);
4557*38fd1498Szrj 
4558*38fd1498Szrj   /* If this insn has a REG_EQUAL note, store the equivalent value in SRC_EQV,
4559*38fd1498Szrj      if different, or if the DEST is a STRICT_LOW_PART/ZERO_EXTRACT.  The
4560*38fd1498Szrj      latter condition is necessary because SRC_EQV is handled specially for
4561*38fd1498Szrj      this case, and if it isn't set, then there will be no equivalence
4562*38fd1498Szrj      for the destination.  */
4563*38fd1498Szrj   if (n_sets == 1 && REG_NOTES (insn) != 0
4564*38fd1498Szrj       && (tem = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
4565*38fd1498Szrj     {
4566*38fd1498Szrj 
4567*38fd1498Szrj       if (GET_CODE (SET_DEST (sets[0].rtl)) != ZERO_EXTRACT
4568*38fd1498Szrj 	  && (! rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl))
4569*38fd1498Szrj 	      || GET_CODE (SET_DEST (sets[0].rtl)) == STRICT_LOW_PART))
4570*38fd1498Szrj 	src_eqv = copy_rtx (XEXP (tem, 0));
4571*38fd1498Szrj       /* If DEST is of the form ZERO_EXTACT, as in:
4572*38fd1498Szrj 	 (set (zero_extract:SI (reg:SI 119)
4573*38fd1498Szrj 		  (const_int 16 [0x10])
4574*38fd1498Szrj 		  (const_int 16 [0x10]))
4575*38fd1498Szrj 	      (const_int 51154 [0xc7d2]))
4576*38fd1498Szrj 	 REG_EQUAL note will specify the value of register (reg:SI 119) at this
4577*38fd1498Szrj 	 point.  Note that this is different from SRC_EQV. We can however
4578*38fd1498Szrj 	 calculate SRC_EQV with the position and width of ZERO_EXTRACT.  */
4579*38fd1498Szrj       else if (GET_CODE (SET_DEST (sets[0].rtl)) == ZERO_EXTRACT
4580*38fd1498Szrj 	       && CONST_INT_P (XEXP (tem, 0))
4581*38fd1498Szrj 	       && CONST_INT_P (XEXP (SET_DEST (sets[0].rtl), 1))
4582*38fd1498Szrj 	       && CONST_INT_P (XEXP (SET_DEST (sets[0].rtl), 2)))
4583*38fd1498Szrj 	{
4584*38fd1498Szrj 	  rtx dest_reg = XEXP (SET_DEST (sets[0].rtl), 0);
4585*38fd1498Szrj 	  /* This is the mode of XEXP (tem, 0) as well.  */
4586*38fd1498Szrj 	  scalar_int_mode dest_mode
4587*38fd1498Szrj 	    = as_a <scalar_int_mode> (GET_MODE (dest_reg));
4588*38fd1498Szrj 	  rtx width = XEXP (SET_DEST (sets[0].rtl), 1);
4589*38fd1498Szrj 	  rtx pos = XEXP (SET_DEST (sets[0].rtl), 2);
4590*38fd1498Szrj 	  HOST_WIDE_INT val = INTVAL (XEXP (tem, 0));
4591*38fd1498Szrj 	  HOST_WIDE_INT mask;
4592*38fd1498Szrj 	  unsigned int shift;
4593*38fd1498Szrj 	  if (BITS_BIG_ENDIAN)
4594*38fd1498Szrj 	    shift = (GET_MODE_PRECISION (dest_mode)
4595*38fd1498Szrj 		     - INTVAL (pos) - INTVAL (width));
4596*38fd1498Szrj 	  else
4597*38fd1498Szrj 	    shift = INTVAL (pos);
4598*38fd1498Szrj 	  if (INTVAL (width) == HOST_BITS_PER_WIDE_INT)
4599*38fd1498Szrj 	    mask = HOST_WIDE_INT_M1;
4600*38fd1498Szrj 	  else
4601*38fd1498Szrj 	    mask = (HOST_WIDE_INT_1 << INTVAL (width)) - 1;
4602*38fd1498Szrj 	  val = (val >> shift) & mask;
4603*38fd1498Szrj 	  src_eqv = GEN_INT (val);
4604*38fd1498Szrj 	}
4605*38fd1498Szrj     }
4606*38fd1498Szrj 
4607*38fd1498Szrj   /* Set sets[i].src_elt to the class each source belongs to.
4608*38fd1498Szrj      Detect assignments from or to volatile things
4609*38fd1498Szrj      and set set[i] to zero so they will be ignored
4610*38fd1498Szrj      in the rest of this function.
4611*38fd1498Szrj 
4612*38fd1498Szrj      Nothing in this loop changes the hash table or the register chains.  */
4613*38fd1498Szrj 
4614*38fd1498Szrj   for (i = 0; i < n_sets; i++)
4615*38fd1498Szrj     {
4616*38fd1498Szrj       bool repeat = false;
4617*38fd1498Szrj       bool mem_noop_insn = false;
4618*38fd1498Szrj       rtx src, dest;
4619*38fd1498Szrj       rtx src_folded;
4620*38fd1498Szrj       struct table_elt *elt = 0, *p;
4621*38fd1498Szrj       machine_mode mode;
4622*38fd1498Szrj       rtx src_eqv_here;
4623*38fd1498Szrj       rtx src_const = 0;
4624*38fd1498Szrj       rtx src_related = 0;
4625*38fd1498Szrj       bool src_related_is_const_anchor = false;
4626*38fd1498Szrj       struct table_elt *src_const_elt = 0;
4627*38fd1498Szrj       int src_cost = MAX_COST;
4628*38fd1498Szrj       int src_eqv_cost = MAX_COST;
4629*38fd1498Szrj       int src_folded_cost = MAX_COST;
4630*38fd1498Szrj       int src_related_cost = MAX_COST;
4631*38fd1498Szrj       int src_elt_cost = MAX_COST;
4632*38fd1498Szrj       int src_regcost = MAX_COST;
4633*38fd1498Szrj       int src_eqv_regcost = MAX_COST;
4634*38fd1498Szrj       int src_folded_regcost = MAX_COST;
4635*38fd1498Szrj       int src_related_regcost = MAX_COST;
4636*38fd1498Szrj       int src_elt_regcost = MAX_COST;
4637*38fd1498Szrj       /* Set nonzero if we need to call force_const_mem on with the
4638*38fd1498Szrj 	 contents of src_folded before using it.  */
4639*38fd1498Szrj       int src_folded_force_flag = 0;
4640*38fd1498Szrj       scalar_int_mode int_mode;
4641*38fd1498Szrj 
4642*38fd1498Szrj       dest = SET_DEST (sets[i].rtl);
4643*38fd1498Szrj       src = SET_SRC (sets[i].rtl);
4644*38fd1498Szrj 
4645*38fd1498Szrj       /* If SRC is a constant that has no machine mode,
4646*38fd1498Szrj 	 hash it with the destination's machine mode.
4647*38fd1498Szrj 	 This way we can keep different modes separate.  */
4648*38fd1498Szrj 
4649*38fd1498Szrj       mode = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src);
4650*38fd1498Szrj       sets[i].mode = mode;
4651*38fd1498Szrj 
4652*38fd1498Szrj       if (src_eqv)
4653*38fd1498Szrj 	{
4654*38fd1498Szrj 	  machine_mode eqvmode = mode;
4655*38fd1498Szrj 	  if (GET_CODE (dest) == STRICT_LOW_PART)
4656*38fd1498Szrj 	    eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
4657*38fd1498Szrj 	  do_not_record = 0;
4658*38fd1498Szrj 	  hash_arg_in_memory = 0;
4659*38fd1498Szrj 	  src_eqv_hash = HASH (src_eqv, eqvmode);
4660*38fd1498Szrj 
4661*38fd1498Szrj 	  /* Find the equivalence class for the equivalent expression.  */
4662*38fd1498Szrj 
4663*38fd1498Szrj 	  if (!do_not_record)
4664*38fd1498Szrj 	    src_eqv_elt = lookup (src_eqv, src_eqv_hash, eqvmode);
4665*38fd1498Szrj 
4666*38fd1498Szrj 	  src_eqv_volatile = do_not_record;
4667*38fd1498Szrj 	  src_eqv_in_memory = hash_arg_in_memory;
4668*38fd1498Szrj 	}
4669*38fd1498Szrj 
4670*38fd1498Szrj       /* If this is a STRICT_LOW_PART assignment, src_eqv corresponds to the
4671*38fd1498Szrj 	 value of the INNER register, not the destination.  So it is not
4672*38fd1498Szrj 	 a valid substitution for the source.  But save it for later.  */
4673*38fd1498Szrj       if (GET_CODE (dest) == STRICT_LOW_PART)
4674*38fd1498Szrj 	src_eqv_here = 0;
4675*38fd1498Szrj       else
4676*38fd1498Szrj 	src_eqv_here = src_eqv;
4677*38fd1498Szrj 
4678*38fd1498Szrj       /* Simplify and foldable subexpressions in SRC.  Then get the fully-
4679*38fd1498Szrj 	 simplified result, which may not necessarily be valid.  */
4680*38fd1498Szrj       src_folded = fold_rtx (src, NULL);
4681*38fd1498Szrj 
4682*38fd1498Szrj #if 0
4683*38fd1498Szrj       /* ??? This caused bad code to be generated for the m68k port with -O2.
4684*38fd1498Szrj 	 Suppose src is (CONST_INT -1), and that after truncation src_folded
4685*38fd1498Szrj 	 is (CONST_INT 3).  Suppose src_folded is then used for src_const.
4686*38fd1498Szrj 	 At the end we will add src and src_const to the same equivalence
4687*38fd1498Szrj 	 class.  We now have 3 and -1 on the same equivalence class.  This
4688*38fd1498Szrj 	 causes later instructions to be mis-optimized.  */
4689*38fd1498Szrj       /* If storing a constant in a bitfield, pre-truncate the constant
4690*38fd1498Szrj 	 so we will be able to record it later.  */
4691*38fd1498Szrj       if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT)
4692*38fd1498Szrj 	{
4693*38fd1498Szrj 	  rtx width = XEXP (SET_DEST (sets[i].rtl), 1);
4694*38fd1498Szrj 
4695*38fd1498Szrj 	  if (CONST_INT_P (src)
4696*38fd1498Szrj 	      && CONST_INT_P (width)
4697*38fd1498Szrj 	      && INTVAL (width) < HOST_BITS_PER_WIDE_INT
4698*38fd1498Szrj 	      && (INTVAL (src) & ((HOST_WIDE_INT) (-1) << INTVAL (width))))
4699*38fd1498Szrj 	    src_folded
4700*38fd1498Szrj 	      = GEN_INT (INTVAL (src) & ((HOST_WIDE_INT_1
4701*38fd1498Szrj 					  << INTVAL (width)) - 1));
4702*38fd1498Szrj 	}
4703*38fd1498Szrj #endif
4704*38fd1498Szrj 
4705*38fd1498Szrj       /* Compute SRC's hash code, and also notice if it
4706*38fd1498Szrj 	 should not be recorded at all.  In that case,
4707*38fd1498Szrj 	 prevent any further processing of this assignment.  */
4708*38fd1498Szrj       do_not_record = 0;
4709*38fd1498Szrj       hash_arg_in_memory = 0;
4710*38fd1498Szrj 
4711*38fd1498Szrj       sets[i].src = src;
4712*38fd1498Szrj       sets[i].src_hash = HASH (src, mode);
4713*38fd1498Szrj       sets[i].src_volatile = do_not_record;
4714*38fd1498Szrj       sets[i].src_in_memory = hash_arg_in_memory;
4715*38fd1498Szrj 
4716*38fd1498Szrj       /* If SRC is a MEM, there is a REG_EQUIV note for SRC, and DEST is
4717*38fd1498Szrj 	 a pseudo, do not record SRC.  Using SRC as a replacement for
4718*38fd1498Szrj 	 anything else will be incorrect in that situation.  Note that
4719*38fd1498Szrj 	 this usually occurs only for stack slots, in which case all the
4720*38fd1498Szrj 	 RTL would be referring to SRC, so we don't lose any optimization
4721*38fd1498Szrj 	 opportunities by not having SRC in the hash table.  */
4722*38fd1498Szrj 
4723*38fd1498Szrj       if (MEM_P (src)
4724*38fd1498Szrj 	  && find_reg_note (insn, REG_EQUIV, NULL_RTX) != 0
4725*38fd1498Szrj 	  && REG_P (dest)
4726*38fd1498Szrj 	  && REGNO (dest) >= FIRST_PSEUDO_REGISTER)
4727*38fd1498Szrj 	sets[i].src_volatile = 1;
4728*38fd1498Szrj 
4729*38fd1498Szrj       else if (GET_CODE (src) == ASM_OPERANDS
4730*38fd1498Szrj 	       && GET_CODE (x) == PARALLEL)
4731*38fd1498Szrj 	{
4732*38fd1498Szrj 	  /* Do not record result of a non-volatile inline asm with
4733*38fd1498Szrj 	     more than one result.  */
4734*38fd1498Szrj 	  if (n_sets > 1)
4735*38fd1498Szrj 	    sets[i].src_volatile = 1;
4736*38fd1498Szrj 
4737*38fd1498Szrj 	  int j, lim = XVECLEN (x, 0);
4738*38fd1498Szrj 	  for (j = 0; j < lim; j++)
4739*38fd1498Szrj 	    {
4740*38fd1498Szrj 	      rtx y = XVECEXP (x, 0, j);
4741*38fd1498Szrj 	      /* And do not record result of a non-volatile inline asm
4742*38fd1498Szrj 		 with "memory" clobber.  */
4743*38fd1498Szrj 	      if (GET_CODE (y) == CLOBBER && MEM_P (XEXP (y, 0)))
4744*38fd1498Szrj 		{
4745*38fd1498Szrj 		  sets[i].src_volatile = 1;
4746*38fd1498Szrj 		  break;
4747*38fd1498Szrj 		}
4748*38fd1498Szrj 	    }
4749*38fd1498Szrj 	}
4750*38fd1498Szrj 
4751*38fd1498Szrj #if 0
4752*38fd1498Szrj       /* It is no longer clear why we used to do this, but it doesn't
4753*38fd1498Szrj 	 appear to still be needed.  So let's try without it since this
4754*38fd1498Szrj 	 code hurts cse'ing widened ops.  */
4755*38fd1498Szrj       /* If source is a paradoxical subreg (such as QI treated as an SI),
4756*38fd1498Szrj 	 treat it as volatile.  It may do the work of an SI in one context
4757*38fd1498Szrj 	 where the extra bits are not being used, but cannot replace an SI
4758*38fd1498Szrj 	 in general.  */
4759*38fd1498Szrj       if (paradoxical_subreg_p (src))
4760*38fd1498Szrj 	sets[i].src_volatile = 1;
4761*38fd1498Szrj #endif
4762*38fd1498Szrj 
4763*38fd1498Szrj       /* Locate all possible equivalent forms for SRC.  Try to replace
4764*38fd1498Szrj          SRC in the insn with each cheaper equivalent.
4765*38fd1498Szrj 
4766*38fd1498Szrj          We have the following types of equivalents: SRC itself, a folded
4767*38fd1498Szrj          version, a value given in a REG_EQUAL note, or a value related
4768*38fd1498Szrj 	 to a constant.
4769*38fd1498Szrj 
4770*38fd1498Szrj          Each of these equivalents may be part of an additional class
4771*38fd1498Szrj          of equivalents (if more than one is in the table, they must be in
4772*38fd1498Szrj          the same class; we check for this).
4773*38fd1498Szrj 
4774*38fd1498Szrj 	 If the source is volatile, we don't do any table lookups.
4775*38fd1498Szrj 
4776*38fd1498Szrj          We note any constant equivalent for possible later use in a
4777*38fd1498Szrj          REG_NOTE.  */
4778*38fd1498Szrj 
4779*38fd1498Szrj       if (!sets[i].src_volatile)
4780*38fd1498Szrj 	elt = lookup (src, sets[i].src_hash, mode);
4781*38fd1498Szrj 
4782*38fd1498Szrj       sets[i].src_elt = elt;
4783*38fd1498Szrj 
4784*38fd1498Szrj       if (elt && src_eqv_here && src_eqv_elt)
4785*38fd1498Szrj 	{
4786*38fd1498Szrj 	  if (elt->first_same_value != src_eqv_elt->first_same_value)
4787*38fd1498Szrj 	    {
4788*38fd1498Szrj 	      /* The REG_EQUAL is indicating that two formerly distinct
4789*38fd1498Szrj 		 classes are now equivalent.  So merge them.  */
4790*38fd1498Szrj 	      merge_equiv_classes (elt, src_eqv_elt);
4791*38fd1498Szrj 	      src_eqv_hash = HASH (src_eqv, elt->mode);
4792*38fd1498Szrj 	      src_eqv_elt = lookup (src_eqv, src_eqv_hash, elt->mode);
4793*38fd1498Szrj 	    }
4794*38fd1498Szrj 
4795*38fd1498Szrj 	  src_eqv_here = 0;
4796*38fd1498Szrj 	}
4797*38fd1498Szrj 
4798*38fd1498Szrj       else if (src_eqv_elt)
4799*38fd1498Szrj 	elt = src_eqv_elt;
4800*38fd1498Szrj 
4801*38fd1498Szrj       /* Try to find a constant somewhere and record it in `src_const'.
4802*38fd1498Szrj 	 Record its table element, if any, in `src_const_elt'.  Look in
4803*38fd1498Szrj 	 any known equivalences first.  (If the constant is not in the
4804*38fd1498Szrj 	 table, also set `sets[i].src_const_hash').  */
4805*38fd1498Szrj       if (elt)
4806*38fd1498Szrj 	for (p = elt->first_same_value; p; p = p->next_same_value)
4807*38fd1498Szrj 	  if (p->is_const)
4808*38fd1498Szrj 	    {
4809*38fd1498Szrj 	      src_const = p->exp;
4810*38fd1498Szrj 	      src_const_elt = elt;
4811*38fd1498Szrj 	      break;
4812*38fd1498Szrj 	    }
4813*38fd1498Szrj 
4814*38fd1498Szrj       if (src_const == 0
4815*38fd1498Szrj 	  && (CONSTANT_P (src_folded)
4816*38fd1498Szrj 	      /* Consider (minus (label_ref L1) (label_ref L2)) as
4817*38fd1498Szrj 		 "constant" here so we will record it. This allows us
4818*38fd1498Szrj 		 to fold switch statements when an ADDR_DIFF_VEC is used.  */
4819*38fd1498Szrj 	      || (GET_CODE (src_folded) == MINUS
4820*38fd1498Szrj 		  && GET_CODE (XEXP (src_folded, 0)) == LABEL_REF
4821*38fd1498Szrj 		  && GET_CODE (XEXP (src_folded, 1)) == LABEL_REF)))
4822*38fd1498Szrj 	src_const = src_folded, src_const_elt = elt;
4823*38fd1498Szrj       else if (src_const == 0 && src_eqv_here && CONSTANT_P (src_eqv_here))
4824*38fd1498Szrj 	src_const = src_eqv_here, src_const_elt = src_eqv_elt;
4825*38fd1498Szrj 
4826*38fd1498Szrj       /* If we don't know if the constant is in the table, get its
4827*38fd1498Szrj 	 hash code and look it up.  */
4828*38fd1498Szrj       if (src_const && src_const_elt == 0)
4829*38fd1498Szrj 	{
4830*38fd1498Szrj 	  sets[i].src_const_hash = HASH (src_const, mode);
4831*38fd1498Szrj 	  src_const_elt = lookup (src_const, sets[i].src_const_hash, mode);
4832*38fd1498Szrj 	}
4833*38fd1498Szrj 
4834*38fd1498Szrj       sets[i].src_const = src_const;
4835*38fd1498Szrj       sets[i].src_const_elt = src_const_elt;
4836*38fd1498Szrj 
4837*38fd1498Szrj       /* If the constant and our source are both in the table, mark them as
4838*38fd1498Szrj 	 equivalent.  Otherwise, if a constant is in the table but the source
4839*38fd1498Szrj 	 isn't, set ELT to it.  */
4840*38fd1498Szrj       if (src_const_elt && elt
4841*38fd1498Szrj 	  && src_const_elt->first_same_value != elt->first_same_value)
4842*38fd1498Szrj 	merge_equiv_classes (elt, src_const_elt);
4843*38fd1498Szrj       else if (src_const_elt && elt == 0)
4844*38fd1498Szrj 	elt = src_const_elt;
4845*38fd1498Szrj 
4846*38fd1498Szrj       /* See if there is a register linearly related to a constant
4847*38fd1498Szrj          equivalent of SRC.  */
4848*38fd1498Szrj       if (src_const
4849*38fd1498Szrj 	  && (GET_CODE (src_const) == CONST
4850*38fd1498Szrj 	      || (src_const_elt && src_const_elt->related_value != 0)))
4851*38fd1498Szrj 	{
4852*38fd1498Szrj 	  src_related = use_related_value (src_const, src_const_elt);
4853*38fd1498Szrj 	  if (src_related)
4854*38fd1498Szrj 	    {
4855*38fd1498Szrj 	      struct table_elt *src_related_elt
4856*38fd1498Szrj 		= lookup (src_related, HASH (src_related, mode), mode);
4857*38fd1498Szrj 	      if (src_related_elt && elt)
4858*38fd1498Szrj 		{
4859*38fd1498Szrj 		  if (elt->first_same_value
4860*38fd1498Szrj 		      != src_related_elt->first_same_value)
4861*38fd1498Szrj 		    /* This can occur when we previously saw a CONST
4862*38fd1498Szrj 		       involving a SYMBOL_REF and then see the SYMBOL_REF
4863*38fd1498Szrj 		       twice.  Merge the involved classes.  */
4864*38fd1498Szrj 		    merge_equiv_classes (elt, src_related_elt);
4865*38fd1498Szrj 
4866*38fd1498Szrj 		  src_related = 0;
4867*38fd1498Szrj 		  src_related_elt = 0;
4868*38fd1498Szrj 		}
4869*38fd1498Szrj 	      else if (src_related_elt && elt == 0)
4870*38fd1498Szrj 		elt = src_related_elt;
4871*38fd1498Szrj 	    }
4872*38fd1498Szrj 	}
4873*38fd1498Szrj 
4874*38fd1498Szrj       /* See if we have a CONST_INT that is already in a register in a
4875*38fd1498Szrj 	 wider mode.  */
4876*38fd1498Szrj 
4877*38fd1498Szrj       if (src_const && src_related == 0 && CONST_INT_P (src_const)
4878*38fd1498Szrj 	  && is_int_mode (mode, &int_mode)
4879*38fd1498Szrj 	  && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
4880*38fd1498Szrj 	{
4881*38fd1498Szrj 	  opt_scalar_int_mode wider_mode_iter;
4882*38fd1498Szrj 	  FOR_EACH_WIDER_MODE (wider_mode_iter, int_mode)
4883*38fd1498Szrj 	    {
4884*38fd1498Szrj 	      scalar_int_mode wider_mode = wider_mode_iter.require ();
4885*38fd1498Szrj 	      if (GET_MODE_PRECISION (wider_mode) > BITS_PER_WORD)
4886*38fd1498Szrj 		break;
4887*38fd1498Szrj 
4888*38fd1498Szrj 	      struct table_elt *const_elt
4889*38fd1498Szrj 		= lookup (src_const, HASH (src_const, wider_mode), wider_mode);
4890*38fd1498Szrj 
4891*38fd1498Szrj 	      if (const_elt == 0)
4892*38fd1498Szrj 		continue;
4893*38fd1498Szrj 
4894*38fd1498Szrj 	      for (const_elt = const_elt->first_same_value;
4895*38fd1498Szrj 		   const_elt; const_elt = const_elt->next_same_value)
4896*38fd1498Szrj 		if (REG_P (const_elt->exp))
4897*38fd1498Szrj 		  {
4898*38fd1498Szrj 		    src_related = gen_lowpart (int_mode, const_elt->exp);
4899*38fd1498Szrj 		    break;
4900*38fd1498Szrj 		  }
4901*38fd1498Szrj 
4902*38fd1498Szrj 	      if (src_related != 0)
4903*38fd1498Szrj 		break;
4904*38fd1498Szrj 	    }
4905*38fd1498Szrj 	}
4906*38fd1498Szrj 
4907*38fd1498Szrj       /* Another possibility is that we have an AND with a constant in
4908*38fd1498Szrj 	 a mode narrower than a word.  If so, it might have been generated
4909*38fd1498Szrj 	 as part of an "if" which would narrow the AND.  If we already
4910*38fd1498Szrj 	 have done the AND in a wider mode, we can use a SUBREG of that
4911*38fd1498Szrj 	 value.  */
4912*38fd1498Szrj 
4913*38fd1498Szrj       if (flag_expensive_optimizations && ! src_related
4914*38fd1498Szrj 	  && is_a <scalar_int_mode> (mode, &int_mode)
4915*38fd1498Szrj 	  && GET_CODE (src) == AND && CONST_INT_P (XEXP (src, 1))
4916*38fd1498Szrj 	  && GET_MODE_SIZE (int_mode) < UNITS_PER_WORD)
4917*38fd1498Szrj 	{
4918*38fd1498Szrj 	  opt_scalar_int_mode tmode_iter;
4919*38fd1498Szrj 	  rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));
4920*38fd1498Szrj 
4921*38fd1498Szrj 	  FOR_EACH_WIDER_MODE (tmode_iter, int_mode)
4922*38fd1498Szrj 	    {
4923*38fd1498Szrj 	      scalar_int_mode tmode = tmode_iter.require ();
4924*38fd1498Szrj 	      if (GET_MODE_SIZE (tmode) > UNITS_PER_WORD)
4925*38fd1498Szrj 		break;
4926*38fd1498Szrj 
4927*38fd1498Szrj 	      rtx inner = gen_lowpart (tmode, XEXP (src, 0));
4928*38fd1498Szrj 	      struct table_elt *larger_elt;
4929*38fd1498Szrj 
4930*38fd1498Szrj 	      if (inner)
4931*38fd1498Szrj 		{
4932*38fd1498Szrj 		  PUT_MODE (new_and, tmode);
4933*38fd1498Szrj 		  XEXP (new_and, 0) = inner;
4934*38fd1498Szrj 		  larger_elt = lookup (new_and, HASH (new_and, tmode), tmode);
4935*38fd1498Szrj 		  if (larger_elt == 0)
4936*38fd1498Szrj 		    continue;
4937*38fd1498Szrj 
4938*38fd1498Szrj 		  for (larger_elt = larger_elt->first_same_value;
4939*38fd1498Szrj 		       larger_elt; larger_elt = larger_elt->next_same_value)
4940*38fd1498Szrj 		    if (REG_P (larger_elt->exp))
4941*38fd1498Szrj 		      {
4942*38fd1498Szrj 			src_related
4943*38fd1498Szrj 			  = gen_lowpart (int_mode, larger_elt->exp);
4944*38fd1498Szrj 			break;
4945*38fd1498Szrj 		      }
4946*38fd1498Szrj 
4947*38fd1498Szrj 		  if (src_related)
4948*38fd1498Szrj 		    break;
4949*38fd1498Szrj 		}
4950*38fd1498Szrj 	    }
4951*38fd1498Szrj 	}
4952*38fd1498Szrj 
4953*38fd1498Szrj       /* See if a MEM has already been loaded with a widening operation;
4954*38fd1498Szrj 	 if it has, we can use a subreg of that.  Many CISC machines
4955*38fd1498Szrj 	 also have such operations, but this is only likely to be
4956*38fd1498Szrj 	 beneficial on these machines.  */
4957*38fd1498Szrj 
4958*38fd1498Szrj       rtx_code extend_op;
4959*38fd1498Szrj       if (flag_expensive_optimizations && src_related == 0
4960*38fd1498Szrj 	  && MEM_P (src) && ! do_not_record
4961*38fd1498Szrj 	  && is_a <scalar_int_mode> (mode, &int_mode)
4962*38fd1498Szrj 	  && (extend_op = load_extend_op (int_mode)) != UNKNOWN)
4963*38fd1498Szrj 	{
4964*38fd1498Szrj 	  struct rtx_def memory_extend_buf;
4965*38fd1498Szrj 	  rtx memory_extend_rtx = &memory_extend_buf;
4966*38fd1498Szrj 
4967*38fd1498Szrj 	  /* Set what we are trying to extend and the operation it might
4968*38fd1498Szrj 	     have been extended with.  */
4969*38fd1498Szrj 	  memset (memory_extend_rtx, 0, sizeof (*memory_extend_rtx));
4970*38fd1498Szrj 	  PUT_CODE (memory_extend_rtx, extend_op);
4971*38fd1498Szrj 	  XEXP (memory_extend_rtx, 0) = src;
4972*38fd1498Szrj 
4973*38fd1498Szrj 	  opt_scalar_int_mode tmode_iter;
4974*38fd1498Szrj 	  FOR_EACH_WIDER_MODE (tmode_iter, int_mode)
4975*38fd1498Szrj 	    {
4976*38fd1498Szrj 	      struct table_elt *larger_elt;
4977*38fd1498Szrj 
4978*38fd1498Szrj 	      scalar_int_mode tmode = tmode_iter.require ();
4979*38fd1498Szrj 	      if (GET_MODE_SIZE (tmode) > UNITS_PER_WORD)
4980*38fd1498Szrj 		break;
4981*38fd1498Szrj 
4982*38fd1498Szrj 	      PUT_MODE (memory_extend_rtx, tmode);
4983*38fd1498Szrj 	      larger_elt = lookup (memory_extend_rtx,
4984*38fd1498Szrj 				   HASH (memory_extend_rtx, tmode), tmode);
4985*38fd1498Szrj 	      if (larger_elt == 0)
4986*38fd1498Szrj 		continue;
4987*38fd1498Szrj 
4988*38fd1498Szrj 	      for (larger_elt = larger_elt->first_same_value;
4989*38fd1498Szrj 		   larger_elt; larger_elt = larger_elt->next_same_value)
4990*38fd1498Szrj 		if (REG_P (larger_elt->exp))
4991*38fd1498Szrj 		  {
4992*38fd1498Szrj 		    src_related = gen_lowpart (int_mode, larger_elt->exp);
4993*38fd1498Szrj 		    break;
4994*38fd1498Szrj 		  }
4995*38fd1498Szrj 
4996*38fd1498Szrj 	      if (src_related)
4997*38fd1498Szrj 		break;
4998*38fd1498Szrj 	    }
4999*38fd1498Szrj 	}
5000*38fd1498Szrj 
5001*38fd1498Szrj       /* Try to express the constant using a register+offset expression
5002*38fd1498Szrj 	 derived from a constant anchor.  */
5003*38fd1498Szrj 
5004*38fd1498Szrj       if (targetm.const_anchor
5005*38fd1498Szrj 	  && !src_related
5006*38fd1498Szrj 	  && src_const
5007*38fd1498Szrj 	  && GET_CODE (src_const) == CONST_INT)
5008*38fd1498Szrj 	{
5009*38fd1498Szrj 	  src_related = try_const_anchors (src_const, mode);
5010*38fd1498Szrj 	  src_related_is_const_anchor = src_related != NULL_RTX;
5011*38fd1498Szrj 	}
5012*38fd1498Szrj 
5013*38fd1498Szrj 
5014*38fd1498Szrj       if (src == src_folded)
5015*38fd1498Szrj 	src_folded = 0;
5016*38fd1498Szrj 
5017*38fd1498Szrj       /* At this point, ELT, if nonzero, points to a class of expressions
5018*38fd1498Szrj          equivalent to the source of this SET and SRC, SRC_EQV, SRC_FOLDED,
5019*38fd1498Szrj 	 and SRC_RELATED, if nonzero, each contain additional equivalent
5020*38fd1498Szrj 	 expressions.  Prune these latter expressions by deleting expressions
5021*38fd1498Szrj 	 already in the equivalence class.
5022*38fd1498Szrj 
5023*38fd1498Szrj 	 Check for an equivalent identical to the destination.  If found,
5024*38fd1498Szrj 	 this is the preferred equivalent since it will likely lead to
5025*38fd1498Szrj 	 elimination of the insn.  Indicate this by placing it in
5026*38fd1498Szrj 	 `src_related'.  */
5027*38fd1498Szrj 
5028*38fd1498Szrj       if (elt)
5029*38fd1498Szrj 	elt = elt->first_same_value;
5030*38fd1498Szrj       for (p = elt; p; p = p->next_same_value)
5031*38fd1498Szrj 	{
5032*38fd1498Szrj 	  enum rtx_code code = GET_CODE (p->exp);
5033*38fd1498Szrj 
5034*38fd1498Szrj 	  /* If the expression is not valid, ignore it.  Then we do not
5035*38fd1498Szrj 	     have to check for validity below.  In most cases, we can use
5036*38fd1498Szrj 	     `rtx_equal_p', since canonicalization has already been done.  */
5037*38fd1498Szrj 	  if (code != REG && ! exp_equiv_p (p->exp, p->exp, 1, false))
5038*38fd1498Szrj 	    continue;
5039*38fd1498Szrj 
5040*38fd1498Szrj 	  /* Also skip paradoxical subregs, unless that's what we're
5041*38fd1498Szrj 	     looking for.  */
5042*38fd1498Szrj 	  if (paradoxical_subreg_p (p->exp)
5043*38fd1498Szrj 	      && ! (src != 0
5044*38fd1498Szrj 		    && GET_CODE (src) == SUBREG
5045*38fd1498Szrj 		    && GET_MODE (src) == GET_MODE (p->exp)
5046*38fd1498Szrj 		    && partial_subreg_p (GET_MODE (SUBREG_REG (src)),
5047*38fd1498Szrj 					 GET_MODE (SUBREG_REG (p->exp)))))
5048*38fd1498Szrj 	    continue;
5049*38fd1498Szrj 
5050*38fd1498Szrj 	  if (src && GET_CODE (src) == code && rtx_equal_p (src, p->exp))
5051*38fd1498Szrj 	    src = 0;
5052*38fd1498Szrj 	  else if (src_folded && GET_CODE (src_folded) == code
5053*38fd1498Szrj 		   && rtx_equal_p (src_folded, p->exp))
5054*38fd1498Szrj 	    src_folded = 0;
5055*38fd1498Szrj 	  else if (src_eqv_here && GET_CODE (src_eqv_here) == code
5056*38fd1498Szrj 		   && rtx_equal_p (src_eqv_here, p->exp))
5057*38fd1498Szrj 	    src_eqv_here = 0;
5058*38fd1498Szrj 	  else if (src_related && GET_CODE (src_related) == code
5059*38fd1498Szrj 		   && rtx_equal_p (src_related, p->exp))
5060*38fd1498Szrj 	    src_related = 0;
5061*38fd1498Szrj 
5062*38fd1498Szrj 	  /* This is the same as the destination of the insns, we want
5063*38fd1498Szrj 	     to prefer it.  Copy it to src_related.  The code below will
5064*38fd1498Szrj 	     then give it a negative cost.  */
5065*38fd1498Szrj 	  if (GET_CODE (dest) == code && rtx_equal_p (p->exp, dest))
5066*38fd1498Szrj 	    src_related = dest;
5067*38fd1498Szrj 	}
5068*38fd1498Szrj 
5069*38fd1498Szrj       /* Find the cheapest valid equivalent, trying all the available
5070*38fd1498Szrj          possibilities.  Prefer items not in the hash table to ones
5071*38fd1498Szrj          that are when they are equal cost.  Note that we can never
5072*38fd1498Szrj          worsen an insn as the current contents will also succeed.
5073*38fd1498Szrj 	 If we find an equivalent identical to the destination, use it as best,
5074*38fd1498Szrj 	 since this insn will probably be eliminated in that case.  */
5075*38fd1498Szrj       if (src)
5076*38fd1498Szrj 	{
5077*38fd1498Szrj 	  if (rtx_equal_p (src, dest))
5078*38fd1498Szrj 	    src_cost = src_regcost = -1;
5079*38fd1498Szrj 	  else
5080*38fd1498Szrj 	    {
5081*38fd1498Szrj 	      src_cost = COST (src, mode);
5082*38fd1498Szrj 	      src_regcost = approx_reg_cost (src);
5083*38fd1498Szrj 	    }
5084*38fd1498Szrj 	}
5085*38fd1498Szrj 
5086*38fd1498Szrj       if (src_eqv_here)
5087*38fd1498Szrj 	{
5088*38fd1498Szrj 	  if (rtx_equal_p (src_eqv_here, dest))
5089*38fd1498Szrj 	    src_eqv_cost = src_eqv_regcost = -1;
5090*38fd1498Szrj 	  else
5091*38fd1498Szrj 	    {
5092*38fd1498Szrj 	      src_eqv_cost = COST (src_eqv_here, mode);
5093*38fd1498Szrj 	      src_eqv_regcost = approx_reg_cost (src_eqv_here);
5094*38fd1498Szrj 	    }
5095*38fd1498Szrj 	}
5096*38fd1498Szrj 
5097*38fd1498Szrj       if (src_folded)
5098*38fd1498Szrj 	{
5099*38fd1498Szrj 	  if (rtx_equal_p (src_folded, dest))
5100*38fd1498Szrj 	    src_folded_cost = src_folded_regcost = -1;
5101*38fd1498Szrj 	  else
5102*38fd1498Szrj 	    {
5103*38fd1498Szrj 	      src_folded_cost = COST (src_folded, mode);
5104*38fd1498Szrj 	      src_folded_regcost = approx_reg_cost (src_folded);
5105*38fd1498Szrj 	    }
5106*38fd1498Szrj 	}
5107*38fd1498Szrj 
5108*38fd1498Szrj       if (src_related)
5109*38fd1498Szrj 	{
5110*38fd1498Szrj 	  if (rtx_equal_p (src_related, dest))
5111*38fd1498Szrj 	    src_related_cost = src_related_regcost = -1;
5112*38fd1498Szrj 	  else
5113*38fd1498Szrj 	    {
5114*38fd1498Szrj 	      src_related_cost = COST (src_related, mode);
5115*38fd1498Szrj 	      src_related_regcost = approx_reg_cost (src_related);
5116*38fd1498Szrj 
5117*38fd1498Szrj 	      /* If a const-anchor is used to synthesize a constant that
5118*38fd1498Szrj 		 normally requires multiple instructions then slightly prefer
5119*38fd1498Szrj 		 it over the original sequence.  These instructions are likely
5120*38fd1498Szrj 		 to become redundant now.  We can't compare against the cost
5121*38fd1498Szrj 		 of src_eqv_here because, on MIPS for example, multi-insn
5122*38fd1498Szrj 		 constants have zero cost; they are assumed to be hoisted from
5123*38fd1498Szrj 		 loops.  */
5124*38fd1498Szrj 	      if (src_related_is_const_anchor
5125*38fd1498Szrj 		  && src_related_cost == src_cost
5126*38fd1498Szrj 		  && src_eqv_here)
5127*38fd1498Szrj 		src_related_cost--;
5128*38fd1498Szrj 	    }
5129*38fd1498Szrj 	}
5130*38fd1498Szrj 
5131*38fd1498Szrj       /* If this was an indirect jump insn, a known label will really be
5132*38fd1498Szrj 	 cheaper even though it looks more expensive.  */
5133*38fd1498Szrj       if (dest == pc_rtx && src_const && GET_CODE (src_const) == LABEL_REF)
5134*38fd1498Szrj 	src_folded = src_const, src_folded_cost = src_folded_regcost = -1;
5135*38fd1498Szrj 
5136*38fd1498Szrj       /* Terminate loop when replacement made.  This must terminate since
5137*38fd1498Szrj          the current contents will be tested and will always be valid.  */
5138*38fd1498Szrj       while (1)
5139*38fd1498Szrj 	{
5140*38fd1498Szrj 	  rtx trial;
5141*38fd1498Szrj 
5142*38fd1498Szrj 	  /* Skip invalid entries.  */
5143*38fd1498Szrj 	  while (elt && !REG_P (elt->exp)
5144*38fd1498Szrj 		 && ! exp_equiv_p (elt->exp, elt->exp, 1, false))
5145*38fd1498Szrj 	    elt = elt->next_same_value;
5146*38fd1498Szrj 
5147*38fd1498Szrj 	  /* A paradoxical subreg would be bad here: it'll be the right
5148*38fd1498Szrj 	     size, but later may be adjusted so that the upper bits aren't
5149*38fd1498Szrj 	     what we want.  So reject it.  */
5150*38fd1498Szrj 	  if (elt != 0
5151*38fd1498Szrj 	      && paradoxical_subreg_p (elt->exp)
5152*38fd1498Szrj 	      /* It is okay, though, if the rtx we're trying to match
5153*38fd1498Szrj 		 will ignore any of the bits we can't predict.  */
5154*38fd1498Szrj 	      && ! (src != 0
5155*38fd1498Szrj 		    && GET_CODE (src) == SUBREG
5156*38fd1498Szrj 		    && GET_MODE (src) == GET_MODE (elt->exp)
5157*38fd1498Szrj 		    && partial_subreg_p (GET_MODE (SUBREG_REG (src)),
5158*38fd1498Szrj 					 GET_MODE (SUBREG_REG (elt->exp)))))
5159*38fd1498Szrj 	    {
5160*38fd1498Szrj 	      elt = elt->next_same_value;
5161*38fd1498Szrj 	      continue;
5162*38fd1498Szrj 	    }
5163*38fd1498Szrj 
5164*38fd1498Szrj 	  if (elt)
5165*38fd1498Szrj 	    {
5166*38fd1498Szrj 	      src_elt_cost = elt->cost;
5167*38fd1498Szrj 	      src_elt_regcost = elt->regcost;
5168*38fd1498Szrj 	    }
5169*38fd1498Szrj 
5170*38fd1498Szrj 	  /* Find cheapest and skip it for the next time.   For items
5171*38fd1498Szrj 	     of equal cost, use this order:
5172*38fd1498Szrj 	     src_folded, src, src_eqv, src_related and hash table entry.  */
5173*38fd1498Szrj 	  if (src_folded
5174*38fd1498Szrj 	      && preferable (src_folded_cost, src_folded_regcost,
5175*38fd1498Szrj 			     src_cost, src_regcost) <= 0
5176*38fd1498Szrj 	      && preferable (src_folded_cost, src_folded_regcost,
5177*38fd1498Szrj 			     src_eqv_cost, src_eqv_regcost) <= 0
5178*38fd1498Szrj 	      && preferable (src_folded_cost, src_folded_regcost,
5179*38fd1498Szrj 			     src_related_cost, src_related_regcost) <= 0
5180*38fd1498Szrj 	      && preferable (src_folded_cost, src_folded_regcost,
5181*38fd1498Szrj 			     src_elt_cost, src_elt_regcost) <= 0)
5182*38fd1498Szrj 	    {
5183*38fd1498Szrj 	      trial = src_folded, src_folded_cost = MAX_COST;
5184*38fd1498Szrj 	      if (src_folded_force_flag)
5185*38fd1498Szrj 		{
5186*38fd1498Szrj 		  rtx forced = force_const_mem (mode, trial);
5187*38fd1498Szrj 		  if (forced)
5188*38fd1498Szrj 		    trial = forced;
5189*38fd1498Szrj 		}
5190*38fd1498Szrj 	    }
5191*38fd1498Szrj 	  else if (src
5192*38fd1498Szrj 		   && preferable (src_cost, src_regcost,
5193*38fd1498Szrj 				  src_eqv_cost, src_eqv_regcost) <= 0
5194*38fd1498Szrj 		   && preferable (src_cost, src_regcost,
5195*38fd1498Szrj 				  src_related_cost, src_related_regcost) <= 0
5196*38fd1498Szrj 		   && preferable (src_cost, src_regcost,
5197*38fd1498Szrj 				  src_elt_cost, src_elt_regcost) <= 0)
5198*38fd1498Szrj 	    trial = src, src_cost = MAX_COST;
5199*38fd1498Szrj 	  else if (src_eqv_here
5200*38fd1498Szrj 		   && preferable (src_eqv_cost, src_eqv_regcost,
5201*38fd1498Szrj 				  src_related_cost, src_related_regcost) <= 0
5202*38fd1498Szrj 		   && preferable (src_eqv_cost, src_eqv_regcost,
5203*38fd1498Szrj 				  src_elt_cost, src_elt_regcost) <= 0)
5204*38fd1498Szrj 	    trial = src_eqv_here, src_eqv_cost = MAX_COST;
5205*38fd1498Szrj 	  else if (src_related
5206*38fd1498Szrj 		   && preferable (src_related_cost, src_related_regcost,
5207*38fd1498Szrj 				  src_elt_cost, src_elt_regcost) <= 0)
5208*38fd1498Szrj 	    trial = src_related, src_related_cost = MAX_COST;
5209*38fd1498Szrj 	  else
5210*38fd1498Szrj 	    {
5211*38fd1498Szrj 	      trial = elt->exp;
5212*38fd1498Szrj 	      elt = elt->next_same_value;
5213*38fd1498Szrj 	      src_elt_cost = MAX_COST;
5214*38fd1498Szrj 	    }
5215*38fd1498Szrj 
5216*38fd1498Szrj 	  /* Avoid creation of overlapping memory moves.  */
5217*38fd1498Szrj 	  if (MEM_P (trial) && MEM_P (dest) && !rtx_equal_p (trial, dest))
5218*38fd1498Szrj 	    {
5219*38fd1498Szrj 	      rtx src, dest;
5220*38fd1498Szrj 
5221*38fd1498Szrj 	      /* BLKmode moves are not handled by cse anyway.  */
5222*38fd1498Szrj 	      if (GET_MODE (trial) == BLKmode)
5223*38fd1498Szrj 		break;
5224*38fd1498Szrj 
5225*38fd1498Szrj 	      src = canon_rtx (trial);
5226*38fd1498Szrj 	      dest = canon_rtx (SET_DEST (sets[i].rtl));
5227*38fd1498Szrj 
5228*38fd1498Szrj 	      if (!MEM_P (src) || !MEM_P (dest)
5229*38fd1498Szrj 		  || !nonoverlapping_memrefs_p (src, dest, false))
5230*38fd1498Szrj 		break;
5231*38fd1498Szrj 	    }
5232*38fd1498Szrj 
5233*38fd1498Szrj 	  /* Try to optimize
5234*38fd1498Szrj 	     (set (reg:M N) (const_int A))
5235*38fd1498Szrj 	     (set (reg:M2 O) (const_int B))
5236*38fd1498Szrj 	     (set (zero_extract:M2 (reg:M N) (const_int C) (const_int D))
5237*38fd1498Szrj 		  (reg:M2 O)).  */
5238*38fd1498Szrj 	  if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT
5239*38fd1498Szrj 	      && CONST_INT_P (trial)
5240*38fd1498Szrj 	      && CONST_INT_P (XEXP (SET_DEST (sets[i].rtl), 1))
5241*38fd1498Szrj 	      && CONST_INT_P (XEXP (SET_DEST (sets[i].rtl), 2))
5242*38fd1498Szrj 	      && REG_P (XEXP (SET_DEST (sets[i].rtl), 0))
5243*38fd1498Szrj 	      && (known_ge
5244*38fd1498Szrj 		  (GET_MODE_PRECISION (GET_MODE (SET_DEST (sets[i].rtl))),
5245*38fd1498Szrj 		   INTVAL (XEXP (SET_DEST (sets[i].rtl), 1))))
5246*38fd1498Szrj 	      && ((unsigned) INTVAL (XEXP (SET_DEST (sets[i].rtl), 1))
5247*38fd1498Szrj 		  + (unsigned) INTVAL (XEXP (SET_DEST (sets[i].rtl), 2))
5248*38fd1498Szrj 		  <= HOST_BITS_PER_WIDE_INT))
5249*38fd1498Szrj 	    {
5250*38fd1498Szrj 	      rtx dest_reg = XEXP (SET_DEST (sets[i].rtl), 0);
5251*38fd1498Szrj 	      rtx width = XEXP (SET_DEST (sets[i].rtl), 1);
5252*38fd1498Szrj 	      rtx pos = XEXP (SET_DEST (sets[i].rtl), 2);
5253*38fd1498Szrj 	      unsigned int dest_hash = HASH (dest_reg, GET_MODE (dest_reg));
5254*38fd1498Szrj 	      struct table_elt *dest_elt
5255*38fd1498Szrj 		= lookup (dest_reg, dest_hash, GET_MODE (dest_reg));
5256*38fd1498Szrj 	      rtx dest_cst = NULL;
5257*38fd1498Szrj 
5258*38fd1498Szrj 	      if (dest_elt)
5259*38fd1498Szrj 		for (p = dest_elt->first_same_value; p; p = p->next_same_value)
5260*38fd1498Szrj 		  if (p->is_const && CONST_INT_P (p->exp))
5261*38fd1498Szrj 		    {
5262*38fd1498Szrj 		      dest_cst = p->exp;
5263*38fd1498Szrj 		      break;
5264*38fd1498Szrj 		    }
5265*38fd1498Szrj 	      if (dest_cst)
5266*38fd1498Szrj 		{
5267*38fd1498Szrj 		  HOST_WIDE_INT val = INTVAL (dest_cst);
5268*38fd1498Szrj 		  HOST_WIDE_INT mask;
5269*38fd1498Szrj 		  unsigned int shift;
5270*38fd1498Szrj 		  /* This is the mode of DEST_CST as well.  */
5271*38fd1498Szrj 		  scalar_int_mode dest_mode
5272*38fd1498Szrj 		    = as_a <scalar_int_mode> (GET_MODE (dest_reg));
5273*38fd1498Szrj 		  if (BITS_BIG_ENDIAN)
5274*38fd1498Szrj 		    shift = GET_MODE_PRECISION (dest_mode)
5275*38fd1498Szrj 			    - INTVAL (pos) - INTVAL (width);
5276*38fd1498Szrj 		  else
5277*38fd1498Szrj 		    shift = INTVAL (pos);
5278*38fd1498Szrj 		  if (INTVAL (width) == HOST_BITS_PER_WIDE_INT)
5279*38fd1498Szrj 		    mask = HOST_WIDE_INT_M1;
5280*38fd1498Szrj 		  else
5281*38fd1498Szrj 		    mask = (HOST_WIDE_INT_1 << INTVAL (width)) - 1;
5282*38fd1498Szrj 		  val &= ~(mask << shift);
5283*38fd1498Szrj 		  val |= (INTVAL (trial) & mask) << shift;
5284*38fd1498Szrj 		  val = trunc_int_for_mode (val, dest_mode);
5285*38fd1498Szrj 		  validate_unshare_change (insn, &SET_DEST (sets[i].rtl),
5286*38fd1498Szrj 					   dest_reg, 1);
5287*38fd1498Szrj 		  validate_unshare_change (insn, &SET_SRC (sets[i].rtl),
5288*38fd1498Szrj 					   GEN_INT (val), 1);
5289*38fd1498Szrj 		  if (apply_change_group ())
5290*38fd1498Szrj 		    {
5291*38fd1498Szrj 		      rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
5292*38fd1498Szrj 		      if (note)
5293*38fd1498Szrj 			{
5294*38fd1498Szrj 			  remove_note (insn, note);
5295*38fd1498Szrj 			  df_notes_rescan (insn);
5296*38fd1498Szrj 			}
5297*38fd1498Szrj 		      src_eqv = NULL_RTX;
5298*38fd1498Szrj 		      src_eqv_elt = NULL;
5299*38fd1498Szrj 		      src_eqv_volatile = 0;
5300*38fd1498Szrj 		      src_eqv_in_memory = 0;
5301*38fd1498Szrj 		      src_eqv_hash = 0;
5302*38fd1498Szrj 		      repeat = true;
5303*38fd1498Szrj 		      break;
5304*38fd1498Szrj 		    }
5305*38fd1498Szrj 		}
5306*38fd1498Szrj 	    }
5307*38fd1498Szrj 
5308*38fd1498Szrj 	  /* We don't normally have an insn matching (set (pc) (pc)), so
5309*38fd1498Szrj 	     check for this separately here.  We will delete such an
5310*38fd1498Szrj 	     insn below.
5311*38fd1498Szrj 
5312*38fd1498Szrj 	     For other cases such as a table jump or conditional jump
5313*38fd1498Szrj 	     where we know the ultimate target, go ahead and replace the
5314*38fd1498Szrj 	     operand.  While that may not make a valid insn, we will
5315*38fd1498Szrj 	     reemit the jump below (and also insert any necessary
5316*38fd1498Szrj 	     barriers).  */
5317*38fd1498Szrj 	  if (n_sets == 1 && dest == pc_rtx
5318*38fd1498Szrj 	      && (trial == pc_rtx
5319*38fd1498Szrj 		  || (GET_CODE (trial) == LABEL_REF
5320*38fd1498Szrj 		      && ! condjump_p (insn))))
5321*38fd1498Szrj 	    {
5322*38fd1498Szrj 	      /* Don't substitute non-local labels, this confuses CFG.  */
5323*38fd1498Szrj 	      if (GET_CODE (trial) == LABEL_REF
5324*38fd1498Szrj 		  && LABEL_REF_NONLOCAL_P (trial))
5325*38fd1498Szrj 		continue;
5326*38fd1498Szrj 
5327*38fd1498Szrj 	      SET_SRC (sets[i].rtl) = trial;
5328*38fd1498Szrj 	      cse_jumps_altered = true;
5329*38fd1498Szrj 	      break;
5330*38fd1498Szrj 	    }
5331*38fd1498Szrj 
5332*38fd1498Szrj 	  /* Similarly, lots of targets don't allow no-op
5333*38fd1498Szrj 	     (set (mem x) (mem x)) moves.  */
5334*38fd1498Szrj 	  else if (n_sets == 1
5335*38fd1498Szrj 		   && MEM_P (trial)
5336*38fd1498Szrj 		   && MEM_P (dest)
5337*38fd1498Szrj 		   && rtx_equal_p (trial, dest)
5338*38fd1498Szrj 		   && !side_effects_p (dest)
5339*38fd1498Szrj 		   && (cfun->can_delete_dead_exceptions
5340*38fd1498Szrj 		       || insn_nothrow_p (insn)))
5341*38fd1498Szrj 	    {
5342*38fd1498Szrj 	      SET_SRC (sets[i].rtl) = trial;
5343*38fd1498Szrj 	      mem_noop_insn = true;
5344*38fd1498Szrj 	      break;
5345*38fd1498Szrj 	    }
5346*38fd1498Szrj 
5347*38fd1498Szrj 	  /* Reject certain invalid forms of CONST that we create.  */
5348*38fd1498Szrj 	  else if (CONSTANT_P (trial)
5349*38fd1498Szrj 		   && GET_CODE (trial) == CONST
5350*38fd1498Szrj 		   /* Reject cases that will cause decode_rtx_const to
5351*38fd1498Szrj 		      die.  On the alpha when simplifying a switch, we
5352*38fd1498Szrj 		      get (const (truncate (minus (label_ref)
5353*38fd1498Szrj 		      (label_ref)))).  */
5354*38fd1498Szrj 		   && (GET_CODE (XEXP (trial, 0)) == TRUNCATE
5355*38fd1498Szrj 		       /* Likewise on IA-64, except without the
5356*38fd1498Szrj 			  truncate.  */
5357*38fd1498Szrj 		       || (GET_CODE (XEXP (trial, 0)) == MINUS
5358*38fd1498Szrj 			   && GET_CODE (XEXP (XEXP (trial, 0), 0)) == LABEL_REF
5359*38fd1498Szrj 			   && GET_CODE (XEXP (XEXP (trial, 0), 1)) == LABEL_REF)))
5360*38fd1498Szrj 	    /* Do nothing for this case.  */
5361*38fd1498Szrj 	    ;
5362*38fd1498Szrj 
5363*38fd1498Szrj 	  /* Look for a substitution that makes a valid insn.  */
5364*38fd1498Szrj 	  else if (validate_unshare_change (insn, &SET_SRC (sets[i].rtl),
5365*38fd1498Szrj 					    trial, 0))
5366*38fd1498Szrj 	    {
5367*38fd1498Szrj 	      rtx new_rtx = canon_reg (SET_SRC (sets[i].rtl), insn);
5368*38fd1498Szrj 
5369*38fd1498Szrj 	      /* The result of apply_change_group can be ignored; see
5370*38fd1498Szrj 		 canon_reg.  */
5371*38fd1498Szrj 
5372*38fd1498Szrj 	      validate_change (insn, &SET_SRC (sets[i].rtl), new_rtx, 1);
5373*38fd1498Szrj 	      apply_change_group ();
5374*38fd1498Szrj 
5375*38fd1498Szrj 	      break;
5376*38fd1498Szrj 	    }
5377*38fd1498Szrj 
5378*38fd1498Szrj 	  /* If we previously found constant pool entries for
5379*38fd1498Szrj 	     constants and this is a constant, try making a
5380*38fd1498Szrj 	     pool entry.  Put it in src_folded unless we already have done
5381*38fd1498Szrj 	     this since that is where it likely came from.  */
5382*38fd1498Szrj 
5383*38fd1498Szrj 	  else if (constant_pool_entries_cost
5384*38fd1498Szrj 		   && CONSTANT_P (trial)
5385*38fd1498Szrj 		   && (src_folded == 0
5386*38fd1498Szrj 		       || (!MEM_P (src_folded)
5387*38fd1498Szrj 			   && ! src_folded_force_flag))
5388*38fd1498Szrj 		   && GET_MODE_CLASS (mode) != MODE_CC
5389*38fd1498Szrj 		   && mode != VOIDmode)
5390*38fd1498Szrj 	    {
5391*38fd1498Szrj 	      src_folded_force_flag = 1;
5392*38fd1498Szrj 	      src_folded = trial;
5393*38fd1498Szrj 	      src_folded_cost = constant_pool_entries_cost;
5394*38fd1498Szrj 	      src_folded_regcost = constant_pool_entries_regcost;
5395*38fd1498Szrj 	    }
5396*38fd1498Szrj 	}
5397*38fd1498Szrj 
5398*38fd1498Szrj       /* If we changed the insn too much, handle this set from scratch.  */
5399*38fd1498Szrj       if (repeat)
5400*38fd1498Szrj 	{
5401*38fd1498Szrj 	  i--;
5402*38fd1498Szrj 	  continue;
5403*38fd1498Szrj 	}
5404*38fd1498Szrj 
5405*38fd1498Szrj       src = SET_SRC (sets[i].rtl);
5406*38fd1498Szrj 
5407*38fd1498Szrj       /* In general, it is good to have a SET with SET_SRC == SET_DEST.
5408*38fd1498Szrj 	 However, there is an important exception:  If both are registers
5409*38fd1498Szrj 	 that are not the head of their equivalence class, replace SET_SRC
5410*38fd1498Szrj 	 with the head of the class.  If we do not do this, we will have
5411*38fd1498Szrj 	 both registers live over a portion of the basic block.  This way,
5412*38fd1498Szrj 	 their lifetimes will likely abut instead of overlapping.  */
5413*38fd1498Szrj       if (REG_P (dest)
5414*38fd1498Szrj 	  && REGNO_QTY_VALID_P (REGNO (dest)))
5415*38fd1498Szrj 	{
5416*38fd1498Szrj 	  int dest_q = REG_QTY (REGNO (dest));
5417*38fd1498Szrj 	  struct qty_table_elem *dest_ent = &qty_table[dest_q];
5418*38fd1498Szrj 
5419*38fd1498Szrj 	  if (dest_ent->mode == GET_MODE (dest)
5420*38fd1498Szrj 	      && dest_ent->first_reg != REGNO (dest)
5421*38fd1498Szrj 	      && REG_P (src) && REGNO (src) == REGNO (dest)
5422*38fd1498Szrj 	      /* Don't do this if the original insn had a hard reg as
5423*38fd1498Szrj 		 SET_SRC or SET_DEST.  */
5424*38fd1498Szrj 	      && (!REG_P (sets[i].src)
5425*38fd1498Szrj 		  || REGNO (sets[i].src) >= FIRST_PSEUDO_REGISTER)
5426*38fd1498Szrj 	      && (!REG_P (dest) || REGNO (dest) >= FIRST_PSEUDO_REGISTER))
5427*38fd1498Szrj 	    /* We can't call canon_reg here because it won't do anything if
5428*38fd1498Szrj 	       SRC is a hard register.  */
5429*38fd1498Szrj 	    {
5430*38fd1498Szrj 	      int src_q = REG_QTY (REGNO (src));
5431*38fd1498Szrj 	      struct qty_table_elem *src_ent = &qty_table[src_q];
5432*38fd1498Szrj 	      int first = src_ent->first_reg;
5433*38fd1498Szrj 	      rtx new_src
5434*38fd1498Szrj 		= (first >= FIRST_PSEUDO_REGISTER
5435*38fd1498Szrj 		   ? regno_reg_rtx[first] : gen_rtx_REG (GET_MODE (src), first));
5436*38fd1498Szrj 
5437*38fd1498Szrj 	      /* We must use validate-change even for this, because this
5438*38fd1498Szrj 		 might be a special no-op instruction, suitable only to
5439*38fd1498Szrj 		 tag notes onto.  */
5440*38fd1498Szrj 	      if (validate_change (insn, &SET_SRC (sets[i].rtl), new_src, 0))
5441*38fd1498Szrj 		{
5442*38fd1498Szrj 		  src = new_src;
5443*38fd1498Szrj 		  /* If we had a constant that is cheaper than what we are now
5444*38fd1498Szrj 		     setting SRC to, use that constant.  We ignored it when we
5445*38fd1498Szrj 		     thought we could make this into a no-op.  */
5446*38fd1498Szrj 		  if (src_const && COST (src_const, mode) < COST (src, mode)
5447*38fd1498Szrj 		      && validate_change (insn, &SET_SRC (sets[i].rtl),
5448*38fd1498Szrj 					  src_const, 0))
5449*38fd1498Szrj 		    src = src_const;
5450*38fd1498Szrj 		}
5451*38fd1498Szrj 	    }
5452*38fd1498Szrj 	}
5453*38fd1498Szrj 
5454*38fd1498Szrj       /* If we made a change, recompute SRC values.  */
5455*38fd1498Szrj       if (src != sets[i].src)
5456*38fd1498Szrj 	{
5457*38fd1498Szrj 	  do_not_record = 0;
5458*38fd1498Szrj 	  hash_arg_in_memory = 0;
5459*38fd1498Szrj 	  sets[i].src = src;
5460*38fd1498Szrj 	  sets[i].src_hash = HASH (src, mode);
5461*38fd1498Szrj 	  sets[i].src_volatile = do_not_record;
5462*38fd1498Szrj 	  sets[i].src_in_memory = hash_arg_in_memory;
5463*38fd1498Szrj 	  sets[i].src_elt = lookup (src, sets[i].src_hash, mode);
5464*38fd1498Szrj 	}
5465*38fd1498Szrj 
5466*38fd1498Szrj       /* If this is a single SET, we are setting a register, and we have an
5467*38fd1498Szrj 	 equivalent constant, we want to add a REG_EQUAL note if the constant
5468*38fd1498Szrj 	 is different from the source.  We don't want to do it for a constant
5469*38fd1498Szrj 	 pseudo since verifying that this pseudo hasn't been eliminated is a
5470*38fd1498Szrj 	 pain; moreover such a note won't help anything.
5471*38fd1498Szrj 
5472*38fd1498Szrj 	 Avoid a REG_EQUAL note for (CONST (MINUS (LABEL_REF) (LABEL_REF)))
5473*38fd1498Szrj 	 which can be created for a reference to a compile time computable
5474*38fd1498Szrj 	 entry in a jump table.  */
5475*38fd1498Szrj       if (n_sets == 1
5476*38fd1498Szrj 	  && REG_P (dest)
5477*38fd1498Szrj 	  && src_const
5478*38fd1498Szrj 	  && !REG_P (src_const)
5479*38fd1498Szrj 	  && !(GET_CODE (src_const) == SUBREG
5480*38fd1498Szrj 	       && REG_P (SUBREG_REG (src_const)))
5481*38fd1498Szrj 	  && !(GET_CODE (src_const) == CONST
5482*38fd1498Szrj 	       && GET_CODE (XEXP (src_const, 0)) == MINUS
5483*38fd1498Szrj 	       && GET_CODE (XEXP (XEXP (src_const, 0), 0)) == LABEL_REF
5484*38fd1498Szrj 	       && GET_CODE (XEXP (XEXP (src_const, 0), 1)) == LABEL_REF)
5485*38fd1498Szrj 	  && !rtx_equal_p (src, src_const))
5486*38fd1498Szrj 	{
5487*38fd1498Szrj 	  /* Make sure that the rtx is not shared.  */
5488*38fd1498Szrj 	  src_const = copy_rtx (src_const);
5489*38fd1498Szrj 
5490*38fd1498Szrj 	  /* Record the actual constant value in a REG_EQUAL note,
5491*38fd1498Szrj 	     making a new one if one does not already exist.  */
5492*38fd1498Szrj 	  set_unique_reg_note (insn, REG_EQUAL, src_const);
5493*38fd1498Szrj 	  df_notes_rescan (insn);
5494*38fd1498Szrj 	}
5495*38fd1498Szrj 
5496*38fd1498Szrj       /* Now deal with the destination.  */
5497*38fd1498Szrj       do_not_record = 0;
5498*38fd1498Szrj 
5499*38fd1498Szrj       /* Look within any ZERO_EXTRACT to the MEM or REG within it.  */
5500*38fd1498Szrj       while (GET_CODE (dest) == SUBREG
5501*38fd1498Szrj 	     || GET_CODE (dest) == ZERO_EXTRACT
5502*38fd1498Szrj 	     || GET_CODE (dest) == STRICT_LOW_PART)
5503*38fd1498Szrj 	dest = XEXP (dest, 0);
5504*38fd1498Szrj 
5505*38fd1498Szrj       sets[i].inner_dest = dest;
5506*38fd1498Szrj 
5507*38fd1498Szrj       if (MEM_P (dest))
5508*38fd1498Szrj 	{
5509*38fd1498Szrj #ifdef PUSH_ROUNDING
5510*38fd1498Szrj 	  /* Stack pushes invalidate the stack pointer.  */
5511*38fd1498Szrj 	  rtx addr = XEXP (dest, 0);
5512*38fd1498Szrj 	  if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC
5513*38fd1498Szrj 	      && XEXP (addr, 0) == stack_pointer_rtx)
5514*38fd1498Szrj 	    invalidate (stack_pointer_rtx, VOIDmode);
5515*38fd1498Szrj #endif
5516*38fd1498Szrj 	  dest = fold_rtx (dest, insn);
5517*38fd1498Szrj 	}
5518*38fd1498Szrj 
5519*38fd1498Szrj       /* Compute the hash code of the destination now,
5520*38fd1498Szrj 	 before the effects of this instruction are recorded,
5521*38fd1498Szrj 	 since the register values used in the address computation
5522*38fd1498Szrj 	 are those before this instruction.  */
5523*38fd1498Szrj       sets[i].dest_hash = HASH (dest, mode);
5524*38fd1498Szrj 
5525*38fd1498Szrj       /* Don't enter a bit-field in the hash table
5526*38fd1498Szrj 	 because the value in it after the store
5527*38fd1498Szrj 	 may not equal what was stored, due to truncation.  */
5528*38fd1498Szrj 
5529*38fd1498Szrj       if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT)
5530*38fd1498Szrj 	{
5531*38fd1498Szrj 	  rtx width = XEXP (SET_DEST (sets[i].rtl), 1);
5532*38fd1498Szrj 
5533*38fd1498Szrj 	  if (src_const != 0 && CONST_INT_P (src_const)
5534*38fd1498Szrj 	      && CONST_INT_P (width)
5535*38fd1498Szrj 	      && INTVAL (width) < HOST_BITS_PER_WIDE_INT
5536*38fd1498Szrj 	      && ! (INTVAL (src_const)
5537*38fd1498Szrj 		    & (HOST_WIDE_INT_M1U << INTVAL (width))))
5538*38fd1498Szrj 	    /* Exception: if the value is constant,
5539*38fd1498Szrj 	       and it won't be truncated, record it.  */
5540*38fd1498Szrj 	    ;
5541*38fd1498Szrj 	  else
5542*38fd1498Szrj 	    {
5543*38fd1498Szrj 	      /* This is chosen so that the destination will be invalidated
5544*38fd1498Szrj 		 but no new value will be recorded.
5545*38fd1498Szrj 		 We must invalidate because sometimes constant
5546*38fd1498Szrj 		 values can be recorded for bitfields.  */
5547*38fd1498Szrj 	      sets[i].src_elt = 0;
5548*38fd1498Szrj 	      sets[i].src_volatile = 1;
5549*38fd1498Szrj 	      src_eqv = 0;
5550*38fd1498Szrj 	      src_eqv_elt = 0;
5551*38fd1498Szrj 	    }
5552*38fd1498Szrj 	}
5553*38fd1498Szrj 
5554*38fd1498Szrj       /* If only one set in a JUMP_INSN and it is now a no-op, we can delete
5555*38fd1498Szrj 	 the insn.  */
5556*38fd1498Szrj       else if (n_sets == 1 && dest == pc_rtx && src == pc_rtx)
5557*38fd1498Szrj 	{
5558*38fd1498Szrj 	  /* One less use of the label this insn used to jump to.  */
5559*38fd1498Szrj 	  cse_cfg_altered |= delete_insn_and_edges (insn);
5560*38fd1498Szrj 	  cse_jumps_altered = true;
5561*38fd1498Szrj 	  /* No more processing for this set.  */
5562*38fd1498Szrj 	  sets[i].rtl = 0;
5563*38fd1498Szrj 	}
5564*38fd1498Szrj 
5565*38fd1498Szrj       /* Similarly for no-op MEM moves.  */
5566*38fd1498Szrj       else if (mem_noop_insn)
5567*38fd1498Szrj 	{
5568*38fd1498Szrj 	  if (cfun->can_throw_non_call_exceptions && can_throw_internal (insn))
5569*38fd1498Szrj 	    cse_cfg_altered = true;
5570*38fd1498Szrj 	  cse_cfg_altered |= delete_insn_and_edges (insn);
5571*38fd1498Szrj 	  /* No more processing for this set.  */
5572*38fd1498Szrj 	  sets[i].rtl = 0;
5573*38fd1498Szrj 	}
5574*38fd1498Szrj 
5575*38fd1498Szrj       /* If this SET is now setting PC to a label, we know it used to
5576*38fd1498Szrj 	 be a conditional or computed branch.  */
5577*38fd1498Szrj       else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF
5578*38fd1498Szrj 	       && !LABEL_REF_NONLOCAL_P (src))
5579*38fd1498Szrj 	{
5580*38fd1498Szrj 	  /* We reemit the jump in as many cases as possible just in
5581*38fd1498Szrj 	     case the form of an unconditional jump is significantly
5582*38fd1498Szrj 	     different than a computed jump or conditional jump.
5583*38fd1498Szrj 
5584*38fd1498Szrj 	     If this insn has multiple sets, then reemitting the
5585*38fd1498Szrj 	     jump is nontrivial.  So instead we just force rerecognition
5586*38fd1498Szrj 	     and hope for the best.  */
5587*38fd1498Szrj 	  if (n_sets == 1)
5588*38fd1498Szrj 	    {
5589*38fd1498Szrj 	      rtx_jump_insn *new_rtx;
5590*38fd1498Szrj 	      rtx note;
5591*38fd1498Szrj 
5592*38fd1498Szrj 	      rtx_insn *seq = targetm.gen_jump (XEXP (src, 0));
5593*38fd1498Szrj 	      new_rtx = emit_jump_insn_before (seq, insn);
5594*38fd1498Szrj 	      JUMP_LABEL (new_rtx) = XEXP (src, 0);
5595*38fd1498Szrj 	      LABEL_NUSES (XEXP (src, 0))++;
5596*38fd1498Szrj 
5597*38fd1498Szrj 	      /* Make sure to copy over REG_NON_LOCAL_GOTO.  */
5598*38fd1498Szrj 	      note = find_reg_note (insn, REG_NON_LOCAL_GOTO, 0);
5599*38fd1498Szrj 	      if (note)
5600*38fd1498Szrj 		{
5601*38fd1498Szrj 		  XEXP (note, 1) = NULL_RTX;
5602*38fd1498Szrj 		  REG_NOTES (new_rtx) = note;
5603*38fd1498Szrj 		}
5604*38fd1498Szrj 
5605*38fd1498Szrj 	      cse_cfg_altered |= delete_insn_and_edges (insn);
5606*38fd1498Szrj 	      insn = new_rtx;
5607*38fd1498Szrj 	    }
5608*38fd1498Szrj 	  else
5609*38fd1498Szrj 	    INSN_CODE (insn) = -1;
5610*38fd1498Szrj 
5611*38fd1498Szrj 	  /* Do not bother deleting any unreachable code, let jump do it.  */
5612*38fd1498Szrj 	  cse_jumps_altered = true;
5613*38fd1498Szrj 	  sets[i].rtl = 0;
5614*38fd1498Szrj 	}
5615*38fd1498Szrj 
5616*38fd1498Szrj       /* If destination is volatile, invalidate it and then do no further
5617*38fd1498Szrj 	 processing for this assignment.  */
5618*38fd1498Szrj 
5619*38fd1498Szrj       else if (do_not_record)
5620*38fd1498Szrj 	{
5621*38fd1498Szrj 	  invalidate_dest (dest);
5622*38fd1498Szrj 	  sets[i].rtl = 0;
5623*38fd1498Szrj 	}
5624*38fd1498Szrj 
5625*38fd1498Szrj       if (sets[i].rtl != 0 && dest != SET_DEST (sets[i].rtl))
5626*38fd1498Szrj 	{
5627*38fd1498Szrj 	  do_not_record = 0;
5628*38fd1498Szrj 	  sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode);
5629*38fd1498Szrj 	  if (do_not_record)
5630*38fd1498Szrj 	    {
5631*38fd1498Szrj 	      invalidate_dest (SET_DEST (sets[i].rtl));
5632*38fd1498Szrj 	      sets[i].rtl = 0;
5633*38fd1498Szrj 	    }
5634*38fd1498Szrj 	}
5635*38fd1498Szrj 
5636*38fd1498Szrj       /* If setting CC0, record what it was set to, or a constant, if it
5637*38fd1498Szrj 	 is equivalent to a constant.  If it is being set to a floating-point
5638*38fd1498Szrj 	 value, make a COMPARE with the appropriate constant of 0.  If we
5639*38fd1498Szrj 	 don't do this, later code can interpret this as a test against
5640*38fd1498Szrj 	 const0_rtx, which can cause problems if we try to put it into an
5641*38fd1498Szrj 	 insn as a floating-point operand.  */
5642*38fd1498Szrj       if (dest == cc0_rtx)
5643*38fd1498Szrj 	{
5644*38fd1498Szrj 	  this_insn_cc0 = src_const && mode != VOIDmode ? src_const : src;
5645*38fd1498Szrj 	  this_insn_cc0_mode = mode;
5646*38fd1498Szrj 	  if (FLOAT_MODE_P (mode))
5647*38fd1498Szrj 	    this_insn_cc0 = gen_rtx_COMPARE (VOIDmode, this_insn_cc0,
5648*38fd1498Szrj 					     CONST0_RTX (mode));
5649*38fd1498Szrj 	}
5650*38fd1498Szrj     }
5651*38fd1498Szrj 
5652*38fd1498Szrj   /* Now enter all non-volatile source expressions in the hash table
5653*38fd1498Szrj      if they are not already present.
5654*38fd1498Szrj      Record their equivalence classes in src_elt.
5655*38fd1498Szrj      This way we can insert the corresponding destinations into
5656*38fd1498Szrj      the same classes even if the actual sources are no longer in them
5657*38fd1498Szrj      (having been invalidated).  */
5658*38fd1498Szrj 
5659*38fd1498Szrj   if (src_eqv && src_eqv_elt == 0 && sets[0].rtl != 0 && ! src_eqv_volatile
5660*38fd1498Szrj       && ! rtx_equal_p (src_eqv, SET_DEST (sets[0].rtl)))
5661*38fd1498Szrj     {
5662*38fd1498Szrj       struct table_elt *elt;
5663*38fd1498Szrj       struct table_elt *classp = sets[0].src_elt;
5664*38fd1498Szrj       rtx dest = SET_DEST (sets[0].rtl);
5665*38fd1498Szrj       machine_mode eqvmode = GET_MODE (dest);
5666*38fd1498Szrj 
5667*38fd1498Szrj       if (GET_CODE (dest) == STRICT_LOW_PART)
5668*38fd1498Szrj 	{
5669*38fd1498Szrj 	  eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
5670*38fd1498Szrj 	  classp = 0;
5671*38fd1498Szrj 	}
5672*38fd1498Szrj       if (insert_regs (src_eqv, classp, 0))
5673*38fd1498Szrj 	{
5674*38fd1498Szrj 	  rehash_using_reg (src_eqv);
5675*38fd1498Szrj 	  src_eqv_hash = HASH (src_eqv, eqvmode);
5676*38fd1498Szrj 	}
5677*38fd1498Szrj       elt = insert (src_eqv, classp, src_eqv_hash, eqvmode);
5678*38fd1498Szrj       elt->in_memory = src_eqv_in_memory;
5679*38fd1498Szrj       src_eqv_elt = elt;
5680*38fd1498Szrj 
5681*38fd1498Szrj       /* Check to see if src_eqv_elt is the same as a set source which
5682*38fd1498Szrj 	 does not yet have an elt, and if so set the elt of the set source
5683*38fd1498Szrj 	 to src_eqv_elt.  */
5684*38fd1498Szrj       for (i = 0; i < n_sets; i++)
5685*38fd1498Szrj 	if (sets[i].rtl && sets[i].src_elt == 0
5686*38fd1498Szrj 	    && rtx_equal_p (SET_SRC (sets[i].rtl), src_eqv))
5687*38fd1498Szrj 	  sets[i].src_elt = src_eqv_elt;
5688*38fd1498Szrj     }
5689*38fd1498Szrj 
5690*38fd1498Szrj   for (i = 0; i < n_sets; i++)
5691*38fd1498Szrj     if (sets[i].rtl && ! sets[i].src_volatile
5692*38fd1498Szrj 	&& ! rtx_equal_p (SET_SRC (sets[i].rtl), SET_DEST (sets[i].rtl)))
5693*38fd1498Szrj       {
5694*38fd1498Szrj 	if (GET_CODE (SET_DEST (sets[i].rtl)) == STRICT_LOW_PART)
5695*38fd1498Szrj 	  {
5696*38fd1498Szrj 	    /* REG_EQUAL in setting a STRICT_LOW_PART
5697*38fd1498Szrj 	       gives an equivalent for the entire destination register,
5698*38fd1498Szrj 	       not just for the subreg being stored in now.
5699*38fd1498Szrj 	       This is a more interesting equivalence, so we arrange later
5700*38fd1498Szrj 	       to treat the entire reg as the destination.  */
5701*38fd1498Szrj 	    sets[i].src_elt = src_eqv_elt;
5702*38fd1498Szrj 	    sets[i].src_hash = src_eqv_hash;
5703*38fd1498Szrj 	  }
5704*38fd1498Szrj 	else
5705*38fd1498Szrj 	  {
5706*38fd1498Szrj 	    /* Insert source and constant equivalent into hash table, if not
5707*38fd1498Szrj 	       already present.  */
5708*38fd1498Szrj 	    struct table_elt *classp = src_eqv_elt;
5709*38fd1498Szrj 	    rtx src = sets[i].src;
5710*38fd1498Szrj 	    rtx dest = SET_DEST (sets[i].rtl);
5711*38fd1498Szrj 	    machine_mode mode
5712*38fd1498Szrj 	      = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src);
5713*38fd1498Szrj 
5714*38fd1498Szrj 	    /* It's possible that we have a source value known to be
5715*38fd1498Szrj 	       constant but don't have a REG_EQUAL note on the insn.
5716*38fd1498Szrj 	       Lack of a note will mean src_eqv_elt will be NULL.  This
5717*38fd1498Szrj 	       can happen where we've generated a SUBREG to access a
5718*38fd1498Szrj 	       CONST_INT that is already in a register in a wider mode.
5719*38fd1498Szrj 	       Ensure that the source expression is put in the proper
5720*38fd1498Szrj 	       constant class.  */
5721*38fd1498Szrj 	    if (!classp)
5722*38fd1498Szrj 	      classp = sets[i].src_const_elt;
5723*38fd1498Szrj 
5724*38fd1498Szrj 	    if (sets[i].src_elt == 0)
5725*38fd1498Szrj 	      {
5726*38fd1498Szrj 		struct table_elt *elt;
5727*38fd1498Szrj 
5728*38fd1498Szrj 		/* Note that these insert_regs calls cannot remove
5729*38fd1498Szrj 		   any of the src_elt's, because they would have failed to
5730*38fd1498Szrj 		   match if not still valid.  */
5731*38fd1498Szrj 		if (insert_regs (src, classp, 0))
5732*38fd1498Szrj 		  {
5733*38fd1498Szrj 		    rehash_using_reg (src);
5734*38fd1498Szrj 		    sets[i].src_hash = HASH (src, mode);
5735*38fd1498Szrj 		  }
5736*38fd1498Szrj 		elt = insert (src, classp, sets[i].src_hash, mode);
5737*38fd1498Szrj 		elt->in_memory = sets[i].src_in_memory;
5738*38fd1498Szrj 		/* If inline asm has any clobbers, ensure we only reuse
5739*38fd1498Szrj 		   existing inline asms and never try to put the ASM_OPERANDS
5740*38fd1498Szrj 		   into an insn that isn't inline asm.  */
5741*38fd1498Szrj 		if (GET_CODE (src) == ASM_OPERANDS
5742*38fd1498Szrj 		    && GET_CODE (x) == PARALLEL)
5743*38fd1498Szrj 		  elt->cost = MAX_COST;
5744*38fd1498Szrj 		sets[i].src_elt = classp = elt;
5745*38fd1498Szrj 	      }
5746*38fd1498Szrj 	    if (sets[i].src_const && sets[i].src_const_elt == 0
5747*38fd1498Szrj 		&& src != sets[i].src_const
5748*38fd1498Szrj 		&& ! rtx_equal_p (sets[i].src_const, src))
5749*38fd1498Szrj 	      sets[i].src_elt = insert (sets[i].src_const, classp,
5750*38fd1498Szrj 					sets[i].src_const_hash, mode);
5751*38fd1498Szrj 	  }
5752*38fd1498Szrj       }
5753*38fd1498Szrj     else if (sets[i].src_elt == 0)
5754*38fd1498Szrj       /* If we did not insert the source into the hash table (e.g., it was
5755*38fd1498Szrj 	 volatile), note the equivalence class for the REG_EQUAL value, if any,
5756*38fd1498Szrj 	 so that the destination goes into that class.  */
5757*38fd1498Szrj       sets[i].src_elt = src_eqv_elt;
5758*38fd1498Szrj 
5759*38fd1498Szrj   /* Record destination addresses in the hash table.  This allows us to
5760*38fd1498Szrj      check if they are invalidated by other sets.  */
5761*38fd1498Szrj   for (i = 0; i < n_sets; i++)
5762*38fd1498Szrj     {
5763*38fd1498Szrj       if (sets[i].rtl)
5764*38fd1498Szrj 	{
5765*38fd1498Szrj 	  rtx x = sets[i].inner_dest;
5766*38fd1498Szrj 	  struct table_elt *elt;
5767*38fd1498Szrj 	  machine_mode mode;
5768*38fd1498Szrj 	  unsigned hash;
5769*38fd1498Szrj 
5770*38fd1498Szrj 	  if (MEM_P (x))
5771*38fd1498Szrj 	    {
5772*38fd1498Szrj 	      x = XEXP (x, 0);
5773*38fd1498Szrj 	      mode = GET_MODE (x);
5774*38fd1498Szrj 	      hash = HASH (x, mode);
5775*38fd1498Szrj 	      elt = lookup (x, hash, mode);
5776*38fd1498Szrj 	      if (!elt)
5777*38fd1498Szrj 		{
5778*38fd1498Szrj 		  if (insert_regs (x, NULL, 0))
5779*38fd1498Szrj 		    {
5780*38fd1498Szrj 		      rtx dest = SET_DEST (sets[i].rtl);
5781*38fd1498Szrj 
5782*38fd1498Szrj 		      rehash_using_reg (x);
5783*38fd1498Szrj 		      hash = HASH (x, mode);
5784*38fd1498Szrj 		      sets[i].dest_hash = HASH (dest, GET_MODE (dest));
5785*38fd1498Szrj 		    }
5786*38fd1498Szrj 		  elt = insert (x, NULL, hash, mode);
5787*38fd1498Szrj 		}
5788*38fd1498Szrj 
5789*38fd1498Szrj 	      sets[i].dest_addr_elt = elt;
5790*38fd1498Szrj 	    }
5791*38fd1498Szrj 	  else
5792*38fd1498Szrj 	    sets[i].dest_addr_elt = NULL;
5793*38fd1498Szrj 	}
5794*38fd1498Szrj     }
5795*38fd1498Szrj 
5796*38fd1498Szrj   invalidate_from_clobbers (insn);
5797*38fd1498Szrj 
5798*38fd1498Szrj   /* Some registers are invalidated by subroutine calls.  Memory is
5799*38fd1498Szrj      invalidated by non-constant calls.  */
5800*38fd1498Szrj 
5801*38fd1498Szrj   if (CALL_P (insn))
5802*38fd1498Szrj     {
5803*38fd1498Szrj       if (!(RTL_CONST_OR_PURE_CALL_P (insn)))
5804*38fd1498Szrj 	invalidate_memory ();
5805*38fd1498Szrj       else
5806*38fd1498Szrj 	/* For const/pure calls, invalidate any argument slots, because
5807*38fd1498Szrj 	   those are owned by the callee.  */
5808*38fd1498Szrj 	for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
5809*38fd1498Szrj 	  if (GET_CODE (XEXP (tem, 0)) == USE
5810*38fd1498Szrj 	      && MEM_P (XEXP (XEXP (tem, 0), 0)))
5811*38fd1498Szrj 	    invalidate (XEXP (XEXP (tem, 0), 0), VOIDmode);
5812*38fd1498Szrj       invalidate_for_call ();
5813*38fd1498Szrj     }
5814*38fd1498Szrj 
5815*38fd1498Szrj   /* Now invalidate everything set by this instruction.
5816*38fd1498Szrj      If a SUBREG or other funny destination is being set,
5817*38fd1498Szrj      sets[i].rtl is still nonzero, so here we invalidate the reg
5818*38fd1498Szrj      a part of which is being set.  */
5819*38fd1498Szrj 
5820*38fd1498Szrj   for (i = 0; i < n_sets; i++)
5821*38fd1498Szrj     if (sets[i].rtl)
5822*38fd1498Szrj       {
5823*38fd1498Szrj 	/* We can't use the inner dest, because the mode associated with
5824*38fd1498Szrj 	   a ZERO_EXTRACT is significant.  */
5825*38fd1498Szrj 	rtx dest = SET_DEST (sets[i].rtl);
5826*38fd1498Szrj 
5827*38fd1498Szrj 	/* Needed for registers to remove the register from its
5828*38fd1498Szrj 	   previous quantity's chain.
5829*38fd1498Szrj 	   Needed for memory if this is a nonvarying address, unless
5830*38fd1498Szrj 	   we have just done an invalidate_memory that covers even those.  */
5831*38fd1498Szrj 	if (REG_P (dest) || GET_CODE (dest) == SUBREG)
5832*38fd1498Szrj 	  invalidate (dest, VOIDmode);
5833*38fd1498Szrj 	else if (MEM_P (dest))
5834*38fd1498Szrj 	  invalidate (dest, VOIDmode);
5835*38fd1498Szrj 	else if (GET_CODE (dest) == STRICT_LOW_PART
5836*38fd1498Szrj 		 || GET_CODE (dest) == ZERO_EXTRACT)
5837*38fd1498Szrj 	  invalidate (XEXP (dest, 0), GET_MODE (dest));
5838*38fd1498Szrj       }
5839*38fd1498Szrj 
5840*38fd1498Szrj   /* Don't cse over a call to setjmp; on some machines (eg VAX)
5841*38fd1498Szrj      the regs restored by the longjmp come from a later time
5842*38fd1498Szrj      than the setjmp.  */
5843*38fd1498Szrj   if (CALL_P (insn) && find_reg_note (insn, REG_SETJMP, NULL))
5844*38fd1498Szrj     {
5845*38fd1498Szrj       flush_hash_table ();
5846*38fd1498Szrj       goto done;
5847*38fd1498Szrj     }
5848*38fd1498Szrj 
5849*38fd1498Szrj   /* Make sure registers mentioned in destinations
5850*38fd1498Szrj      are safe for use in an expression to be inserted.
5851*38fd1498Szrj      This removes from the hash table
5852*38fd1498Szrj      any invalid entry that refers to one of these registers.
5853*38fd1498Szrj 
5854*38fd1498Szrj      We don't care about the return value from mention_regs because
5855*38fd1498Szrj      we are going to hash the SET_DEST values unconditionally.  */
5856*38fd1498Szrj 
5857*38fd1498Szrj   for (i = 0; i < n_sets; i++)
5858*38fd1498Szrj     {
5859*38fd1498Szrj       if (sets[i].rtl)
5860*38fd1498Szrj 	{
5861*38fd1498Szrj 	  rtx x = SET_DEST (sets[i].rtl);
5862*38fd1498Szrj 
5863*38fd1498Szrj 	  if (!REG_P (x))
5864*38fd1498Szrj 	    mention_regs (x);
5865*38fd1498Szrj 	  else
5866*38fd1498Szrj 	    {
5867*38fd1498Szrj 	      /* We used to rely on all references to a register becoming
5868*38fd1498Szrj 		 inaccessible when a register changes to a new quantity,
5869*38fd1498Szrj 		 since that changes the hash code.  However, that is not
5870*38fd1498Szrj 		 safe, since after HASH_SIZE new quantities we get a
5871*38fd1498Szrj 		 hash 'collision' of a register with its own invalid
5872*38fd1498Szrj 		 entries.  And since SUBREGs have been changed not to
5873*38fd1498Szrj 		 change their hash code with the hash code of the register,
5874*38fd1498Szrj 		 it wouldn't work any longer at all.  So we have to check
5875*38fd1498Szrj 		 for any invalid references lying around now.
5876*38fd1498Szrj 		 This code is similar to the REG case in mention_regs,
5877*38fd1498Szrj 		 but it knows that reg_tick has been incremented, and
5878*38fd1498Szrj 		 it leaves reg_in_table as -1 .  */
5879*38fd1498Szrj 	      unsigned int regno = REGNO (x);
5880*38fd1498Szrj 	      unsigned int endregno = END_REGNO (x);
5881*38fd1498Szrj 	      unsigned int i;
5882*38fd1498Szrj 
5883*38fd1498Szrj 	      for (i = regno; i < endregno; i++)
5884*38fd1498Szrj 		{
5885*38fd1498Szrj 		  if (REG_IN_TABLE (i) >= 0)
5886*38fd1498Szrj 		    {
5887*38fd1498Szrj 		      remove_invalid_refs (i);
5888*38fd1498Szrj 		      REG_IN_TABLE (i) = -1;
5889*38fd1498Szrj 		    }
5890*38fd1498Szrj 		}
5891*38fd1498Szrj 	    }
5892*38fd1498Szrj 	}
5893*38fd1498Szrj     }
5894*38fd1498Szrj 
5895*38fd1498Szrj   /* We may have just removed some of the src_elt's from the hash table.
5896*38fd1498Szrj      So replace each one with the current head of the same class.
5897*38fd1498Szrj      Also check if destination addresses have been removed.  */
5898*38fd1498Szrj 
5899*38fd1498Szrj   for (i = 0; i < n_sets; i++)
5900*38fd1498Szrj     if (sets[i].rtl)
5901*38fd1498Szrj       {
5902*38fd1498Szrj 	if (sets[i].dest_addr_elt
5903*38fd1498Szrj 	    && sets[i].dest_addr_elt->first_same_value == 0)
5904*38fd1498Szrj 	  {
5905*38fd1498Szrj 	    /* The elt was removed, which means this destination is not
5906*38fd1498Szrj 	       valid after this instruction.  */
5907*38fd1498Szrj 	    sets[i].rtl = NULL_RTX;
5908*38fd1498Szrj 	  }
5909*38fd1498Szrj 	else if (sets[i].src_elt && sets[i].src_elt->first_same_value == 0)
5910*38fd1498Szrj 	  /* If elt was removed, find current head of same class,
5911*38fd1498Szrj 	     or 0 if nothing remains of that class.  */
5912*38fd1498Szrj 	  {
5913*38fd1498Szrj 	    struct table_elt *elt = sets[i].src_elt;
5914*38fd1498Szrj 
5915*38fd1498Szrj 	    while (elt && elt->prev_same_value)
5916*38fd1498Szrj 	      elt = elt->prev_same_value;
5917*38fd1498Szrj 
5918*38fd1498Szrj 	    while (elt && elt->first_same_value == 0)
5919*38fd1498Szrj 	      elt = elt->next_same_value;
5920*38fd1498Szrj 	    sets[i].src_elt = elt ? elt->first_same_value : 0;
5921*38fd1498Szrj 	  }
5922*38fd1498Szrj       }
5923*38fd1498Szrj 
5924*38fd1498Szrj   /* Now insert the destinations into their equivalence classes.  */
5925*38fd1498Szrj 
5926*38fd1498Szrj   for (i = 0; i < n_sets; i++)
5927*38fd1498Szrj     if (sets[i].rtl)
5928*38fd1498Szrj       {
5929*38fd1498Szrj 	rtx dest = SET_DEST (sets[i].rtl);
5930*38fd1498Szrj 	struct table_elt *elt;
5931*38fd1498Szrj 
5932*38fd1498Szrj 	/* Don't record value if we are not supposed to risk allocating
5933*38fd1498Szrj 	   floating-point values in registers that might be wider than
5934*38fd1498Szrj 	   memory.  */
5935*38fd1498Szrj 	if ((flag_float_store
5936*38fd1498Szrj 	     && MEM_P (dest)
5937*38fd1498Szrj 	     && FLOAT_MODE_P (GET_MODE (dest)))
5938*38fd1498Szrj 	    /* Don't record BLKmode values, because we don't know the
5939*38fd1498Szrj 	       size of it, and can't be sure that other BLKmode values
5940*38fd1498Szrj 	       have the same or smaller size.  */
5941*38fd1498Szrj 	    || GET_MODE (dest) == BLKmode
5942*38fd1498Szrj 	    /* If we didn't put a REG_EQUAL value or a source into the hash
5943*38fd1498Szrj 	       table, there is no point is recording DEST.  */
5944*38fd1498Szrj 	    || sets[i].src_elt == 0)
5945*38fd1498Szrj 	  continue;
5946*38fd1498Szrj 
5947*38fd1498Szrj 	/* STRICT_LOW_PART isn't part of the value BEING set,
5948*38fd1498Szrj 	   and neither is the SUBREG inside it.
5949*38fd1498Szrj 	   Note that in this case SETS[I].SRC_ELT is really SRC_EQV_ELT.  */
5950*38fd1498Szrj 	if (GET_CODE (dest) == STRICT_LOW_PART)
5951*38fd1498Szrj 	  dest = SUBREG_REG (XEXP (dest, 0));
5952*38fd1498Szrj 
5953*38fd1498Szrj 	if (REG_P (dest) || GET_CODE (dest) == SUBREG)
5954*38fd1498Szrj 	  /* Registers must also be inserted into chains for quantities.  */
5955*38fd1498Szrj 	  if (insert_regs (dest, sets[i].src_elt, 1))
5956*38fd1498Szrj 	    {
5957*38fd1498Szrj 	      /* If `insert_regs' changes something, the hash code must be
5958*38fd1498Szrj 		 recalculated.  */
5959*38fd1498Szrj 	      rehash_using_reg (dest);
5960*38fd1498Szrj 	      sets[i].dest_hash = HASH (dest, GET_MODE (dest));
5961*38fd1498Szrj 	    }
5962*38fd1498Szrj 
5963*38fd1498Szrj 	/* If DEST is a paradoxical SUBREG, don't record DEST since the bits
5964*38fd1498Szrj 	   outside the mode of GET_MODE (SUBREG_REG (dest)) are undefined.  */
5965*38fd1498Szrj 	if (paradoxical_subreg_p (dest))
5966*38fd1498Szrj 	  continue;
5967*38fd1498Szrj 
5968*38fd1498Szrj 	elt = insert (dest, sets[i].src_elt,
5969*38fd1498Szrj 		      sets[i].dest_hash, GET_MODE (dest));
5970*38fd1498Szrj 
5971*38fd1498Szrj 	/* If this is a constant, insert the constant anchors with the
5972*38fd1498Szrj 	   equivalent register-offset expressions using register DEST.  */
5973*38fd1498Szrj 	if (targetm.const_anchor
5974*38fd1498Szrj 	    && REG_P (dest)
5975*38fd1498Szrj 	    && SCALAR_INT_MODE_P (GET_MODE (dest))
5976*38fd1498Szrj 	    && GET_CODE (sets[i].src_elt->exp) == CONST_INT)
5977*38fd1498Szrj 	  insert_const_anchors (dest, sets[i].src_elt->exp, GET_MODE (dest));
5978*38fd1498Szrj 
5979*38fd1498Szrj 	elt->in_memory = (MEM_P (sets[i].inner_dest)
5980*38fd1498Szrj 			  && !MEM_READONLY_P (sets[i].inner_dest));
5981*38fd1498Szrj 
5982*38fd1498Szrj 	/* If we have (set (subreg:m1 (reg:m2 foo) 0) (bar:m1)), M1 is no
5983*38fd1498Szrj 	   narrower than M2, and both M1 and M2 are the same number of words,
5984*38fd1498Szrj 	   we are also doing (set (reg:m2 foo) (subreg:m2 (bar:m1) 0)) so
5985*38fd1498Szrj 	   make that equivalence as well.
5986*38fd1498Szrj 
5987*38fd1498Szrj 	   However, BAR may have equivalences for which gen_lowpart
5988*38fd1498Szrj 	   will produce a simpler value than gen_lowpart applied to
5989*38fd1498Szrj 	   BAR (e.g., if BAR was ZERO_EXTENDed from M2), so we will scan all
5990*38fd1498Szrj 	   BAR's equivalences.  If we don't get a simplified form, make
5991*38fd1498Szrj 	   the SUBREG.  It will not be used in an equivalence, but will
5992*38fd1498Szrj 	   cause two similar assignments to be detected.
5993*38fd1498Szrj 
5994*38fd1498Szrj 	   Note the loop below will find SUBREG_REG (DEST) since we have
5995*38fd1498Szrj 	   already entered SRC and DEST of the SET in the table.  */
5996*38fd1498Szrj 
5997*38fd1498Szrj 	if (GET_CODE (dest) == SUBREG
5998*38fd1498Szrj 	    && (known_equal_after_align_down
5999*38fd1498Szrj 		(GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) - 1,
6000*38fd1498Szrj 		 GET_MODE_SIZE (GET_MODE (dest)) - 1,
6001*38fd1498Szrj 		 UNITS_PER_WORD))
6002*38fd1498Szrj 	    && !partial_subreg_p (dest)
6003*38fd1498Szrj 	    && sets[i].src_elt != 0)
6004*38fd1498Szrj 	  {
6005*38fd1498Szrj 	    machine_mode new_mode = GET_MODE (SUBREG_REG (dest));
6006*38fd1498Szrj 	    struct table_elt *elt, *classp = 0;
6007*38fd1498Szrj 
6008*38fd1498Szrj 	    for (elt = sets[i].src_elt->first_same_value; elt;
6009*38fd1498Szrj 		 elt = elt->next_same_value)
6010*38fd1498Szrj 	      {
6011*38fd1498Szrj 		rtx new_src = 0;
6012*38fd1498Szrj 		unsigned src_hash;
6013*38fd1498Szrj 		struct table_elt *src_elt;
6014*38fd1498Szrj 
6015*38fd1498Szrj 		/* Ignore invalid entries.  */
6016*38fd1498Szrj 		if (!REG_P (elt->exp)
6017*38fd1498Szrj 		    && ! exp_equiv_p (elt->exp, elt->exp, 1, false))
6018*38fd1498Szrj 		  continue;
6019*38fd1498Szrj 
6020*38fd1498Szrj 		/* We may have already been playing subreg games.  If the
6021*38fd1498Szrj 		   mode is already correct for the destination, use it.  */
6022*38fd1498Szrj 		if (GET_MODE (elt->exp) == new_mode)
6023*38fd1498Szrj 		  new_src = elt->exp;
6024*38fd1498Szrj 		else
6025*38fd1498Szrj 		  {
6026*38fd1498Szrj 		    poly_uint64 byte
6027*38fd1498Szrj 		      = subreg_lowpart_offset (new_mode, GET_MODE (dest));
6028*38fd1498Szrj 		    new_src = simplify_gen_subreg (new_mode, elt->exp,
6029*38fd1498Szrj 					           GET_MODE (dest), byte);
6030*38fd1498Szrj 		  }
6031*38fd1498Szrj 
6032*38fd1498Szrj 		/* The call to simplify_gen_subreg fails if the value
6033*38fd1498Szrj 		   is VOIDmode, yet we can't do any simplification, e.g.
6034*38fd1498Szrj 		   for EXPR_LISTs denoting function call results.
6035*38fd1498Szrj 		   It is invalid to construct a SUBREG with a VOIDmode
6036*38fd1498Szrj 		   SUBREG_REG, hence a zero new_src means we can't do
6037*38fd1498Szrj 		   this substitution.  */
6038*38fd1498Szrj 		if (! new_src)
6039*38fd1498Szrj 		  continue;
6040*38fd1498Szrj 
6041*38fd1498Szrj 		src_hash = HASH (new_src, new_mode);
6042*38fd1498Szrj 		src_elt = lookup (new_src, src_hash, new_mode);
6043*38fd1498Szrj 
6044*38fd1498Szrj 		/* Put the new source in the hash table is if isn't
6045*38fd1498Szrj 		   already.  */
6046*38fd1498Szrj 		if (src_elt == 0)
6047*38fd1498Szrj 		  {
6048*38fd1498Szrj 		    if (insert_regs (new_src, classp, 0))
6049*38fd1498Szrj 		      {
6050*38fd1498Szrj 			rehash_using_reg (new_src);
6051*38fd1498Szrj 			src_hash = HASH (new_src, new_mode);
6052*38fd1498Szrj 		      }
6053*38fd1498Szrj 		    src_elt = insert (new_src, classp, src_hash, new_mode);
6054*38fd1498Szrj 		    src_elt->in_memory = elt->in_memory;
6055*38fd1498Szrj 		    if (GET_CODE (new_src) == ASM_OPERANDS
6056*38fd1498Szrj 			&& elt->cost == MAX_COST)
6057*38fd1498Szrj 		      src_elt->cost = MAX_COST;
6058*38fd1498Szrj 		  }
6059*38fd1498Szrj 		else if (classp && classp != src_elt->first_same_value)
6060*38fd1498Szrj 		  /* Show that two things that we've seen before are
6061*38fd1498Szrj 		     actually the same.  */
6062*38fd1498Szrj 		  merge_equiv_classes (src_elt, classp);
6063*38fd1498Szrj 
6064*38fd1498Szrj 		classp = src_elt->first_same_value;
6065*38fd1498Szrj 		/* Ignore invalid entries.  */
6066*38fd1498Szrj 		while (classp
6067*38fd1498Szrj 		       && !REG_P (classp->exp)
6068*38fd1498Szrj 		       && ! exp_equiv_p (classp->exp, classp->exp, 1, false))
6069*38fd1498Szrj 		  classp = classp->next_same_value;
6070*38fd1498Szrj 	      }
6071*38fd1498Szrj 	  }
6072*38fd1498Szrj       }
6073*38fd1498Szrj 
6074*38fd1498Szrj   /* Special handling for (set REG0 REG1) where REG0 is the
6075*38fd1498Szrj      "cheapest", cheaper than REG1.  After cse, REG1 will probably not
6076*38fd1498Szrj      be used in the sequel, so (if easily done) change this insn to
6077*38fd1498Szrj      (set REG1 REG0) and replace REG1 with REG0 in the previous insn
6078*38fd1498Szrj      that computed their value.  Then REG1 will become a dead store
6079*38fd1498Szrj      and won't cloud the situation for later optimizations.
6080*38fd1498Szrj 
6081*38fd1498Szrj      Do not make this change if REG1 is a hard register, because it will
6082*38fd1498Szrj      then be used in the sequel and we may be changing a two-operand insn
6083*38fd1498Szrj      into a three-operand insn.
6084*38fd1498Szrj 
6085*38fd1498Szrj      Also do not do this if we are operating on a copy of INSN.  */
6086*38fd1498Szrj 
6087*38fd1498Szrj   if (n_sets == 1 && sets[0].rtl)
6088*38fd1498Szrj     try_back_substitute_reg (sets[0].rtl, insn);
6089*38fd1498Szrj 
6090*38fd1498Szrj done:;
6091*38fd1498Szrj }
6092*38fd1498Szrj 
6093*38fd1498Szrj /* Remove from the hash table all expressions that reference memory.  */
6094*38fd1498Szrj 
6095*38fd1498Szrj static void
invalidate_memory(void)6096*38fd1498Szrj invalidate_memory (void)
6097*38fd1498Szrj {
6098*38fd1498Szrj   int i;
6099*38fd1498Szrj   struct table_elt *p, *next;
6100*38fd1498Szrj 
6101*38fd1498Szrj   for (i = 0; i < HASH_SIZE; i++)
6102*38fd1498Szrj     for (p = table[i]; p; p = next)
6103*38fd1498Szrj       {
6104*38fd1498Szrj 	next = p->next_same_hash;
6105*38fd1498Szrj 	if (p->in_memory)
6106*38fd1498Szrj 	  remove_from_table (p, i);
6107*38fd1498Szrj       }
6108*38fd1498Szrj }
6109*38fd1498Szrj 
6110*38fd1498Szrj /* Perform invalidation on the basis of everything about INSN,
6111*38fd1498Szrj    except for invalidating the actual places that are SET in it.
6112*38fd1498Szrj    This includes the places CLOBBERed, and anything that might
6113*38fd1498Szrj    alias with something that is SET or CLOBBERed.  */
6114*38fd1498Szrj 
6115*38fd1498Szrj static void
invalidate_from_clobbers(rtx_insn * insn)6116*38fd1498Szrj invalidate_from_clobbers (rtx_insn *insn)
6117*38fd1498Szrj {
6118*38fd1498Szrj   rtx x = PATTERN (insn);
6119*38fd1498Szrj 
6120*38fd1498Szrj   if (GET_CODE (x) == CLOBBER)
6121*38fd1498Szrj     {
6122*38fd1498Szrj       rtx ref = XEXP (x, 0);
6123*38fd1498Szrj       if (ref)
6124*38fd1498Szrj 	{
6125*38fd1498Szrj 	  if (REG_P (ref) || GET_CODE (ref) == SUBREG
6126*38fd1498Szrj 	      || MEM_P (ref))
6127*38fd1498Szrj 	    invalidate (ref, VOIDmode);
6128*38fd1498Szrj 	  else if (GET_CODE (ref) == STRICT_LOW_PART
6129*38fd1498Szrj 		   || GET_CODE (ref) == ZERO_EXTRACT)
6130*38fd1498Szrj 	    invalidate (XEXP (ref, 0), GET_MODE (ref));
6131*38fd1498Szrj 	}
6132*38fd1498Szrj     }
6133*38fd1498Szrj   else if (GET_CODE (x) == PARALLEL)
6134*38fd1498Szrj     {
6135*38fd1498Szrj       int i;
6136*38fd1498Szrj       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
6137*38fd1498Szrj 	{
6138*38fd1498Szrj 	  rtx y = XVECEXP (x, 0, i);
6139*38fd1498Szrj 	  if (GET_CODE (y) == CLOBBER)
6140*38fd1498Szrj 	    {
6141*38fd1498Szrj 	      rtx ref = XEXP (y, 0);
6142*38fd1498Szrj 	      if (REG_P (ref) || GET_CODE (ref) == SUBREG
6143*38fd1498Szrj 		  || MEM_P (ref))
6144*38fd1498Szrj 		invalidate (ref, VOIDmode);
6145*38fd1498Szrj 	      else if (GET_CODE (ref) == STRICT_LOW_PART
6146*38fd1498Szrj 		       || GET_CODE (ref) == ZERO_EXTRACT)
6147*38fd1498Szrj 		invalidate (XEXP (ref, 0), GET_MODE (ref));
6148*38fd1498Szrj 	    }
6149*38fd1498Szrj 	}
6150*38fd1498Szrj     }
6151*38fd1498Szrj }
6152*38fd1498Szrj 
6153*38fd1498Szrj /* Perform invalidation on the basis of everything about INSN.
6154*38fd1498Szrj    This includes the places CLOBBERed, and anything that might
6155*38fd1498Szrj    alias with something that is SET or CLOBBERed.  */
6156*38fd1498Szrj 
6157*38fd1498Szrj static void
invalidate_from_sets_and_clobbers(rtx_insn * insn)6158*38fd1498Szrj invalidate_from_sets_and_clobbers (rtx_insn *insn)
6159*38fd1498Szrj {
6160*38fd1498Szrj   rtx tem;
6161*38fd1498Szrj   rtx x = PATTERN (insn);
6162*38fd1498Szrj 
6163*38fd1498Szrj   if (CALL_P (insn))
6164*38fd1498Szrj     {
6165*38fd1498Szrj       for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
6166*38fd1498Szrj 	if (GET_CODE (XEXP (tem, 0)) == CLOBBER)
6167*38fd1498Szrj 	  invalidate (SET_DEST (XEXP (tem, 0)), VOIDmode);
6168*38fd1498Szrj     }
6169*38fd1498Szrj 
6170*38fd1498Szrj   /* Ensure we invalidate the destination register of a CALL insn.
6171*38fd1498Szrj      This is necessary for machines where this register is a fixed_reg,
6172*38fd1498Szrj      because no other code would invalidate it.  */
6173*38fd1498Szrj   if (GET_CODE (x) == SET && GET_CODE (SET_SRC (x)) == CALL)
6174*38fd1498Szrj     invalidate (SET_DEST (x), VOIDmode);
6175*38fd1498Szrj 
6176*38fd1498Szrj   else if (GET_CODE (x) == PARALLEL)
6177*38fd1498Szrj     {
6178*38fd1498Szrj       int i;
6179*38fd1498Szrj 
6180*38fd1498Szrj       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
6181*38fd1498Szrj 	{
6182*38fd1498Szrj 	  rtx y = XVECEXP (x, 0, i);
6183*38fd1498Szrj 	  if (GET_CODE (y) == CLOBBER)
6184*38fd1498Szrj 	    {
6185*38fd1498Szrj 	      rtx clobbered = XEXP (y, 0);
6186*38fd1498Szrj 
6187*38fd1498Szrj 	      if (REG_P (clobbered)
6188*38fd1498Szrj 		  || GET_CODE (clobbered) == SUBREG)
6189*38fd1498Szrj 		invalidate (clobbered, VOIDmode);
6190*38fd1498Szrj 	      else if (GET_CODE (clobbered) == STRICT_LOW_PART
6191*38fd1498Szrj 		       || GET_CODE (clobbered) == ZERO_EXTRACT)
6192*38fd1498Szrj 		invalidate (XEXP (clobbered, 0), GET_MODE (clobbered));
6193*38fd1498Szrj 	    }
6194*38fd1498Szrj 	  else if (GET_CODE (y) == SET && GET_CODE (SET_SRC (y)) == CALL)
6195*38fd1498Szrj 	    invalidate (SET_DEST (y), VOIDmode);
6196*38fd1498Szrj 	}
6197*38fd1498Szrj     }
6198*38fd1498Szrj }
6199*38fd1498Szrj 
6200*38fd1498Szrj /* Process X, part of the REG_NOTES of an insn.  Look at any REG_EQUAL notes
6201*38fd1498Szrj    and replace any registers in them with either an equivalent constant
6202*38fd1498Szrj    or the canonical form of the register.  If we are inside an address,
6203*38fd1498Szrj    only do this if the address remains valid.
6204*38fd1498Szrj 
6205*38fd1498Szrj    OBJECT is 0 except when within a MEM in which case it is the MEM.
6206*38fd1498Szrj 
6207*38fd1498Szrj    Return the replacement for X.  */
6208*38fd1498Szrj 
6209*38fd1498Szrj static rtx
cse_process_notes_1(rtx x,rtx object,bool * changed)6210*38fd1498Szrj cse_process_notes_1 (rtx x, rtx object, bool *changed)
6211*38fd1498Szrj {
6212*38fd1498Szrj   enum rtx_code code = GET_CODE (x);
6213*38fd1498Szrj   const char *fmt = GET_RTX_FORMAT (code);
6214*38fd1498Szrj   int i;
6215*38fd1498Szrj 
6216*38fd1498Szrj   switch (code)
6217*38fd1498Szrj     {
6218*38fd1498Szrj     case CONST:
6219*38fd1498Szrj     case SYMBOL_REF:
6220*38fd1498Szrj     case LABEL_REF:
6221*38fd1498Szrj     CASE_CONST_ANY:
6222*38fd1498Szrj     case PC:
6223*38fd1498Szrj     case CC0:
6224*38fd1498Szrj     case LO_SUM:
6225*38fd1498Szrj       return x;
6226*38fd1498Szrj 
6227*38fd1498Szrj     case MEM:
6228*38fd1498Szrj       validate_change (x, &XEXP (x, 0),
6229*38fd1498Szrj 		       cse_process_notes (XEXP (x, 0), x, changed), 0);
6230*38fd1498Szrj       return x;
6231*38fd1498Szrj 
6232*38fd1498Szrj     case EXPR_LIST:
6233*38fd1498Szrj       if (REG_NOTE_KIND (x) == REG_EQUAL)
6234*38fd1498Szrj 	XEXP (x, 0) = cse_process_notes (XEXP (x, 0), NULL_RTX, changed);
6235*38fd1498Szrj       /* Fall through.  */
6236*38fd1498Szrj 
6237*38fd1498Szrj     case INSN_LIST:
6238*38fd1498Szrj     case INT_LIST:
6239*38fd1498Szrj       if (XEXP (x, 1))
6240*38fd1498Szrj 	XEXP (x, 1) = cse_process_notes (XEXP (x, 1), NULL_RTX, changed);
6241*38fd1498Szrj       return x;
6242*38fd1498Szrj 
6243*38fd1498Szrj     case SIGN_EXTEND:
6244*38fd1498Szrj     case ZERO_EXTEND:
6245*38fd1498Szrj     case SUBREG:
6246*38fd1498Szrj       {
6247*38fd1498Szrj 	rtx new_rtx = cse_process_notes (XEXP (x, 0), object, changed);
6248*38fd1498Szrj 	/* We don't substitute VOIDmode constants into these rtx,
6249*38fd1498Szrj 	   since they would impede folding.  */
6250*38fd1498Szrj 	if (GET_MODE (new_rtx) != VOIDmode)
6251*38fd1498Szrj 	  validate_change (object, &XEXP (x, 0), new_rtx, 0);
6252*38fd1498Szrj 	return x;
6253*38fd1498Szrj       }
6254*38fd1498Szrj 
6255*38fd1498Szrj     case UNSIGNED_FLOAT:
6256*38fd1498Szrj       {
6257*38fd1498Szrj 	rtx new_rtx = cse_process_notes (XEXP (x, 0), object, changed);
6258*38fd1498Szrj 	/* We don't substitute negative VOIDmode constants into these rtx,
6259*38fd1498Szrj 	   since they would impede folding.  */
6260*38fd1498Szrj 	if (GET_MODE (new_rtx) != VOIDmode
6261*38fd1498Szrj 	    || (CONST_INT_P (new_rtx) && INTVAL (new_rtx) >= 0)
6262*38fd1498Szrj 	    || (CONST_DOUBLE_P (new_rtx) && CONST_DOUBLE_HIGH (new_rtx) >= 0))
6263*38fd1498Szrj 	  validate_change (object, &XEXP (x, 0), new_rtx, 0);
6264*38fd1498Szrj 	return x;
6265*38fd1498Szrj       }
6266*38fd1498Szrj 
6267*38fd1498Szrj     case REG:
6268*38fd1498Szrj       i = REG_QTY (REGNO (x));
6269*38fd1498Szrj 
6270*38fd1498Szrj       /* Return a constant or a constant register.  */
6271*38fd1498Szrj       if (REGNO_QTY_VALID_P (REGNO (x)))
6272*38fd1498Szrj 	{
6273*38fd1498Szrj 	  struct qty_table_elem *ent = &qty_table[i];
6274*38fd1498Szrj 
6275*38fd1498Szrj 	  if (ent->const_rtx != NULL_RTX
6276*38fd1498Szrj 	      && (CONSTANT_P (ent->const_rtx)
6277*38fd1498Szrj 		  || REG_P (ent->const_rtx)))
6278*38fd1498Szrj 	    {
6279*38fd1498Szrj 	      rtx new_rtx = gen_lowpart (GET_MODE (x), ent->const_rtx);
6280*38fd1498Szrj 	      if (new_rtx)
6281*38fd1498Szrj 		return copy_rtx (new_rtx);
6282*38fd1498Szrj 	    }
6283*38fd1498Szrj 	}
6284*38fd1498Szrj 
6285*38fd1498Szrj       /* Otherwise, canonicalize this register.  */
6286*38fd1498Szrj       return canon_reg (x, NULL);
6287*38fd1498Szrj 
6288*38fd1498Szrj     default:
6289*38fd1498Szrj       break;
6290*38fd1498Szrj     }
6291*38fd1498Szrj 
6292*38fd1498Szrj   for (i = 0; i < GET_RTX_LENGTH (code); i++)
6293*38fd1498Szrj     if (fmt[i] == 'e')
6294*38fd1498Szrj       validate_change (object, &XEXP (x, i),
6295*38fd1498Szrj 		       cse_process_notes (XEXP (x, i), object, changed), 0);
6296*38fd1498Szrj 
6297*38fd1498Szrj   return x;
6298*38fd1498Szrj }
6299*38fd1498Szrj 
6300*38fd1498Szrj static rtx
cse_process_notes(rtx x,rtx object,bool * changed)6301*38fd1498Szrj cse_process_notes (rtx x, rtx object, bool *changed)
6302*38fd1498Szrj {
6303*38fd1498Szrj   rtx new_rtx = cse_process_notes_1 (x, object, changed);
6304*38fd1498Szrj   if (new_rtx != x)
6305*38fd1498Szrj     *changed = true;
6306*38fd1498Szrj   return new_rtx;
6307*38fd1498Szrj }
6308*38fd1498Szrj 
6309*38fd1498Szrj 
6310*38fd1498Szrj /* Find a path in the CFG, starting with FIRST_BB to perform CSE on.
6311*38fd1498Szrj 
6312*38fd1498Szrj    DATA is a pointer to a struct cse_basic_block_data, that is used to
6313*38fd1498Szrj    describe the path.
6314*38fd1498Szrj    It is filled with a queue of basic blocks, starting with FIRST_BB
6315*38fd1498Szrj    and following a trace through the CFG.
6316*38fd1498Szrj 
6317*38fd1498Szrj    If all paths starting at FIRST_BB have been followed, or no new path
6318*38fd1498Szrj    starting at FIRST_BB can be constructed, this function returns FALSE.
6319*38fd1498Szrj    Otherwise, DATA->path is filled and the function returns TRUE indicating
6320*38fd1498Szrj    that a path to follow was found.
6321*38fd1498Szrj 
6322*38fd1498Szrj    If FOLLOW_JUMPS is false, the maximum path length is 1 and the only
6323*38fd1498Szrj    block in the path will be FIRST_BB.  */
6324*38fd1498Szrj 
6325*38fd1498Szrj static bool
cse_find_path(basic_block first_bb,struct cse_basic_block_data * data,int follow_jumps)6326*38fd1498Szrj cse_find_path (basic_block first_bb, struct cse_basic_block_data *data,
6327*38fd1498Szrj 	       int follow_jumps)
6328*38fd1498Szrj {
6329*38fd1498Szrj   basic_block bb;
6330*38fd1498Szrj   edge e;
6331*38fd1498Szrj   int path_size;
6332*38fd1498Szrj 
6333*38fd1498Szrj   bitmap_set_bit (cse_visited_basic_blocks, first_bb->index);
6334*38fd1498Szrj 
6335*38fd1498Szrj   /* See if there is a previous path.  */
6336*38fd1498Szrj   path_size = data->path_size;
6337*38fd1498Szrj 
6338*38fd1498Szrj   /* There is a previous path.  Make sure it started with FIRST_BB.  */
6339*38fd1498Szrj   if (path_size)
6340*38fd1498Szrj     gcc_assert (data->path[0].bb == first_bb);
6341*38fd1498Szrj 
6342*38fd1498Szrj   /* There was only one basic block in the last path.  Clear the path and
6343*38fd1498Szrj      return, so that paths starting at another basic block can be tried.  */
6344*38fd1498Szrj   if (path_size == 1)
6345*38fd1498Szrj     {
6346*38fd1498Szrj       path_size = 0;
6347*38fd1498Szrj       goto done;
6348*38fd1498Szrj     }
6349*38fd1498Szrj 
6350*38fd1498Szrj   /* If the path was empty from the beginning, construct a new path.  */
6351*38fd1498Szrj   if (path_size == 0)
6352*38fd1498Szrj     data->path[path_size++].bb = first_bb;
6353*38fd1498Szrj   else
6354*38fd1498Szrj     {
6355*38fd1498Szrj       /* Otherwise, path_size must be equal to or greater than 2, because
6356*38fd1498Szrj 	 a previous path exists that is at least two basic blocks long.
6357*38fd1498Szrj 
6358*38fd1498Szrj 	 Update the previous branch path, if any.  If the last branch was
6359*38fd1498Szrj 	 previously along the branch edge, take the fallthrough edge now.  */
6360*38fd1498Szrj       while (path_size >= 2)
6361*38fd1498Szrj 	{
6362*38fd1498Szrj 	  basic_block last_bb_in_path, previous_bb_in_path;
6363*38fd1498Szrj 	  edge e;
6364*38fd1498Szrj 
6365*38fd1498Szrj 	  --path_size;
6366*38fd1498Szrj 	  last_bb_in_path = data->path[path_size].bb;
6367*38fd1498Szrj 	  previous_bb_in_path = data->path[path_size - 1].bb;
6368*38fd1498Szrj 
6369*38fd1498Szrj 	  /* If we previously followed a path along the branch edge, try
6370*38fd1498Szrj 	     the fallthru edge now.  */
6371*38fd1498Szrj 	  if (EDGE_COUNT (previous_bb_in_path->succs) == 2
6372*38fd1498Szrj 	      && any_condjump_p (BB_END (previous_bb_in_path))
6373*38fd1498Szrj 	      && (e = find_edge (previous_bb_in_path, last_bb_in_path))
6374*38fd1498Szrj 	      && e == BRANCH_EDGE (previous_bb_in_path))
6375*38fd1498Szrj 	    {
6376*38fd1498Szrj 	      bb = FALLTHRU_EDGE (previous_bb_in_path)->dest;
6377*38fd1498Szrj 	      if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
6378*38fd1498Szrj 		  && single_pred_p (bb)
6379*38fd1498Szrj 		  /* We used to assert here that we would only see blocks
6380*38fd1498Szrj 		     that we have not visited yet.  But we may end up
6381*38fd1498Szrj 		     visiting basic blocks twice if the CFG has changed
6382*38fd1498Szrj 		     in this run of cse_main, because when the CFG changes
6383*38fd1498Szrj 		     the topological sort of the CFG also changes.  A basic
6384*38fd1498Szrj 		     blocks that previously had more than two predecessors
6385*38fd1498Szrj 		     may now have a single predecessor, and become part of
6386*38fd1498Szrj 		     a path that starts at another basic block.
6387*38fd1498Szrj 
6388*38fd1498Szrj 		     We still want to visit each basic block only once, so
6389*38fd1498Szrj 		     halt the path here if we have already visited BB.  */
6390*38fd1498Szrj 		  && !bitmap_bit_p (cse_visited_basic_blocks, bb->index))
6391*38fd1498Szrj 		{
6392*38fd1498Szrj 		  bitmap_set_bit (cse_visited_basic_blocks, bb->index);
6393*38fd1498Szrj 		  data->path[path_size++].bb = bb;
6394*38fd1498Szrj 		  break;
6395*38fd1498Szrj 		}
6396*38fd1498Szrj 	    }
6397*38fd1498Szrj 
6398*38fd1498Szrj 	  data->path[path_size].bb = NULL;
6399*38fd1498Szrj 	}
6400*38fd1498Szrj 
6401*38fd1498Szrj       /* If only one block remains in the path, bail.  */
6402*38fd1498Szrj       if (path_size == 1)
6403*38fd1498Szrj 	{
6404*38fd1498Szrj 	  path_size = 0;
6405*38fd1498Szrj 	  goto done;
6406*38fd1498Szrj 	}
6407*38fd1498Szrj     }
6408*38fd1498Szrj 
6409*38fd1498Szrj   /* Extend the path if possible.  */
6410*38fd1498Szrj   if (follow_jumps)
6411*38fd1498Szrj     {
6412*38fd1498Szrj       bb = data->path[path_size - 1].bb;
6413*38fd1498Szrj       while (bb && path_size < PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH))
6414*38fd1498Szrj 	{
6415*38fd1498Szrj 	  if (single_succ_p (bb))
6416*38fd1498Szrj 	    e = single_succ_edge (bb);
6417*38fd1498Szrj 	  else if (EDGE_COUNT (bb->succs) == 2
6418*38fd1498Szrj 		   && any_condjump_p (BB_END (bb)))
6419*38fd1498Szrj 	    {
6420*38fd1498Szrj 	      /* First try to follow the branch.  If that doesn't lead
6421*38fd1498Szrj 		 to a useful path, follow the fallthru edge.  */
6422*38fd1498Szrj 	      e = BRANCH_EDGE (bb);
6423*38fd1498Szrj 	      if (!single_pred_p (e->dest))
6424*38fd1498Szrj 		e = FALLTHRU_EDGE (bb);
6425*38fd1498Szrj 	    }
6426*38fd1498Szrj 	  else
6427*38fd1498Szrj 	    e = NULL;
6428*38fd1498Szrj 
6429*38fd1498Szrj 	  if (e
6430*38fd1498Szrj 	      && !((e->flags & EDGE_ABNORMAL_CALL) && cfun->has_nonlocal_label)
6431*38fd1498Szrj 	      && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
6432*38fd1498Szrj 	      && single_pred_p (e->dest)
6433*38fd1498Szrj 	      /* Avoid visiting basic blocks twice.  The large comment
6434*38fd1498Szrj 		 above explains why this can happen.  */
6435*38fd1498Szrj 	      && !bitmap_bit_p (cse_visited_basic_blocks, e->dest->index))
6436*38fd1498Szrj 	    {
6437*38fd1498Szrj 	      basic_block bb2 = e->dest;
6438*38fd1498Szrj 	      bitmap_set_bit (cse_visited_basic_blocks, bb2->index);
6439*38fd1498Szrj 	      data->path[path_size++].bb = bb2;
6440*38fd1498Szrj 	      bb = bb2;
6441*38fd1498Szrj 	    }
6442*38fd1498Szrj 	  else
6443*38fd1498Szrj 	    bb = NULL;
6444*38fd1498Szrj 	}
6445*38fd1498Szrj     }
6446*38fd1498Szrj 
6447*38fd1498Szrj done:
6448*38fd1498Szrj   data->path_size = path_size;
6449*38fd1498Szrj   return path_size != 0;
6450*38fd1498Szrj }
6451*38fd1498Szrj 
6452*38fd1498Szrj /* Dump the path in DATA to file F.  NSETS is the number of sets
6453*38fd1498Szrj    in the path.  */
6454*38fd1498Szrj 
6455*38fd1498Szrj static void
cse_dump_path(struct cse_basic_block_data * data,int nsets,FILE * f)6456*38fd1498Szrj cse_dump_path (struct cse_basic_block_data *data, int nsets, FILE *f)
6457*38fd1498Szrj {
6458*38fd1498Szrj   int path_entry;
6459*38fd1498Szrj 
6460*38fd1498Szrj   fprintf (f, ";; Following path with %d sets: ", nsets);
6461*38fd1498Szrj   for (path_entry = 0; path_entry < data->path_size; path_entry++)
6462*38fd1498Szrj     fprintf (f, "%d ", (data->path[path_entry].bb)->index);
6463*38fd1498Szrj   fputc ('\n', dump_file);
6464*38fd1498Szrj   fflush (f);
6465*38fd1498Szrj }
6466*38fd1498Szrj 
6467*38fd1498Szrj 
6468*38fd1498Szrj /* Return true if BB has exception handling successor edges.  */
6469*38fd1498Szrj 
6470*38fd1498Szrj static bool
have_eh_succ_edges(basic_block bb)6471*38fd1498Szrj have_eh_succ_edges (basic_block bb)
6472*38fd1498Szrj {
6473*38fd1498Szrj   edge e;
6474*38fd1498Szrj   edge_iterator ei;
6475*38fd1498Szrj 
6476*38fd1498Szrj   FOR_EACH_EDGE (e, ei, bb->succs)
6477*38fd1498Szrj     if (e->flags & EDGE_EH)
6478*38fd1498Szrj       return true;
6479*38fd1498Szrj 
6480*38fd1498Szrj   return false;
6481*38fd1498Szrj }
6482*38fd1498Szrj 
6483*38fd1498Szrj 
6484*38fd1498Szrj /* Scan to the end of the path described by DATA.  Return an estimate of
6485*38fd1498Szrj    the total number of SETs of all insns in the path.  */
6486*38fd1498Szrj 
6487*38fd1498Szrj static void
cse_prescan_path(struct cse_basic_block_data * data)6488*38fd1498Szrj cse_prescan_path (struct cse_basic_block_data *data)
6489*38fd1498Szrj {
6490*38fd1498Szrj   int nsets = 0;
6491*38fd1498Szrj   int path_size = data->path_size;
6492*38fd1498Szrj   int path_entry;
6493*38fd1498Szrj 
6494*38fd1498Szrj   /* Scan to end of each basic block in the path.  */
6495*38fd1498Szrj   for (path_entry = 0; path_entry < path_size; path_entry++)
6496*38fd1498Szrj     {
6497*38fd1498Szrj       basic_block bb;
6498*38fd1498Szrj       rtx_insn *insn;
6499*38fd1498Szrj 
6500*38fd1498Szrj       bb = data->path[path_entry].bb;
6501*38fd1498Szrj 
6502*38fd1498Szrj       FOR_BB_INSNS (bb, insn)
6503*38fd1498Szrj 	{
6504*38fd1498Szrj 	  if (!INSN_P (insn))
6505*38fd1498Szrj 	    continue;
6506*38fd1498Szrj 
6507*38fd1498Szrj 	  /* A PARALLEL can have lots of SETs in it,
6508*38fd1498Szrj 	     especially if it is really an ASM_OPERANDS.  */
6509*38fd1498Szrj 	  if (GET_CODE (PATTERN (insn)) == PARALLEL)
6510*38fd1498Szrj 	    nsets += XVECLEN (PATTERN (insn), 0);
6511*38fd1498Szrj 	  else
6512*38fd1498Szrj 	    nsets += 1;
6513*38fd1498Szrj 	}
6514*38fd1498Szrj     }
6515*38fd1498Szrj 
6516*38fd1498Szrj   data->nsets = nsets;
6517*38fd1498Szrj }
6518*38fd1498Szrj 
6519*38fd1498Szrj /* Return true if the pattern of INSN uses a LABEL_REF for which
6520*38fd1498Szrj    there isn't a REG_LABEL_OPERAND note.  */
6521*38fd1498Szrj 
6522*38fd1498Szrj static bool
check_for_label_ref(rtx_insn * insn)6523*38fd1498Szrj check_for_label_ref (rtx_insn *insn)
6524*38fd1498Szrj {
6525*38fd1498Szrj   /* If this insn uses a LABEL_REF and there isn't a REG_LABEL_OPERAND
6526*38fd1498Szrj      note for it, we must rerun jump since it needs to place the note.  If
6527*38fd1498Szrj      this is a LABEL_REF for a CODE_LABEL that isn't in the insn chain,
6528*38fd1498Szrj      don't do this since no REG_LABEL_OPERAND will be added.  */
6529*38fd1498Szrj   subrtx_iterator::array_type array;
6530*38fd1498Szrj   FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL)
6531*38fd1498Szrj     {
6532*38fd1498Szrj       const_rtx x = *iter;
6533*38fd1498Szrj       if (GET_CODE (x) == LABEL_REF
6534*38fd1498Szrj 	  && !LABEL_REF_NONLOCAL_P (x)
6535*38fd1498Szrj 	  && (!JUMP_P (insn)
6536*38fd1498Szrj 	      || !label_is_jump_target_p (label_ref_label (x), insn))
6537*38fd1498Szrj 	  && LABEL_P (label_ref_label (x))
6538*38fd1498Szrj 	  && INSN_UID (label_ref_label (x)) != 0
6539*38fd1498Szrj 	  && !find_reg_note (insn, REG_LABEL_OPERAND, label_ref_label (x)))
6540*38fd1498Szrj 	return true;
6541*38fd1498Szrj     }
6542*38fd1498Szrj   return false;
6543*38fd1498Szrj }
6544*38fd1498Szrj 
6545*38fd1498Szrj /* Process a single extended basic block described by EBB_DATA.  */
6546*38fd1498Szrj 
6547*38fd1498Szrj static void
cse_extended_basic_block(struct cse_basic_block_data * ebb_data)6548*38fd1498Szrj cse_extended_basic_block (struct cse_basic_block_data *ebb_data)
6549*38fd1498Szrj {
6550*38fd1498Szrj   int path_size = ebb_data->path_size;
6551*38fd1498Szrj   int path_entry;
6552*38fd1498Szrj   int num_insns = 0;
6553*38fd1498Szrj 
6554*38fd1498Szrj   /* Allocate the space needed by qty_table.  */
6555*38fd1498Szrj   qty_table = XNEWVEC (struct qty_table_elem, max_qty);
6556*38fd1498Szrj 
6557*38fd1498Szrj   new_basic_block ();
6558*38fd1498Szrj   cse_ebb_live_in = df_get_live_in (ebb_data->path[0].bb);
6559*38fd1498Szrj   cse_ebb_live_out = df_get_live_out (ebb_data->path[path_size - 1].bb);
6560*38fd1498Szrj   for (path_entry = 0; path_entry < path_size; path_entry++)
6561*38fd1498Szrj     {
6562*38fd1498Szrj       basic_block bb;
6563*38fd1498Szrj       rtx_insn *insn;
6564*38fd1498Szrj 
6565*38fd1498Szrj       bb = ebb_data->path[path_entry].bb;
6566*38fd1498Szrj 
6567*38fd1498Szrj       /* Invalidate recorded information for eh regs if there is an EH
6568*38fd1498Szrj 	 edge pointing to that bb.  */
6569*38fd1498Szrj       if (bb_has_eh_pred (bb))
6570*38fd1498Szrj 	{
6571*38fd1498Szrj 	  df_ref def;
6572*38fd1498Szrj 
6573*38fd1498Szrj 	  FOR_EACH_ARTIFICIAL_DEF (def, bb->index)
6574*38fd1498Szrj 	    if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
6575*38fd1498Szrj 	      invalidate (DF_REF_REG (def), GET_MODE (DF_REF_REG (def)));
6576*38fd1498Szrj 	}
6577*38fd1498Szrj 
6578*38fd1498Szrj       optimize_this_for_speed_p = optimize_bb_for_speed_p (bb);
6579*38fd1498Szrj       FOR_BB_INSNS (bb, insn)
6580*38fd1498Szrj 	{
6581*38fd1498Szrj 	  /* If we have processed 1,000 insns, flush the hash table to
6582*38fd1498Szrj 	     avoid extreme quadratic behavior.  We must not include NOTEs
6583*38fd1498Szrj 	     in the count since there may be more of them when generating
6584*38fd1498Szrj 	     debugging information.  If we clear the table at different
6585*38fd1498Szrj 	     times, code generated with -g -O might be different than code
6586*38fd1498Szrj 	     generated with -O but not -g.
6587*38fd1498Szrj 
6588*38fd1498Szrj 	     FIXME: This is a real kludge and needs to be done some other
6589*38fd1498Szrj 		    way.  */
6590*38fd1498Szrj 	  if (NONDEBUG_INSN_P (insn)
6591*38fd1498Szrj 	      && num_insns++ > PARAM_VALUE (PARAM_MAX_CSE_INSNS))
6592*38fd1498Szrj 	    {
6593*38fd1498Szrj 	      flush_hash_table ();
6594*38fd1498Szrj 	      num_insns = 0;
6595*38fd1498Szrj 	    }
6596*38fd1498Szrj 
6597*38fd1498Szrj 	  if (INSN_P (insn))
6598*38fd1498Szrj 	    {
6599*38fd1498Szrj 	      /* Process notes first so we have all notes in canonical forms
6600*38fd1498Szrj 		 when looking for duplicate operations.  */
6601*38fd1498Szrj 	      if (REG_NOTES (insn))
6602*38fd1498Szrj 		{
6603*38fd1498Szrj 		  bool changed = false;
6604*38fd1498Szrj 		  REG_NOTES (insn) = cse_process_notes (REG_NOTES (insn),
6605*38fd1498Szrj 						        NULL_RTX, &changed);
6606*38fd1498Szrj 		  if (changed)
6607*38fd1498Szrj 		    df_notes_rescan (insn);
6608*38fd1498Szrj 		}
6609*38fd1498Szrj 
6610*38fd1498Szrj 	      cse_insn (insn);
6611*38fd1498Szrj 
6612*38fd1498Szrj 	      /* If we haven't already found an insn where we added a LABEL_REF,
6613*38fd1498Szrj 		 check this one.  */
6614*38fd1498Szrj 	      if (INSN_P (insn) && !recorded_label_ref
6615*38fd1498Szrj 		  && check_for_label_ref (insn))
6616*38fd1498Szrj 		recorded_label_ref = true;
6617*38fd1498Szrj 
6618*38fd1498Szrj 	      if (HAVE_cc0 && NONDEBUG_INSN_P (insn))
6619*38fd1498Szrj 		{
6620*38fd1498Szrj 		  /* If the previous insn sets CC0 and this insn no
6621*38fd1498Szrj 		     longer references CC0, delete the previous insn.
6622*38fd1498Szrj 		     Here we use fact that nothing expects CC0 to be
6623*38fd1498Szrj 		     valid over an insn, which is true until the final
6624*38fd1498Szrj 		     pass.  */
6625*38fd1498Szrj 		  rtx_insn *prev_insn;
6626*38fd1498Szrj 		  rtx tem;
6627*38fd1498Szrj 
6628*38fd1498Szrj 		  prev_insn = prev_nonnote_nondebug_insn (insn);
6629*38fd1498Szrj 		  if (prev_insn && NONJUMP_INSN_P (prev_insn)
6630*38fd1498Szrj 		      && (tem = single_set (prev_insn)) != NULL_RTX
6631*38fd1498Szrj 		      && SET_DEST (tem) == cc0_rtx
6632*38fd1498Szrj 		      && ! reg_mentioned_p (cc0_rtx, PATTERN (insn)))
6633*38fd1498Szrj 		    delete_insn (prev_insn);
6634*38fd1498Szrj 
6635*38fd1498Szrj 		  /* If this insn is not the last insn in the basic
6636*38fd1498Szrj 		     block, it will be PREV_INSN(insn) in the next
6637*38fd1498Szrj 		     iteration.  If we recorded any CC0-related
6638*38fd1498Szrj 		     information for this insn, remember it.  */
6639*38fd1498Szrj 		  if (insn != BB_END (bb))
6640*38fd1498Szrj 		    {
6641*38fd1498Szrj 		      prev_insn_cc0 = this_insn_cc0;
6642*38fd1498Szrj 		      prev_insn_cc0_mode = this_insn_cc0_mode;
6643*38fd1498Szrj 		    }
6644*38fd1498Szrj 		}
6645*38fd1498Szrj 	    }
6646*38fd1498Szrj 	}
6647*38fd1498Szrj 
6648*38fd1498Szrj       /* With non-call exceptions, we are not always able to update
6649*38fd1498Szrj 	 the CFG properly inside cse_insn.  So clean up possibly
6650*38fd1498Szrj 	 redundant EH edges here.  */
6651*38fd1498Szrj       if (cfun->can_throw_non_call_exceptions && have_eh_succ_edges (bb))
6652*38fd1498Szrj 	cse_cfg_altered |= purge_dead_edges (bb);
6653*38fd1498Szrj 
6654*38fd1498Szrj       /* If we changed a conditional jump, we may have terminated
6655*38fd1498Szrj 	 the path we are following.  Check that by verifying that
6656*38fd1498Szrj 	 the edge we would take still exists.  If the edge does
6657*38fd1498Szrj 	 not exist anymore, purge the remainder of the path.
6658*38fd1498Szrj 	 Note that this will cause us to return to the caller.  */
6659*38fd1498Szrj       if (path_entry < path_size - 1)
6660*38fd1498Szrj 	{
6661*38fd1498Szrj 	  basic_block next_bb = ebb_data->path[path_entry + 1].bb;
6662*38fd1498Szrj 	  if (!find_edge (bb, next_bb))
6663*38fd1498Szrj 	    {
6664*38fd1498Szrj 	      do
6665*38fd1498Szrj 		{
6666*38fd1498Szrj 		  path_size--;
6667*38fd1498Szrj 
6668*38fd1498Szrj 		  /* If we truncate the path, we must also reset the
6669*38fd1498Szrj 		     visited bit on the remaining blocks in the path,
6670*38fd1498Szrj 		     or we will never visit them at all.  */
6671*38fd1498Szrj 		  bitmap_clear_bit (cse_visited_basic_blocks,
6672*38fd1498Szrj 			     ebb_data->path[path_size].bb->index);
6673*38fd1498Szrj 		  ebb_data->path[path_size].bb = NULL;
6674*38fd1498Szrj 		}
6675*38fd1498Szrj 	      while (path_size - 1 != path_entry);
6676*38fd1498Szrj 	      ebb_data->path_size = path_size;
6677*38fd1498Szrj 	    }
6678*38fd1498Szrj 	}
6679*38fd1498Szrj 
6680*38fd1498Szrj       /* If this is a conditional jump insn, record any known
6681*38fd1498Szrj 	 equivalences due to the condition being tested.  */
6682*38fd1498Szrj       insn = BB_END (bb);
6683*38fd1498Szrj       if (path_entry < path_size - 1
6684*38fd1498Szrj 	  && EDGE_COUNT (bb->succs) == 2
6685*38fd1498Szrj 	  && JUMP_P (insn)
6686*38fd1498Szrj 	  && single_set (insn)
6687*38fd1498Szrj 	  && any_condjump_p (insn))
6688*38fd1498Szrj 	{
6689*38fd1498Szrj 	  basic_block next_bb = ebb_data->path[path_entry + 1].bb;
6690*38fd1498Szrj 	  bool taken = (next_bb == BRANCH_EDGE (bb)->dest);
6691*38fd1498Szrj 	  record_jump_equiv (insn, taken);
6692*38fd1498Szrj 	}
6693*38fd1498Szrj 
6694*38fd1498Szrj       /* Clear the CC0-tracking related insns, they can't provide
6695*38fd1498Szrj 	 useful information across basic block boundaries.  */
6696*38fd1498Szrj       prev_insn_cc0 = 0;
6697*38fd1498Szrj     }
6698*38fd1498Szrj 
6699*38fd1498Szrj   gcc_assert (next_qty <= max_qty);
6700*38fd1498Szrj 
6701*38fd1498Szrj   free (qty_table);
6702*38fd1498Szrj }
6703*38fd1498Szrj 
6704*38fd1498Szrj 
6705*38fd1498Szrj /* Perform cse on the instructions of a function.
6706*38fd1498Szrj    F is the first instruction.
6707*38fd1498Szrj    NREGS is one plus the highest pseudo-reg number used in the instruction.
6708*38fd1498Szrj 
6709*38fd1498Szrj    Return 2 if jump optimizations should be redone due to simplifications
6710*38fd1498Szrj    in conditional jump instructions.
6711*38fd1498Szrj    Return 1 if the CFG should be cleaned up because it has been modified.
6712*38fd1498Szrj    Return 0 otherwise.  */
6713*38fd1498Szrj 
6714*38fd1498Szrj static int
cse_main(rtx_insn * f ATTRIBUTE_UNUSED,int nregs)6715*38fd1498Szrj cse_main (rtx_insn *f ATTRIBUTE_UNUSED, int nregs)
6716*38fd1498Szrj {
6717*38fd1498Szrj   struct cse_basic_block_data ebb_data;
6718*38fd1498Szrj   basic_block bb;
6719*38fd1498Szrj   int *rc_order = XNEWVEC (int, last_basic_block_for_fn (cfun));
6720*38fd1498Szrj   int i, n_blocks;
6721*38fd1498Szrj 
6722*38fd1498Szrj   /* CSE doesn't use dominane info but can invalidate it in different ways.
6723*38fd1498Szrj      For simplicity free dominance info here.  */
6724*38fd1498Szrj   free_dominance_info (CDI_DOMINATORS);
6725*38fd1498Szrj 
6726*38fd1498Szrj   df_set_flags (DF_LR_RUN_DCE);
6727*38fd1498Szrj   df_note_add_problem ();
6728*38fd1498Szrj   df_analyze ();
6729*38fd1498Szrj   df_set_flags (DF_DEFER_INSN_RESCAN);
6730*38fd1498Szrj 
6731*38fd1498Szrj   reg_scan (get_insns (), max_reg_num ());
6732*38fd1498Szrj   init_cse_reg_info (nregs);
6733*38fd1498Szrj 
6734*38fd1498Szrj   ebb_data.path = XNEWVEC (struct branch_path,
6735*38fd1498Szrj 			   PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH));
6736*38fd1498Szrj 
6737*38fd1498Szrj   cse_cfg_altered = false;
6738*38fd1498Szrj   cse_jumps_altered = false;
6739*38fd1498Szrj   recorded_label_ref = false;
6740*38fd1498Szrj   constant_pool_entries_cost = 0;
6741*38fd1498Szrj   constant_pool_entries_regcost = 0;
6742*38fd1498Szrj   ebb_data.path_size = 0;
6743*38fd1498Szrj   ebb_data.nsets = 0;
6744*38fd1498Szrj   rtl_hooks = cse_rtl_hooks;
6745*38fd1498Szrj 
6746*38fd1498Szrj   init_recog ();
6747*38fd1498Szrj   init_alias_analysis ();
6748*38fd1498Szrj 
6749*38fd1498Szrj   reg_eqv_table = XNEWVEC (struct reg_eqv_elem, nregs);
6750*38fd1498Szrj 
6751*38fd1498Szrj   /* Set up the table of already visited basic blocks.  */
6752*38fd1498Szrj   cse_visited_basic_blocks = sbitmap_alloc (last_basic_block_for_fn (cfun));
6753*38fd1498Szrj   bitmap_clear (cse_visited_basic_blocks);
6754*38fd1498Szrj 
6755*38fd1498Szrj   /* Loop over basic blocks in reverse completion order (RPO),
6756*38fd1498Szrj      excluding the ENTRY and EXIT blocks.  */
6757*38fd1498Szrj   n_blocks = pre_and_rev_post_order_compute (NULL, rc_order, false);
6758*38fd1498Szrj   i = 0;
6759*38fd1498Szrj   while (i < n_blocks)
6760*38fd1498Szrj     {
6761*38fd1498Szrj       /* Find the first block in the RPO queue that we have not yet
6762*38fd1498Szrj 	 processed before.  */
6763*38fd1498Szrj       do
6764*38fd1498Szrj 	{
6765*38fd1498Szrj 	  bb = BASIC_BLOCK_FOR_FN (cfun, rc_order[i++]);
6766*38fd1498Szrj 	}
6767*38fd1498Szrj       while (bitmap_bit_p (cse_visited_basic_blocks, bb->index)
6768*38fd1498Szrj 	     && i < n_blocks);
6769*38fd1498Szrj 
6770*38fd1498Szrj       /* Find all paths starting with BB, and process them.  */
6771*38fd1498Szrj       while (cse_find_path (bb, &ebb_data, flag_cse_follow_jumps))
6772*38fd1498Szrj 	{
6773*38fd1498Szrj 	  /* Pre-scan the path.  */
6774*38fd1498Szrj 	  cse_prescan_path (&ebb_data);
6775*38fd1498Szrj 
6776*38fd1498Szrj 	  /* If this basic block has no sets, skip it.  */
6777*38fd1498Szrj 	  if (ebb_data.nsets == 0)
6778*38fd1498Szrj 	    continue;
6779*38fd1498Szrj 
6780*38fd1498Szrj 	  /* Get a reasonable estimate for the maximum number of qty's
6781*38fd1498Szrj 	     needed for this path.  For this, we take the number of sets
6782*38fd1498Szrj 	     and multiply that by MAX_RECOG_OPERANDS.  */
6783*38fd1498Szrj 	  max_qty = ebb_data.nsets * MAX_RECOG_OPERANDS;
6784*38fd1498Szrj 
6785*38fd1498Szrj 	  /* Dump the path we're about to process.  */
6786*38fd1498Szrj 	  if (dump_file)
6787*38fd1498Szrj 	    cse_dump_path (&ebb_data, ebb_data.nsets, dump_file);
6788*38fd1498Szrj 
6789*38fd1498Szrj 	  cse_extended_basic_block (&ebb_data);
6790*38fd1498Szrj 	}
6791*38fd1498Szrj     }
6792*38fd1498Szrj 
6793*38fd1498Szrj   /* Clean up.  */
6794*38fd1498Szrj   end_alias_analysis ();
6795*38fd1498Szrj   free (reg_eqv_table);
6796*38fd1498Szrj   free (ebb_data.path);
6797*38fd1498Szrj   sbitmap_free (cse_visited_basic_blocks);
6798*38fd1498Szrj   free (rc_order);
6799*38fd1498Szrj   rtl_hooks = general_rtl_hooks;
6800*38fd1498Szrj 
6801*38fd1498Szrj   if (cse_jumps_altered || recorded_label_ref)
6802*38fd1498Szrj     return 2;
6803*38fd1498Szrj   else if (cse_cfg_altered)
6804*38fd1498Szrj     return 1;
6805*38fd1498Szrj   else
6806*38fd1498Szrj     return 0;
6807*38fd1498Szrj }
6808*38fd1498Szrj 
6809*38fd1498Szrj /* Count the number of times registers are used (not set) in X.
6810*38fd1498Szrj    COUNTS is an array in which we accumulate the count, INCR is how much
6811*38fd1498Szrj    we count each register usage.
6812*38fd1498Szrj 
6813*38fd1498Szrj    Don't count a usage of DEST, which is the SET_DEST of a SET which
6814*38fd1498Szrj    contains X in its SET_SRC.  This is because such a SET does not
6815*38fd1498Szrj    modify the liveness of DEST.
6816*38fd1498Szrj    DEST is set to pc_rtx for a trapping insn, or for an insn with side effects.
6817*38fd1498Szrj    We must then count uses of a SET_DEST regardless, because the insn can't be
6818*38fd1498Szrj    deleted here.  */
6819*38fd1498Szrj 
6820*38fd1498Szrj static void
count_reg_usage(rtx x,int * counts,rtx dest,int incr)6821*38fd1498Szrj count_reg_usage (rtx x, int *counts, rtx dest, int incr)
6822*38fd1498Szrj {
6823*38fd1498Szrj   enum rtx_code code;
6824*38fd1498Szrj   rtx note;
6825*38fd1498Szrj   const char *fmt;
6826*38fd1498Szrj   int i, j;
6827*38fd1498Szrj 
6828*38fd1498Szrj   if (x == 0)
6829*38fd1498Szrj     return;
6830*38fd1498Szrj 
6831*38fd1498Szrj   switch (code = GET_CODE (x))
6832*38fd1498Szrj     {
6833*38fd1498Szrj     case REG:
6834*38fd1498Szrj       if (x != dest)
6835*38fd1498Szrj 	counts[REGNO (x)] += incr;
6836*38fd1498Szrj       return;
6837*38fd1498Szrj 
6838*38fd1498Szrj     case PC:
6839*38fd1498Szrj     case CC0:
6840*38fd1498Szrj     case CONST:
6841*38fd1498Szrj     CASE_CONST_ANY:
6842*38fd1498Szrj     case SYMBOL_REF:
6843*38fd1498Szrj     case LABEL_REF:
6844*38fd1498Szrj       return;
6845*38fd1498Szrj 
6846*38fd1498Szrj     case CLOBBER:
6847*38fd1498Szrj       /* If we are clobbering a MEM, mark any registers inside the address
6848*38fd1498Szrj          as being used.  */
6849*38fd1498Szrj       if (MEM_P (XEXP (x, 0)))
6850*38fd1498Szrj 	count_reg_usage (XEXP (XEXP (x, 0), 0), counts, NULL_RTX, incr);
6851*38fd1498Szrj       return;
6852*38fd1498Szrj 
6853*38fd1498Szrj     case SET:
6854*38fd1498Szrj       /* Unless we are setting a REG, count everything in SET_DEST.  */
6855*38fd1498Szrj       if (!REG_P (SET_DEST (x)))
6856*38fd1498Szrj 	count_reg_usage (SET_DEST (x), counts, NULL_RTX, incr);
6857*38fd1498Szrj       count_reg_usage (SET_SRC (x), counts,
6858*38fd1498Szrj 		       dest ? dest : SET_DEST (x),
6859*38fd1498Szrj 		       incr);
6860*38fd1498Szrj       return;
6861*38fd1498Szrj 
6862*38fd1498Szrj     case DEBUG_INSN:
6863*38fd1498Szrj       return;
6864*38fd1498Szrj 
6865*38fd1498Szrj     case CALL_INSN:
6866*38fd1498Szrj     case INSN:
6867*38fd1498Szrj     case JUMP_INSN:
6868*38fd1498Szrj       /* We expect dest to be NULL_RTX here.  If the insn may throw,
6869*38fd1498Szrj 	 or if it cannot be deleted due to side-effects, mark this fact
6870*38fd1498Szrj 	 by setting DEST to pc_rtx.  */
6871*38fd1498Szrj       if ((!cfun->can_delete_dead_exceptions && !insn_nothrow_p (x))
6872*38fd1498Szrj 	  || side_effects_p (PATTERN (x)))
6873*38fd1498Szrj 	dest = pc_rtx;
6874*38fd1498Szrj       if (code == CALL_INSN)
6875*38fd1498Szrj 	count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, dest, incr);
6876*38fd1498Szrj       count_reg_usage (PATTERN (x), counts, dest, incr);
6877*38fd1498Szrj 
6878*38fd1498Szrj       /* Things used in a REG_EQUAL note aren't dead since loop may try to
6879*38fd1498Szrj 	 use them.  */
6880*38fd1498Szrj 
6881*38fd1498Szrj       note = find_reg_equal_equiv_note (x);
6882*38fd1498Szrj       if (note)
6883*38fd1498Szrj 	{
6884*38fd1498Szrj 	  rtx eqv = XEXP (note, 0);
6885*38fd1498Szrj 
6886*38fd1498Szrj 	  if (GET_CODE (eqv) == EXPR_LIST)
6887*38fd1498Szrj 	  /* This REG_EQUAL note describes the result of a function call.
6888*38fd1498Szrj 	     Process all the arguments.  */
6889*38fd1498Szrj 	    do
6890*38fd1498Szrj 	      {
6891*38fd1498Szrj 		count_reg_usage (XEXP (eqv, 0), counts, dest, incr);
6892*38fd1498Szrj 		eqv = XEXP (eqv, 1);
6893*38fd1498Szrj 	      }
6894*38fd1498Szrj 	    while (eqv && GET_CODE (eqv) == EXPR_LIST);
6895*38fd1498Szrj 	  else
6896*38fd1498Szrj 	    count_reg_usage (eqv, counts, dest, incr);
6897*38fd1498Szrj 	}
6898*38fd1498Szrj       return;
6899*38fd1498Szrj 
6900*38fd1498Szrj     case EXPR_LIST:
6901*38fd1498Szrj       if (REG_NOTE_KIND (x) == REG_EQUAL
6902*38fd1498Szrj 	  || (REG_NOTE_KIND (x) != REG_NONNEG && GET_CODE (XEXP (x,0)) == USE)
6903*38fd1498Szrj 	  /* FUNCTION_USAGE expression lists may include (CLOBBER (mem /u)),
6904*38fd1498Szrj 	     involving registers in the address.  */
6905*38fd1498Szrj 	  || GET_CODE (XEXP (x, 0)) == CLOBBER)
6906*38fd1498Szrj 	count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr);
6907*38fd1498Szrj 
6908*38fd1498Szrj       count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr);
6909*38fd1498Szrj       return;
6910*38fd1498Szrj 
6911*38fd1498Szrj     case ASM_OPERANDS:
6912*38fd1498Szrj       /* Iterate over just the inputs, not the constraints as well.  */
6913*38fd1498Szrj       for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
6914*38fd1498Szrj 	count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, dest, incr);
6915*38fd1498Szrj       return;
6916*38fd1498Szrj 
6917*38fd1498Szrj     case INSN_LIST:
6918*38fd1498Szrj     case INT_LIST:
6919*38fd1498Szrj       gcc_unreachable ();
6920*38fd1498Szrj 
6921*38fd1498Szrj     default:
6922*38fd1498Szrj       break;
6923*38fd1498Szrj     }
6924*38fd1498Szrj 
6925*38fd1498Szrj   fmt = GET_RTX_FORMAT (code);
6926*38fd1498Szrj   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
6927*38fd1498Szrj     {
6928*38fd1498Szrj       if (fmt[i] == 'e')
6929*38fd1498Szrj 	count_reg_usage (XEXP (x, i), counts, dest, incr);
6930*38fd1498Szrj       else if (fmt[i] == 'E')
6931*38fd1498Szrj 	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
6932*38fd1498Szrj 	  count_reg_usage (XVECEXP (x, i, j), counts, dest, incr);
6933*38fd1498Szrj     }
6934*38fd1498Szrj }
6935*38fd1498Szrj 
6936*38fd1498Szrj /* Return true if X is a dead register.  */
6937*38fd1498Szrj 
6938*38fd1498Szrj static inline int
is_dead_reg(const_rtx x,int * counts)6939*38fd1498Szrj is_dead_reg (const_rtx x, int *counts)
6940*38fd1498Szrj {
6941*38fd1498Szrj   return (REG_P (x)
6942*38fd1498Szrj 	  && REGNO (x) >= FIRST_PSEUDO_REGISTER
6943*38fd1498Szrj 	  && counts[REGNO (x)] == 0);
6944*38fd1498Szrj }
6945*38fd1498Szrj 
6946*38fd1498Szrj /* Return true if set is live.  */
6947*38fd1498Szrj static bool
set_live_p(rtx set,rtx_insn * insn ATTRIBUTE_UNUSED,int * counts)6948*38fd1498Szrj set_live_p (rtx set, rtx_insn *insn ATTRIBUTE_UNUSED, /* Only used with HAVE_cc0.  */
6949*38fd1498Szrj 	    int *counts)
6950*38fd1498Szrj {
6951*38fd1498Szrj   rtx_insn *tem;
6952*38fd1498Szrj 
6953*38fd1498Szrj   if (set_noop_p (set))
6954*38fd1498Szrj     ;
6955*38fd1498Szrj 
6956*38fd1498Szrj   else if (GET_CODE (SET_DEST (set)) == CC0
6957*38fd1498Szrj 	   && !side_effects_p (SET_SRC (set))
6958*38fd1498Szrj 	   && ((tem = next_nonnote_nondebug_insn (insn)) == NULL_RTX
6959*38fd1498Szrj 	       || !INSN_P (tem)
6960*38fd1498Szrj 	       || !reg_referenced_p (cc0_rtx, PATTERN (tem))))
6961*38fd1498Szrj     return false;
6962*38fd1498Szrj   else if (!is_dead_reg (SET_DEST (set), counts)
6963*38fd1498Szrj 	   || side_effects_p (SET_SRC (set)))
6964*38fd1498Szrj     return true;
6965*38fd1498Szrj   return false;
6966*38fd1498Szrj }
6967*38fd1498Szrj 
6968*38fd1498Szrj /* Return true if insn is live.  */
6969*38fd1498Szrj 
6970*38fd1498Szrj static bool
insn_live_p(rtx_insn * insn,int * counts)6971*38fd1498Szrj insn_live_p (rtx_insn *insn, int *counts)
6972*38fd1498Szrj {
6973*38fd1498Szrj   int i;
6974*38fd1498Szrj   if (!cfun->can_delete_dead_exceptions && !insn_nothrow_p (insn))
6975*38fd1498Szrj     return true;
6976*38fd1498Szrj   else if (GET_CODE (PATTERN (insn)) == SET)
6977*38fd1498Szrj     return set_live_p (PATTERN (insn), insn, counts);
6978*38fd1498Szrj   else if (GET_CODE (PATTERN (insn)) == PARALLEL)
6979*38fd1498Szrj     {
6980*38fd1498Szrj       for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
6981*38fd1498Szrj 	{
6982*38fd1498Szrj 	  rtx elt = XVECEXP (PATTERN (insn), 0, i);
6983*38fd1498Szrj 
6984*38fd1498Szrj 	  if (GET_CODE (elt) == SET)
6985*38fd1498Szrj 	    {
6986*38fd1498Szrj 	      if (set_live_p (elt, insn, counts))
6987*38fd1498Szrj 		return true;
6988*38fd1498Szrj 	    }
6989*38fd1498Szrj 	  else if (GET_CODE (elt) != CLOBBER && GET_CODE (elt) != USE)
6990*38fd1498Szrj 	    return true;
6991*38fd1498Szrj 	}
6992*38fd1498Szrj       return false;
6993*38fd1498Szrj     }
6994*38fd1498Szrj   else if (DEBUG_INSN_P (insn))
6995*38fd1498Szrj     {
6996*38fd1498Szrj       rtx_insn *next;
6997*38fd1498Szrj 
6998*38fd1498Szrj       if (DEBUG_MARKER_INSN_P (insn))
6999*38fd1498Szrj 	return true;
7000*38fd1498Szrj 
7001*38fd1498Szrj       for (next = NEXT_INSN (insn); next; next = NEXT_INSN (next))
7002*38fd1498Szrj 	if (NOTE_P (next))
7003*38fd1498Szrj 	  continue;
7004*38fd1498Szrj 	else if (!DEBUG_INSN_P (next))
7005*38fd1498Szrj 	  return true;
7006*38fd1498Szrj 	/* If we find an inspection point, such as a debug begin stmt,
7007*38fd1498Szrj 	   we want to keep the earlier debug insn.  */
7008*38fd1498Szrj 	else if (DEBUG_MARKER_INSN_P (next))
7009*38fd1498Szrj 	  return true;
7010*38fd1498Szrj 	else if (INSN_VAR_LOCATION_DECL (insn) == INSN_VAR_LOCATION_DECL (next))
7011*38fd1498Szrj 	  return false;
7012*38fd1498Szrj 
7013*38fd1498Szrj       return true;
7014*38fd1498Szrj     }
7015*38fd1498Szrj   else
7016*38fd1498Szrj     return true;
7017*38fd1498Szrj }
7018*38fd1498Szrj 
7019*38fd1498Szrj /* Count the number of stores into pseudo.  Callback for note_stores.  */
7020*38fd1498Szrj 
7021*38fd1498Szrj static void
count_stores(rtx x,const_rtx set ATTRIBUTE_UNUSED,void * data)7022*38fd1498Szrj count_stores (rtx x, const_rtx set ATTRIBUTE_UNUSED, void *data)
7023*38fd1498Szrj {
7024*38fd1498Szrj   int *counts = (int *) data;
7025*38fd1498Szrj   if (REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER)
7026*38fd1498Szrj     counts[REGNO (x)]++;
7027*38fd1498Szrj }
7028*38fd1498Szrj 
7029*38fd1498Szrj /* Return if DEBUG_INSN pattern PAT needs to be reset because some dead
7030*38fd1498Szrj    pseudo doesn't have a replacement.  COUNTS[X] is zero if register X
7031*38fd1498Szrj    is dead and REPLACEMENTS[X] is null if it has no replacemenet.
7032*38fd1498Szrj    Set *SEEN_REPL to true if we see a dead register that does have
7033*38fd1498Szrj    a replacement.  */
7034*38fd1498Szrj 
7035*38fd1498Szrj static bool
is_dead_debug_insn(const_rtx pat,int * counts,rtx * replacements,bool * seen_repl)7036*38fd1498Szrj is_dead_debug_insn (const_rtx pat, int *counts, rtx *replacements,
7037*38fd1498Szrj 		    bool *seen_repl)
7038*38fd1498Szrj {
7039*38fd1498Szrj   subrtx_iterator::array_type array;
7040*38fd1498Szrj   FOR_EACH_SUBRTX (iter, array, pat, NONCONST)
7041*38fd1498Szrj     {
7042*38fd1498Szrj       const_rtx x = *iter;
7043*38fd1498Szrj       if (is_dead_reg (x, counts))
7044*38fd1498Szrj 	{
7045*38fd1498Szrj 	  if (replacements && replacements[REGNO (x)] != NULL_RTX)
7046*38fd1498Szrj 	    *seen_repl = true;
7047*38fd1498Szrj 	  else
7048*38fd1498Szrj 	    return true;
7049*38fd1498Szrj 	}
7050*38fd1498Szrj     }
7051*38fd1498Szrj   return false;
7052*38fd1498Szrj }
7053*38fd1498Szrj 
7054*38fd1498Szrj /* Replace a dead pseudo in a DEBUG_INSN with replacement DEBUG_EXPR.
7055*38fd1498Szrj    Callback for simplify_replace_fn_rtx.  */
7056*38fd1498Szrj 
7057*38fd1498Szrj static rtx
replace_dead_reg(rtx x,const_rtx old_rtx ATTRIBUTE_UNUSED,void * data)7058*38fd1498Szrj replace_dead_reg (rtx x, const_rtx old_rtx ATTRIBUTE_UNUSED, void *data)
7059*38fd1498Szrj {
7060*38fd1498Szrj   rtx *replacements = (rtx *) data;
7061*38fd1498Szrj 
7062*38fd1498Szrj   if (REG_P (x)
7063*38fd1498Szrj       && REGNO (x) >= FIRST_PSEUDO_REGISTER
7064*38fd1498Szrj       && replacements[REGNO (x)] != NULL_RTX)
7065*38fd1498Szrj     {
7066*38fd1498Szrj       if (GET_MODE (x) == GET_MODE (replacements[REGNO (x)]))
7067*38fd1498Szrj 	return replacements[REGNO (x)];
7068*38fd1498Szrj       return lowpart_subreg (GET_MODE (x), replacements[REGNO (x)],
7069*38fd1498Szrj 			     GET_MODE (replacements[REGNO (x)]));
7070*38fd1498Szrj     }
7071*38fd1498Szrj   return NULL_RTX;
7072*38fd1498Szrj }
7073*38fd1498Szrj 
7074*38fd1498Szrj /* Scan all the insns and delete any that are dead; i.e., they store a register
7075*38fd1498Szrj    that is never used or they copy a register to itself.
7076*38fd1498Szrj 
7077*38fd1498Szrj    This is used to remove insns made obviously dead by cse, loop or other
7078*38fd1498Szrj    optimizations.  It improves the heuristics in loop since it won't try to
7079*38fd1498Szrj    move dead invariants out of loops or make givs for dead quantities.  The
7080*38fd1498Szrj    remaining passes of the compilation are also sped up.  */
7081*38fd1498Szrj 
7082*38fd1498Szrj int
delete_trivially_dead_insns(rtx_insn * insns,int nreg)7083*38fd1498Szrj delete_trivially_dead_insns (rtx_insn *insns, int nreg)
7084*38fd1498Szrj {
7085*38fd1498Szrj   int *counts;
7086*38fd1498Szrj   rtx_insn *insn, *prev;
7087*38fd1498Szrj   rtx *replacements = NULL;
7088*38fd1498Szrj   int ndead = 0;
7089*38fd1498Szrj 
7090*38fd1498Szrj   timevar_push (TV_DELETE_TRIVIALLY_DEAD);
7091*38fd1498Szrj   /* First count the number of times each register is used.  */
7092*38fd1498Szrj   if (MAY_HAVE_DEBUG_BIND_INSNS)
7093*38fd1498Szrj     {
7094*38fd1498Szrj       counts = XCNEWVEC (int, nreg * 3);
7095*38fd1498Szrj       for (insn = insns; insn; insn = NEXT_INSN (insn))
7096*38fd1498Szrj 	if (DEBUG_BIND_INSN_P (insn))
7097*38fd1498Szrj 	  count_reg_usage (INSN_VAR_LOCATION_LOC (insn), counts + nreg,
7098*38fd1498Szrj 			   NULL_RTX, 1);
7099*38fd1498Szrj 	else if (INSN_P (insn))
7100*38fd1498Szrj 	  {
7101*38fd1498Szrj 	    count_reg_usage (insn, counts, NULL_RTX, 1);
7102*38fd1498Szrj 	    note_stores (PATTERN (insn), count_stores, counts + nreg * 2);
7103*38fd1498Szrj 	  }
7104*38fd1498Szrj       /* If there can be debug insns, COUNTS are 3 consecutive arrays.
7105*38fd1498Szrj 	 First one counts how many times each pseudo is used outside
7106*38fd1498Szrj 	 of debug insns, second counts how many times each pseudo is
7107*38fd1498Szrj 	 used in debug insns and third counts how many times a pseudo
7108*38fd1498Szrj 	 is stored.  */
7109*38fd1498Szrj     }
7110*38fd1498Szrj   else
7111*38fd1498Szrj     {
7112*38fd1498Szrj       counts = XCNEWVEC (int, nreg);
7113*38fd1498Szrj       for (insn = insns; insn; insn = NEXT_INSN (insn))
7114*38fd1498Szrj 	if (INSN_P (insn))
7115*38fd1498Szrj 	  count_reg_usage (insn, counts, NULL_RTX, 1);
7116*38fd1498Szrj       /* If no debug insns can be present, COUNTS is just an array
7117*38fd1498Szrj 	 which counts how many times each pseudo is used.  */
7118*38fd1498Szrj     }
7119*38fd1498Szrj   /* Pseudo PIC register should be considered as used due to possible
7120*38fd1498Szrj      new usages generated.  */
7121*38fd1498Szrj   if (!reload_completed
7122*38fd1498Szrj       && pic_offset_table_rtx
7123*38fd1498Szrj       && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER)
7124*38fd1498Szrj     counts[REGNO (pic_offset_table_rtx)]++;
7125*38fd1498Szrj   /* Go from the last insn to the first and delete insns that only set unused
7126*38fd1498Szrj      registers or copy a register to itself.  As we delete an insn, remove
7127*38fd1498Szrj      usage counts for registers it uses.
7128*38fd1498Szrj 
7129*38fd1498Szrj      The first jump optimization pass may leave a real insn as the last
7130*38fd1498Szrj      insn in the function.   We must not skip that insn or we may end
7131*38fd1498Szrj      up deleting code that is not really dead.
7132*38fd1498Szrj 
7133*38fd1498Szrj      If some otherwise unused register is only used in DEBUG_INSNs,
7134*38fd1498Szrj      try to create a DEBUG_EXPR temporary and emit a DEBUG_INSN before
7135*38fd1498Szrj      the setter.  Then go through DEBUG_INSNs and if a DEBUG_EXPR
7136*38fd1498Szrj      has been created for the unused register, replace it with
7137*38fd1498Szrj      the DEBUG_EXPR, otherwise reset the DEBUG_INSN.  */
7138*38fd1498Szrj   for (insn = get_last_insn (); insn; insn = prev)
7139*38fd1498Szrj     {
7140*38fd1498Szrj       int live_insn = 0;
7141*38fd1498Szrj 
7142*38fd1498Szrj       prev = PREV_INSN (insn);
7143*38fd1498Szrj       if (!INSN_P (insn))
7144*38fd1498Szrj 	continue;
7145*38fd1498Szrj 
7146*38fd1498Szrj       live_insn = insn_live_p (insn, counts);
7147*38fd1498Szrj 
7148*38fd1498Szrj       /* If this is a dead insn, delete it and show registers in it aren't
7149*38fd1498Szrj 	 being used.  */
7150*38fd1498Szrj 
7151*38fd1498Szrj       if (! live_insn && dbg_cnt (delete_trivial_dead))
7152*38fd1498Szrj 	{
7153*38fd1498Szrj 	  if (DEBUG_INSN_P (insn))
7154*38fd1498Szrj 	    {
7155*38fd1498Szrj 	      if (DEBUG_BIND_INSN_P (insn))
7156*38fd1498Szrj 		count_reg_usage (INSN_VAR_LOCATION_LOC (insn), counts + nreg,
7157*38fd1498Szrj 				 NULL_RTX, -1);
7158*38fd1498Szrj 	    }
7159*38fd1498Szrj 	  else
7160*38fd1498Szrj 	    {
7161*38fd1498Szrj 	      rtx set;
7162*38fd1498Szrj 	      if (MAY_HAVE_DEBUG_BIND_INSNS
7163*38fd1498Szrj 		  && (set = single_set (insn)) != NULL_RTX
7164*38fd1498Szrj 		  && is_dead_reg (SET_DEST (set), counts)
7165*38fd1498Szrj 		  /* Used at least once in some DEBUG_INSN.  */
7166*38fd1498Szrj 		  && counts[REGNO (SET_DEST (set)) + nreg] > 0
7167*38fd1498Szrj 		  /* And set exactly once.  */
7168*38fd1498Szrj 		  && counts[REGNO (SET_DEST (set)) + nreg * 2] == 1
7169*38fd1498Szrj 		  && !side_effects_p (SET_SRC (set))
7170*38fd1498Szrj 		  && asm_noperands (PATTERN (insn)) < 0)
7171*38fd1498Szrj 		{
7172*38fd1498Szrj 		  rtx dval, bind_var_loc;
7173*38fd1498Szrj 		  rtx_insn *bind;
7174*38fd1498Szrj 
7175*38fd1498Szrj 		  /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL).  */
7176*38fd1498Szrj 		  dval = make_debug_expr_from_rtl (SET_DEST (set));
7177*38fd1498Szrj 
7178*38fd1498Szrj 		  /* Emit a debug bind insn before the insn in which
7179*38fd1498Szrj 		     reg dies.  */
7180*38fd1498Szrj 		  bind_var_loc =
7181*38fd1498Szrj 		    gen_rtx_VAR_LOCATION (GET_MODE (SET_DEST (set)),
7182*38fd1498Szrj 					  DEBUG_EXPR_TREE_DECL (dval),
7183*38fd1498Szrj 					  SET_SRC (set),
7184*38fd1498Szrj 					  VAR_INIT_STATUS_INITIALIZED);
7185*38fd1498Szrj 		  count_reg_usage (bind_var_loc, counts + nreg, NULL_RTX, 1);
7186*38fd1498Szrj 
7187*38fd1498Szrj 		  bind = emit_debug_insn_before (bind_var_loc, insn);
7188*38fd1498Szrj 		  df_insn_rescan (bind);
7189*38fd1498Szrj 
7190*38fd1498Szrj 		  if (replacements == NULL)
7191*38fd1498Szrj 		    replacements = XCNEWVEC (rtx, nreg);
7192*38fd1498Szrj 		  replacements[REGNO (SET_DEST (set))] = dval;
7193*38fd1498Szrj 		}
7194*38fd1498Szrj 
7195*38fd1498Szrj 	      count_reg_usage (insn, counts, NULL_RTX, -1);
7196*38fd1498Szrj 	      ndead++;
7197*38fd1498Szrj 	    }
7198*38fd1498Szrj 	  cse_cfg_altered |= delete_insn_and_edges (insn);
7199*38fd1498Szrj 	}
7200*38fd1498Szrj     }
7201*38fd1498Szrj 
7202*38fd1498Szrj   if (MAY_HAVE_DEBUG_BIND_INSNS)
7203*38fd1498Szrj     {
7204*38fd1498Szrj       for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
7205*38fd1498Szrj 	if (DEBUG_BIND_INSN_P (insn))
7206*38fd1498Szrj 	  {
7207*38fd1498Szrj 	    /* If this debug insn references a dead register that wasn't replaced
7208*38fd1498Szrj 	       with an DEBUG_EXPR, reset the DEBUG_INSN.  */
7209*38fd1498Szrj 	    bool seen_repl = false;
7210*38fd1498Szrj 	    if (is_dead_debug_insn (INSN_VAR_LOCATION_LOC (insn),
7211*38fd1498Szrj 				    counts, replacements, &seen_repl))
7212*38fd1498Szrj 	      {
7213*38fd1498Szrj 		INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
7214*38fd1498Szrj 		df_insn_rescan (insn);
7215*38fd1498Szrj 	      }
7216*38fd1498Szrj 	    else if (seen_repl)
7217*38fd1498Szrj 	      {
7218*38fd1498Szrj 		INSN_VAR_LOCATION_LOC (insn)
7219*38fd1498Szrj 		  = simplify_replace_fn_rtx (INSN_VAR_LOCATION_LOC (insn),
7220*38fd1498Szrj 					     NULL_RTX, replace_dead_reg,
7221*38fd1498Szrj 					     replacements);
7222*38fd1498Szrj 		df_insn_rescan (insn);
7223*38fd1498Szrj 	      }
7224*38fd1498Szrj 	  }
7225*38fd1498Szrj       free (replacements);
7226*38fd1498Szrj     }
7227*38fd1498Szrj 
7228*38fd1498Szrj   if (dump_file && ndead)
7229*38fd1498Szrj     fprintf (dump_file, "Deleted %i trivially dead insns\n",
7230*38fd1498Szrj 	     ndead);
7231*38fd1498Szrj   /* Clean up.  */
7232*38fd1498Szrj   free (counts);
7233*38fd1498Szrj   timevar_pop (TV_DELETE_TRIVIALLY_DEAD);
7234*38fd1498Szrj   return ndead;
7235*38fd1498Szrj }
7236*38fd1498Szrj 
7237*38fd1498Szrj /* If LOC contains references to NEWREG in a different mode, change them
7238*38fd1498Szrj    to use NEWREG instead.  */
7239*38fd1498Szrj 
7240*38fd1498Szrj static void
cse_change_cc_mode(subrtx_ptr_iterator::array_type & array,rtx * loc,rtx_insn * insn,rtx newreg)7241*38fd1498Szrj cse_change_cc_mode (subrtx_ptr_iterator::array_type &array,
7242*38fd1498Szrj 		    rtx *loc, rtx_insn *insn, rtx newreg)
7243*38fd1498Szrj {
7244*38fd1498Szrj   FOR_EACH_SUBRTX_PTR (iter, array, loc, NONCONST)
7245*38fd1498Szrj     {
7246*38fd1498Szrj       rtx *loc = *iter;
7247*38fd1498Szrj       rtx x = *loc;
7248*38fd1498Szrj       if (x
7249*38fd1498Szrj 	  && REG_P (x)
7250*38fd1498Szrj 	  && REGNO (x) == REGNO (newreg)
7251*38fd1498Szrj 	  && GET_MODE (x) != GET_MODE (newreg))
7252*38fd1498Szrj 	{
7253*38fd1498Szrj 	  validate_change (insn, loc, newreg, 1);
7254*38fd1498Szrj 	  iter.skip_subrtxes ();
7255*38fd1498Szrj 	}
7256*38fd1498Szrj     }
7257*38fd1498Szrj }
7258*38fd1498Szrj 
7259*38fd1498Szrj /* Change the mode of any reference to the register REGNO (NEWREG) to
7260*38fd1498Szrj    GET_MODE (NEWREG) in INSN.  */
7261*38fd1498Szrj 
7262*38fd1498Szrj static void
cse_change_cc_mode_insn(rtx_insn * insn,rtx newreg)7263*38fd1498Szrj cse_change_cc_mode_insn (rtx_insn *insn, rtx newreg)
7264*38fd1498Szrj {
7265*38fd1498Szrj   int success;
7266*38fd1498Szrj 
7267*38fd1498Szrj   if (!INSN_P (insn))
7268*38fd1498Szrj     return;
7269*38fd1498Szrj 
7270*38fd1498Szrj   subrtx_ptr_iterator::array_type array;
7271*38fd1498Szrj   cse_change_cc_mode (array, &PATTERN (insn), insn, newreg);
7272*38fd1498Szrj   cse_change_cc_mode (array, &REG_NOTES (insn), insn, newreg);
7273*38fd1498Szrj 
7274*38fd1498Szrj   /* If the following assertion was triggered, there is most probably
7275*38fd1498Szrj      something wrong with the cc_modes_compatible back end function.
7276*38fd1498Szrj      CC modes only can be considered compatible if the insn - with the mode
7277*38fd1498Szrj      replaced by any of the compatible modes - can still be recognized.  */
7278*38fd1498Szrj   success = apply_change_group ();
7279*38fd1498Szrj   gcc_assert (success);
7280*38fd1498Szrj }
7281*38fd1498Szrj 
7282*38fd1498Szrj /* Change the mode of any reference to the register REGNO (NEWREG) to
7283*38fd1498Szrj    GET_MODE (NEWREG), starting at START.  Stop before END.  Stop at
7284*38fd1498Szrj    any instruction which modifies NEWREG.  */
7285*38fd1498Szrj 
7286*38fd1498Szrj static void
cse_change_cc_mode_insns(rtx_insn * start,rtx_insn * end,rtx newreg)7287*38fd1498Szrj cse_change_cc_mode_insns (rtx_insn *start, rtx_insn *end, rtx newreg)
7288*38fd1498Szrj {
7289*38fd1498Szrj   rtx_insn *insn;
7290*38fd1498Szrj 
7291*38fd1498Szrj   for (insn = start; insn != end; insn = NEXT_INSN (insn))
7292*38fd1498Szrj     {
7293*38fd1498Szrj       if (! INSN_P (insn))
7294*38fd1498Szrj 	continue;
7295*38fd1498Szrj 
7296*38fd1498Szrj       if (reg_set_p (newreg, insn))
7297*38fd1498Szrj 	return;
7298*38fd1498Szrj 
7299*38fd1498Szrj       cse_change_cc_mode_insn (insn, newreg);
7300*38fd1498Szrj     }
7301*38fd1498Szrj }
7302*38fd1498Szrj 
7303*38fd1498Szrj /* BB is a basic block which finishes with CC_REG as a condition code
7304*38fd1498Szrj    register which is set to CC_SRC.  Look through the successors of BB
7305*38fd1498Szrj    to find blocks which have a single predecessor (i.e., this one),
7306*38fd1498Szrj    and look through those blocks for an assignment to CC_REG which is
7307*38fd1498Szrj    equivalent to CC_SRC.  CAN_CHANGE_MODE indicates whether we are
7308*38fd1498Szrj    permitted to change the mode of CC_SRC to a compatible mode.  This
7309*38fd1498Szrj    returns VOIDmode if no equivalent assignments were found.
7310*38fd1498Szrj    Otherwise it returns the mode which CC_SRC should wind up with.
7311*38fd1498Szrj    ORIG_BB should be the same as BB in the outermost cse_cc_succs call,
7312*38fd1498Szrj    but is passed unmodified down to recursive calls in order to prevent
7313*38fd1498Szrj    endless recursion.
7314*38fd1498Szrj 
7315*38fd1498Szrj    The main complexity in this function is handling the mode issues.
7316*38fd1498Szrj    We may have more than one duplicate which we can eliminate, and we
7317*38fd1498Szrj    try to find a mode which will work for multiple duplicates.  */
7318*38fd1498Szrj 
7319*38fd1498Szrj static machine_mode
cse_cc_succs(basic_block bb,basic_block orig_bb,rtx cc_reg,rtx cc_src,bool can_change_mode)7320*38fd1498Szrj cse_cc_succs (basic_block bb, basic_block orig_bb, rtx cc_reg, rtx cc_src,
7321*38fd1498Szrj 	      bool can_change_mode)
7322*38fd1498Szrj {
7323*38fd1498Szrj   bool found_equiv;
7324*38fd1498Szrj   machine_mode mode;
7325*38fd1498Szrj   unsigned int insn_count;
7326*38fd1498Szrj   edge e;
7327*38fd1498Szrj   rtx_insn *insns[2];
7328*38fd1498Szrj   machine_mode modes[2];
7329*38fd1498Szrj   rtx_insn *last_insns[2];
7330*38fd1498Szrj   unsigned int i;
7331*38fd1498Szrj   rtx newreg;
7332*38fd1498Szrj   edge_iterator ei;
7333*38fd1498Szrj 
7334*38fd1498Szrj   /* We expect to have two successors.  Look at both before picking
7335*38fd1498Szrj      the final mode for the comparison.  If we have more successors
7336*38fd1498Szrj      (i.e., some sort of table jump, although that seems unlikely),
7337*38fd1498Szrj      then we require all beyond the first two to use the same
7338*38fd1498Szrj      mode.  */
7339*38fd1498Szrj 
7340*38fd1498Szrj   found_equiv = false;
7341*38fd1498Szrj   mode = GET_MODE (cc_src);
7342*38fd1498Szrj   insn_count = 0;
7343*38fd1498Szrj   FOR_EACH_EDGE (e, ei, bb->succs)
7344*38fd1498Szrj     {
7345*38fd1498Szrj       rtx_insn *insn;
7346*38fd1498Szrj       rtx_insn *end;
7347*38fd1498Szrj 
7348*38fd1498Szrj       if (e->flags & EDGE_COMPLEX)
7349*38fd1498Szrj 	continue;
7350*38fd1498Szrj 
7351*38fd1498Szrj       if (EDGE_COUNT (e->dest->preds) != 1
7352*38fd1498Szrj 	  || e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun)
7353*38fd1498Szrj 	  /* Avoid endless recursion on unreachable blocks.  */
7354*38fd1498Szrj 	  || e->dest == orig_bb)
7355*38fd1498Szrj 	continue;
7356*38fd1498Szrj 
7357*38fd1498Szrj       end = NEXT_INSN (BB_END (e->dest));
7358*38fd1498Szrj       for (insn = BB_HEAD (e->dest); insn != end; insn = NEXT_INSN (insn))
7359*38fd1498Szrj 	{
7360*38fd1498Szrj 	  rtx set;
7361*38fd1498Szrj 
7362*38fd1498Szrj 	  if (! INSN_P (insn))
7363*38fd1498Szrj 	    continue;
7364*38fd1498Szrj 
7365*38fd1498Szrj 	  /* If CC_SRC is modified, we have to stop looking for
7366*38fd1498Szrj 	     something which uses it.  */
7367*38fd1498Szrj 	  if (modified_in_p (cc_src, insn))
7368*38fd1498Szrj 	    break;
7369*38fd1498Szrj 
7370*38fd1498Szrj 	  /* Check whether INSN sets CC_REG to CC_SRC.  */
7371*38fd1498Szrj 	  set = single_set (insn);
7372*38fd1498Szrj 	  if (set
7373*38fd1498Szrj 	      && REG_P (SET_DEST (set))
7374*38fd1498Szrj 	      && REGNO (SET_DEST (set)) == REGNO (cc_reg))
7375*38fd1498Szrj 	    {
7376*38fd1498Szrj 	      bool found;
7377*38fd1498Szrj 	      machine_mode set_mode;
7378*38fd1498Szrj 	      machine_mode comp_mode;
7379*38fd1498Szrj 
7380*38fd1498Szrj 	      found = false;
7381*38fd1498Szrj 	      set_mode = GET_MODE (SET_SRC (set));
7382*38fd1498Szrj 	      comp_mode = set_mode;
7383*38fd1498Szrj 	      if (rtx_equal_p (cc_src, SET_SRC (set)))
7384*38fd1498Szrj 		found = true;
7385*38fd1498Szrj 	      else if (GET_CODE (cc_src) == COMPARE
7386*38fd1498Szrj 		       && GET_CODE (SET_SRC (set)) == COMPARE
7387*38fd1498Szrj 		       && mode != set_mode
7388*38fd1498Szrj 		       && rtx_equal_p (XEXP (cc_src, 0),
7389*38fd1498Szrj 				       XEXP (SET_SRC (set), 0))
7390*38fd1498Szrj 		       && rtx_equal_p (XEXP (cc_src, 1),
7391*38fd1498Szrj 				       XEXP (SET_SRC (set), 1)))
7392*38fd1498Szrj 
7393*38fd1498Szrj 		{
7394*38fd1498Szrj 		  comp_mode = targetm.cc_modes_compatible (mode, set_mode);
7395*38fd1498Szrj 		  if (comp_mode != VOIDmode
7396*38fd1498Szrj 		      && (can_change_mode || comp_mode == mode))
7397*38fd1498Szrj 		    found = true;
7398*38fd1498Szrj 		}
7399*38fd1498Szrj 
7400*38fd1498Szrj 	      if (found)
7401*38fd1498Szrj 		{
7402*38fd1498Szrj 		  found_equiv = true;
7403*38fd1498Szrj 		  if (insn_count < ARRAY_SIZE (insns))
7404*38fd1498Szrj 		    {
7405*38fd1498Szrj 		      insns[insn_count] = insn;
7406*38fd1498Szrj 		      modes[insn_count] = set_mode;
7407*38fd1498Szrj 		      last_insns[insn_count] = end;
7408*38fd1498Szrj 		      ++insn_count;
7409*38fd1498Szrj 
7410*38fd1498Szrj 		      if (mode != comp_mode)
7411*38fd1498Szrj 			{
7412*38fd1498Szrj 			  gcc_assert (can_change_mode);
7413*38fd1498Szrj 			  mode = comp_mode;
7414*38fd1498Szrj 
7415*38fd1498Szrj 			  /* The modified insn will be re-recognized later.  */
7416*38fd1498Szrj 			  PUT_MODE (cc_src, mode);
7417*38fd1498Szrj 			}
7418*38fd1498Szrj 		    }
7419*38fd1498Szrj 		  else
7420*38fd1498Szrj 		    {
7421*38fd1498Szrj 		      if (set_mode != mode)
7422*38fd1498Szrj 			{
7423*38fd1498Szrj 			  /* We found a matching expression in the
7424*38fd1498Szrj 			     wrong mode, but we don't have room to
7425*38fd1498Szrj 			     store it in the array.  Punt.  This case
7426*38fd1498Szrj 			     should be rare.  */
7427*38fd1498Szrj 			  break;
7428*38fd1498Szrj 			}
7429*38fd1498Szrj 		      /* INSN sets CC_REG to a value equal to CC_SRC
7430*38fd1498Szrj 			 with the right mode.  We can simply delete
7431*38fd1498Szrj 			 it.  */
7432*38fd1498Szrj 		      delete_insn (insn);
7433*38fd1498Szrj 		    }
7434*38fd1498Szrj 
7435*38fd1498Szrj 		  /* We found an instruction to delete.  Keep looking,
7436*38fd1498Szrj 		     in the hopes of finding a three-way jump.  */
7437*38fd1498Szrj 		  continue;
7438*38fd1498Szrj 		}
7439*38fd1498Szrj 
7440*38fd1498Szrj 	      /* We found an instruction which sets the condition
7441*38fd1498Szrj 		 code, so don't look any farther.  */
7442*38fd1498Szrj 	      break;
7443*38fd1498Szrj 	    }
7444*38fd1498Szrj 
7445*38fd1498Szrj 	  /* If INSN sets CC_REG in some other way, don't look any
7446*38fd1498Szrj 	     farther.  */
7447*38fd1498Szrj 	  if (reg_set_p (cc_reg, insn))
7448*38fd1498Szrj 	    break;
7449*38fd1498Szrj 	}
7450*38fd1498Szrj 
7451*38fd1498Szrj       /* If we fell off the bottom of the block, we can keep looking
7452*38fd1498Szrj 	 through successors.  We pass CAN_CHANGE_MODE as false because
7453*38fd1498Szrj 	 we aren't prepared to handle compatibility between the
7454*38fd1498Szrj 	 further blocks and this block.  */
7455*38fd1498Szrj       if (insn == end)
7456*38fd1498Szrj 	{
7457*38fd1498Szrj 	  machine_mode submode;
7458*38fd1498Szrj 
7459*38fd1498Szrj 	  submode = cse_cc_succs (e->dest, orig_bb, cc_reg, cc_src, false);
7460*38fd1498Szrj 	  if (submode != VOIDmode)
7461*38fd1498Szrj 	    {
7462*38fd1498Szrj 	      gcc_assert (submode == mode);
7463*38fd1498Szrj 	      found_equiv = true;
7464*38fd1498Szrj 	      can_change_mode = false;
7465*38fd1498Szrj 	    }
7466*38fd1498Szrj 	}
7467*38fd1498Szrj     }
7468*38fd1498Szrj 
7469*38fd1498Szrj   if (! found_equiv)
7470*38fd1498Szrj     return VOIDmode;
7471*38fd1498Szrj 
7472*38fd1498Szrj   /* Now INSN_COUNT is the number of instructions we found which set
7473*38fd1498Szrj      CC_REG to a value equivalent to CC_SRC.  The instructions are in
7474*38fd1498Szrj      INSNS.  The modes used by those instructions are in MODES.  */
7475*38fd1498Szrj 
7476*38fd1498Szrj   newreg = NULL_RTX;
7477*38fd1498Szrj   for (i = 0; i < insn_count; ++i)
7478*38fd1498Szrj     {
7479*38fd1498Szrj       if (modes[i] != mode)
7480*38fd1498Szrj 	{
7481*38fd1498Szrj 	  /* We need to change the mode of CC_REG in INSNS[i] and
7482*38fd1498Szrj 	     subsequent instructions.  */
7483*38fd1498Szrj 	  if (! newreg)
7484*38fd1498Szrj 	    {
7485*38fd1498Szrj 	      if (GET_MODE (cc_reg) == mode)
7486*38fd1498Szrj 		newreg = cc_reg;
7487*38fd1498Szrj 	      else
7488*38fd1498Szrj 		newreg = gen_rtx_REG (mode, REGNO (cc_reg));
7489*38fd1498Szrj 	    }
7490*38fd1498Szrj 	  cse_change_cc_mode_insns (NEXT_INSN (insns[i]), last_insns[i],
7491*38fd1498Szrj 				    newreg);
7492*38fd1498Szrj 	}
7493*38fd1498Szrj 
7494*38fd1498Szrj       cse_cfg_altered |= delete_insn_and_edges (insns[i]);
7495*38fd1498Szrj     }
7496*38fd1498Szrj 
7497*38fd1498Szrj   return mode;
7498*38fd1498Szrj }
7499*38fd1498Szrj 
7500*38fd1498Szrj /* If we have a fixed condition code register (or two), walk through
7501*38fd1498Szrj    the instructions and try to eliminate duplicate assignments.  */
7502*38fd1498Szrj 
7503*38fd1498Szrj static void
cse_condition_code_reg(void)7504*38fd1498Szrj cse_condition_code_reg (void)
7505*38fd1498Szrj {
7506*38fd1498Szrj   unsigned int cc_regno_1;
7507*38fd1498Szrj   unsigned int cc_regno_2;
7508*38fd1498Szrj   rtx cc_reg_1;
7509*38fd1498Szrj   rtx cc_reg_2;
7510*38fd1498Szrj   basic_block bb;
7511*38fd1498Szrj 
7512*38fd1498Szrj   if (! targetm.fixed_condition_code_regs (&cc_regno_1, &cc_regno_2))
7513*38fd1498Szrj     return;
7514*38fd1498Szrj 
7515*38fd1498Szrj   cc_reg_1 = gen_rtx_REG (CCmode, cc_regno_1);
7516*38fd1498Szrj   if (cc_regno_2 != INVALID_REGNUM)
7517*38fd1498Szrj     cc_reg_2 = gen_rtx_REG (CCmode, cc_regno_2);
7518*38fd1498Szrj   else
7519*38fd1498Szrj     cc_reg_2 = NULL_RTX;
7520*38fd1498Szrj 
7521*38fd1498Szrj   FOR_EACH_BB_FN (bb, cfun)
7522*38fd1498Szrj     {
7523*38fd1498Szrj       rtx_insn *last_insn;
7524*38fd1498Szrj       rtx cc_reg;
7525*38fd1498Szrj       rtx_insn *insn;
7526*38fd1498Szrj       rtx_insn *cc_src_insn;
7527*38fd1498Szrj       rtx cc_src;
7528*38fd1498Szrj       machine_mode mode;
7529*38fd1498Szrj       machine_mode orig_mode;
7530*38fd1498Szrj 
7531*38fd1498Szrj       /* Look for blocks which end with a conditional jump based on a
7532*38fd1498Szrj 	 condition code register.  Then look for the instruction which
7533*38fd1498Szrj 	 sets the condition code register.  Then look through the
7534*38fd1498Szrj 	 successor blocks for instructions which set the condition
7535*38fd1498Szrj 	 code register to the same value.  There are other possible
7536*38fd1498Szrj 	 uses of the condition code register, but these are by far the
7537*38fd1498Szrj 	 most common and the ones which we are most likely to be able
7538*38fd1498Szrj 	 to optimize.  */
7539*38fd1498Szrj 
7540*38fd1498Szrj       last_insn = BB_END (bb);
7541*38fd1498Szrj       if (!JUMP_P (last_insn))
7542*38fd1498Szrj 	continue;
7543*38fd1498Szrj 
7544*38fd1498Szrj       if (reg_referenced_p (cc_reg_1, PATTERN (last_insn)))
7545*38fd1498Szrj 	cc_reg = cc_reg_1;
7546*38fd1498Szrj       else if (cc_reg_2 && reg_referenced_p (cc_reg_2, PATTERN (last_insn)))
7547*38fd1498Szrj 	cc_reg = cc_reg_2;
7548*38fd1498Szrj       else
7549*38fd1498Szrj 	continue;
7550*38fd1498Szrj 
7551*38fd1498Szrj       cc_src_insn = NULL;
7552*38fd1498Szrj       cc_src = NULL_RTX;
7553*38fd1498Szrj       for (insn = PREV_INSN (last_insn);
7554*38fd1498Szrj 	   insn && insn != PREV_INSN (BB_HEAD (bb));
7555*38fd1498Szrj 	   insn = PREV_INSN (insn))
7556*38fd1498Szrj 	{
7557*38fd1498Szrj 	  rtx set;
7558*38fd1498Szrj 
7559*38fd1498Szrj 	  if (! INSN_P (insn))
7560*38fd1498Szrj 	    continue;
7561*38fd1498Szrj 	  set = single_set (insn);
7562*38fd1498Szrj 	  if (set
7563*38fd1498Szrj 	      && REG_P (SET_DEST (set))
7564*38fd1498Szrj 	      && REGNO (SET_DEST (set)) == REGNO (cc_reg))
7565*38fd1498Szrj 	    {
7566*38fd1498Szrj 	      cc_src_insn = insn;
7567*38fd1498Szrj 	      cc_src = SET_SRC (set);
7568*38fd1498Szrj 	      break;
7569*38fd1498Szrj 	    }
7570*38fd1498Szrj 	  else if (reg_set_p (cc_reg, insn))
7571*38fd1498Szrj 	    break;
7572*38fd1498Szrj 	}
7573*38fd1498Szrj 
7574*38fd1498Szrj       if (! cc_src_insn)
7575*38fd1498Szrj 	continue;
7576*38fd1498Szrj 
7577*38fd1498Szrj       if (modified_between_p (cc_src, cc_src_insn, NEXT_INSN (last_insn)))
7578*38fd1498Szrj 	continue;
7579*38fd1498Szrj 
7580*38fd1498Szrj       /* Now CC_REG is a condition code register used for a
7581*38fd1498Szrj 	 conditional jump at the end of the block, and CC_SRC, in
7582*38fd1498Szrj 	 CC_SRC_INSN, is the value to which that condition code
7583*38fd1498Szrj 	 register is set, and CC_SRC is still meaningful at the end of
7584*38fd1498Szrj 	 the basic block.  */
7585*38fd1498Szrj 
7586*38fd1498Szrj       orig_mode = GET_MODE (cc_src);
7587*38fd1498Szrj       mode = cse_cc_succs (bb, bb, cc_reg, cc_src, true);
7588*38fd1498Szrj       if (mode != VOIDmode)
7589*38fd1498Szrj 	{
7590*38fd1498Szrj 	  gcc_assert (mode == GET_MODE (cc_src));
7591*38fd1498Szrj 	  if (mode != orig_mode)
7592*38fd1498Szrj 	    {
7593*38fd1498Szrj 	      rtx newreg = gen_rtx_REG (mode, REGNO (cc_reg));
7594*38fd1498Szrj 
7595*38fd1498Szrj 	      cse_change_cc_mode_insn (cc_src_insn, newreg);
7596*38fd1498Szrj 
7597*38fd1498Szrj 	      /* Do the same in the following insns that use the
7598*38fd1498Szrj 		 current value of CC_REG within BB.  */
7599*38fd1498Szrj 	      cse_change_cc_mode_insns (NEXT_INSN (cc_src_insn),
7600*38fd1498Szrj 					NEXT_INSN (last_insn),
7601*38fd1498Szrj 					newreg);
7602*38fd1498Szrj 	    }
7603*38fd1498Szrj 	}
7604*38fd1498Szrj     }
7605*38fd1498Szrj }
7606*38fd1498Szrj 
7607*38fd1498Szrj 
7608*38fd1498Szrj /* Perform common subexpression elimination.  Nonzero value from
7609*38fd1498Szrj    `cse_main' means that jumps were simplified and some code may now
7610*38fd1498Szrj    be unreachable, so do jump optimization again.  */
7611*38fd1498Szrj static unsigned int
rest_of_handle_cse(void)7612*38fd1498Szrj rest_of_handle_cse (void)
7613*38fd1498Szrj {
7614*38fd1498Szrj   int tem;
7615*38fd1498Szrj 
7616*38fd1498Szrj   if (dump_file)
7617*38fd1498Szrj     dump_flow_info (dump_file, dump_flags);
7618*38fd1498Szrj 
7619*38fd1498Szrj   tem = cse_main (get_insns (), max_reg_num ());
7620*38fd1498Szrj 
7621*38fd1498Szrj   /* If we are not running more CSE passes, then we are no longer
7622*38fd1498Szrj      expecting CSE to be run.  But always rerun it in a cheap mode.  */
7623*38fd1498Szrj   cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse;
7624*38fd1498Szrj 
7625*38fd1498Szrj   if (tem == 2)
7626*38fd1498Szrj     {
7627*38fd1498Szrj       timevar_push (TV_JUMP);
7628*38fd1498Szrj       rebuild_jump_labels (get_insns ());
7629*38fd1498Szrj       cse_cfg_altered |= cleanup_cfg (CLEANUP_CFG_CHANGED);
7630*38fd1498Szrj       timevar_pop (TV_JUMP);
7631*38fd1498Szrj     }
7632*38fd1498Szrj   else if (tem == 1 || optimize > 1)
7633*38fd1498Szrj     cse_cfg_altered |= cleanup_cfg (0);
7634*38fd1498Szrj 
7635*38fd1498Szrj   return 0;
7636*38fd1498Szrj }
7637*38fd1498Szrj 
7638*38fd1498Szrj namespace {
7639*38fd1498Szrj 
7640*38fd1498Szrj const pass_data pass_data_cse =
7641*38fd1498Szrj {
7642*38fd1498Szrj   RTL_PASS, /* type */
7643*38fd1498Szrj   "cse1", /* name */
7644*38fd1498Szrj   OPTGROUP_NONE, /* optinfo_flags */
7645*38fd1498Szrj   TV_CSE, /* tv_id */
7646*38fd1498Szrj   0, /* properties_required */
7647*38fd1498Szrj   0, /* properties_provided */
7648*38fd1498Szrj   0, /* properties_destroyed */
7649*38fd1498Szrj   0, /* todo_flags_start */
7650*38fd1498Szrj   TODO_df_finish, /* todo_flags_finish */
7651*38fd1498Szrj };
7652*38fd1498Szrj 
7653*38fd1498Szrj class pass_cse : public rtl_opt_pass
7654*38fd1498Szrj {
7655*38fd1498Szrj public:
pass_cse(gcc::context * ctxt)7656*38fd1498Szrj   pass_cse (gcc::context *ctxt)
7657*38fd1498Szrj     : rtl_opt_pass (pass_data_cse, ctxt)
7658*38fd1498Szrj   {}
7659*38fd1498Szrj 
7660*38fd1498Szrj   /* opt_pass methods: */
gate(function *)7661*38fd1498Szrj   virtual bool gate (function *) { return optimize > 0; }
execute(function *)7662*38fd1498Szrj   virtual unsigned int execute (function *) { return rest_of_handle_cse (); }
7663*38fd1498Szrj 
7664*38fd1498Szrj }; // class pass_cse
7665*38fd1498Szrj 
7666*38fd1498Szrj } // anon namespace
7667*38fd1498Szrj 
7668*38fd1498Szrj rtl_opt_pass *
make_pass_cse(gcc::context * ctxt)7669*38fd1498Szrj make_pass_cse (gcc::context *ctxt)
7670*38fd1498Szrj {
7671*38fd1498Szrj   return new pass_cse (ctxt);
7672*38fd1498Szrj }
7673*38fd1498Szrj 
7674*38fd1498Szrj 
7675*38fd1498Szrj /* Run second CSE pass after loop optimizations.  */
7676*38fd1498Szrj static unsigned int
rest_of_handle_cse2(void)7677*38fd1498Szrj rest_of_handle_cse2 (void)
7678*38fd1498Szrj {
7679*38fd1498Szrj   int tem;
7680*38fd1498Szrj 
7681*38fd1498Szrj   if (dump_file)
7682*38fd1498Szrj     dump_flow_info (dump_file, dump_flags);
7683*38fd1498Szrj 
7684*38fd1498Szrj   tem = cse_main (get_insns (), max_reg_num ());
7685*38fd1498Szrj 
7686*38fd1498Szrj   /* Run a pass to eliminate duplicated assignments to condition code
7687*38fd1498Szrj      registers.  We have to run this after bypass_jumps, because it
7688*38fd1498Szrj      makes it harder for that pass to determine whether a jump can be
7689*38fd1498Szrj      bypassed safely.  */
7690*38fd1498Szrj   cse_condition_code_reg ();
7691*38fd1498Szrj 
7692*38fd1498Szrj   delete_trivially_dead_insns (get_insns (), max_reg_num ());
7693*38fd1498Szrj 
7694*38fd1498Szrj   if (tem == 2)
7695*38fd1498Szrj     {
7696*38fd1498Szrj       timevar_push (TV_JUMP);
7697*38fd1498Szrj       rebuild_jump_labels (get_insns ());
7698*38fd1498Szrj       cse_cfg_altered |= cleanup_cfg (CLEANUP_CFG_CHANGED);
7699*38fd1498Szrj       timevar_pop (TV_JUMP);
7700*38fd1498Szrj     }
7701*38fd1498Szrj   else if (tem == 1)
7702*38fd1498Szrj     cse_cfg_altered |= cleanup_cfg (0);
7703*38fd1498Szrj 
7704*38fd1498Szrj   cse_not_expected = 1;
7705*38fd1498Szrj   return 0;
7706*38fd1498Szrj }
7707*38fd1498Szrj 
7708*38fd1498Szrj 
7709*38fd1498Szrj namespace {
7710*38fd1498Szrj 
7711*38fd1498Szrj const pass_data pass_data_cse2 =
7712*38fd1498Szrj {
7713*38fd1498Szrj   RTL_PASS, /* type */
7714*38fd1498Szrj   "cse2", /* name */
7715*38fd1498Szrj   OPTGROUP_NONE, /* optinfo_flags */
7716*38fd1498Szrj   TV_CSE2, /* tv_id */
7717*38fd1498Szrj   0, /* properties_required */
7718*38fd1498Szrj   0, /* properties_provided */
7719*38fd1498Szrj   0, /* properties_destroyed */
7720*38fd1498Szrj   0, /* todo_flags_start */
7721*38fd1498Szrj   TODO_df_finish, /* todo_flags_finish */
7722*38fd1498Szrj };
7723*38fd1498Szrj 
7724*38fd1498Szrj class pass_cse2 : public rtl_opt_pass
7725*38fd1498Szrj {
7726*38fd1498Szrj public:
pass_cse2(gcc::context * ctxt)7727*38fd1498Szrj   pass_cse2 (gcc::context *ctxt)
7728*38fd1498Szrj     : rtl_opt_pass (pass_data_cse2, ctxt)
7729*38fd1498Szrj   {}
7730*38fd1498Szrj 
7731*38fd1498Szrj   /* opt_pass methods: */
gate(function *)7732*38fd1498Szrj   virtual bool gate (function *)
7733*38fd1498Szrj     {
7734*38fd1498Szrj       return optimize > 0 && flag_rerun_cse_after_loop;
7735*38fd1498Szrj     }
7736*38fd1498Szrj 
execute(function *)7737*38fd1498Szrj   virtual unsigned int execute (function *) { return rest_of_handle_cse2 (); }
7738*38fd1498Szrj 
7739*38fd1498Szrj }; // class pass_cse2
7740*38fd1498Szrj 
7741*38fd1498Szrj } // anon namespace
7742*38fd1498Szrj 
7743*38fd1498Szrj rtl_opt_pass *
make_pass_cse2(gcc::context * ctxt)7744*38fd1498Szrj make_pass_cse2 (gcc::context *ctxt)
7745*38fd1498Szrj {
7746*38fd1498Szrj   return new pass_cse2 (ctxt);
7747*38fd1498Szrj }
7748*38fd1498Szrj 
7749*38fd1498Szrj /* Run second CSE pass after loop optimizations.  */
7750*38fd1498Szrj static unsigned int
rest_of_handle_cse_after_global_opts(void)7751*38fd1498Szrj rest_of_handle_cse_after_global_opts (void)
7752*38fd1498Szrj {
7753*38fd1498Szrj   int save_cfj;
7754*38fd1498Szrj   int tem;
7755*38fd1498Szrj 
7756*38fd1498Szrj   /* We only want to do local CSE, so don't follow jumps.  */
7757*38fd1498Szrj   save_cfj = flag_cse_follow_jumps;
7758*38fd1498Szrj   flag_cse_follow_jumps = 0;
7759*38fd1498Szrj 
7760*38fd1498Szrj   rebuild_jump_labels (get_insns ());
7761*38fd1498Szrj   tem = cse_main (get_insns (), max_reg_num ());
7762*38fd1498Szrj   cse_cfg_altered |= purge_all_dead_edges ();
7763*38fd1498Szrj   delete_trivially_dead_insns (get_insns (), max_reg_num ());
7764*38fd1498Szrj 
7765*38fd1498Szrj   cse_not_expected = !flag_rerun_cse_after_loop;
7766*38fd1498Szrj 
7767*38fd1498Szrj   /* If cse altered any jumps, rerun jump opts to clean things up.  */
7768*38fd1498Szrj   if (tem == 2)
7769*38fd1498Szrj     {
7770*38fd1498Szrj       timevar_push (TV_JUMP);
7771*38fd1498Szrj       rebuild_jump_labels (get_insns ());
7772*38fd1498Szrj       cse_cfg_altered |= cleanup_cfg (CLEANUP_CFG_CHANGED);
7773*38fd1498Szrj       timevar_pop (TV_JUMP);
7774*38fd1498Szrj     }
7775*38fd1498Szrj   else if (tem == 1)
7776*38fd1498Szrj     cse_cfg_altered |= cleanup_cfg (0);
7777*38fd1498Szrj 
7778*38fd1498Szrj   flag_cse_follow_jumps = save_cfj;
7779*38fd1498Szrj   return 0;
7780*38fd1498Szrj }
7781*38fd1498Szrj 
7782*38fd1498Szrj namespace {
7783*38fd1498Szrj 
7784*38fd1498Szrj const pass_data pass_data_cse_after_global_opts =
7785*38fd1498Szrj {
7786*38fd1498Szrj   RTL_PASS, /* type */
7787*38fd1498Szrj   "cse_local", /* name */
7788*38fd1498Szrj   OPTGROUP_NONE, /* optinfo_flags */
7789*38fd1498Szrj   TV_CSE, /* tv_id */
7790*38fd1498Szrj   0, /* properties_required */
7791*38fd1498Szrj   0, /* properties_provided */
7792*38fd1498Szrj   0, /* properties_destroyed */
7793*38fd1498Szrj   0, /* todo_flags_start */
7794*38fd1498Szrj   TODO_df_finish, /* todo_flags_finish */
7795*38fd1498Szrj };
7796*38fd1498Szrj 
7797*38fd1498Szrj class pass_cse_after_global_opts : public rtl_opt_pass
7798*38fd1498Szrj {
7799*38fd1498Szrj public:
pass_cse_after_global_opts(gcc::context * ctxt)7800*38fd1498Szrj   pass_cse_after_global_opts (gcc::context *ctxt)
7801*38fd1498Szrj     : rtl_opt_pass (pass_data_cse_after_global_opts, ctxt)
7802*38fd1498Szrj   {}
7803*38fd1498Szrj 
7804*38fd1498Szrj   /* opt_pass methods: */
gate(function *)7805*38fd1498Szrj   virtual bool gate (function *)
7806*38fd1498Szrj     {
7807*38fd1498Szrj       return optimize > 0 && flag_rerun_cse_after_global_opts;
7808*38fd1498Szrj     }
7809*38fd1498Szrj 
execute(function *)7810*38fd1498Szrj   virtual unsigned int execute (function *)
7811*38fd1498Szrj     {
7812*38fd1498Szrj       return rest_of_handle_cse_after_global_opts ();
7813*38fd1498Szrj     }
7814*38fd1498Szrj 
7815*38fd1498Szrj }; // class pass_cse_after_global_opts
7816*38fd1498Szrj 
7817*38fd1498Szrj } // anon namespace
7818*38fd1498Szrj 
7819*38fd1498Szrj rtl_opt_pass *
make_pass_cse_after_global_opts(gcc::context * ctxt)7820*38fd1498Szrj make_pass_cse_after_global_opts (gcc::context *ctxt)
7821*38fd1498Szrj {
7822*38fd1498Szrj   return new pass_cse_after_global_opts (ctxt);
7823*38fd1498Szrj }
7824