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 = ®_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, ®_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