1*e4b17023SJohn Marino /* RTL-level loop invariant motion.
2*e4b17023SJohn Marino Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
3*e4b17023SJohn Marino Free Software Foundation, Inc.
4*e4b17023SJohn Marino
5*e4b17023SJohn Marino This file is part of GCC.
6*e4b17023SJohn Marino
7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it
8*e4b17023SJohn Marino under the terms of the GNU General Public License as published by the
9*e4b17023SJohn Marino Free Software Foundation; either version 3, or (at your option) any
10*e4b17023SJohn Marino later version.
11*e4b17023SJohn Marino
12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT
13*e4b17023SJohn Marino ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15*e4b17023SJohn Marino for more details.
16*e4b17023SJohn Marino
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
20*e4b17023SJohn Marino
21*e4b17023SJohn Marino /* This implements the loop invariant motion pass. It is very simple
22*e4b17023SJohn Marino (no calls, no loads/stores, etc.). This should be sufficient to cleanup
23*e4b17023SJohn Marino things like address arithmetics -- other more complicated invariants should
24*e4b17023SJohn Marino be eliminated on GIMPLE either in tree-ssa-loop-im.c or in tree-ssa-pre.c.
25*e4b17023SJohn Marino
26*e4b17023SJohn Marino We proceed loop by loop -- it is simpler than trying to handle things
27*e4b17023SJohn Marino globally and should not lose much. First we inspect all sets inside loop
28*e4b17023SJohn Marino and create a dependency graph on insns (saying "to move this insn, you must
29*e4b17023SJohn Marino also move the following insns").
30*e4b17023SJohn Marino
31*e4b17023SJohn Marino We then need to determine what to move. We estimate the number of registers
32*e4b17023SJohn Marino used and move as many invariants as possible while we still have enough free
33*e4b17023SJohn Marino registers. We prefer the expensive invariants.
34*e4b17023SJohn Marino
35*e4b17023SJohn Marino Then we move the selected invariants out of the loop, creating a new
36*e4b17023SJohn Marino temporaries for them if necessary. */
37*e4b17023SJohn Marino
38*e4b17023SJohn Marino #include "config.h"
39*e4b17023SJohn Marino #include "system.h"
40*e4b17023SJohn Marino #include "coretypes.h"
41*e4b17023SJohn Marino #include "tm.h"
42*e4b17023SJohn Marino #include "hard-reg-set.h"
43*e4b17023SJohn Marino #include "rtl.h"
44*e4b17023SJohn Marino #include "tm_p.h"
45*e4b17023SJohn Marino #include "obstack.h"
46*e4b17023SJohn Marino #include "basic-block.h"
47*e4b17023SJohn Marino #include "cfgloop.h"
48*e4b17023SJohn Marino #include "expr.h"
49*e4b17023SJohn Marino #include "recog.h"
50*e4b17023SJohn Marino #include "output.h"
51*e4b17023SJohn Marino #include "function.h"
52*e4b17023SJohn Marino #include "flags.h"
53*e4b17023SJohn Marino #include "df.h"
54*e4b17023SJohn Marino #include "hashtab.h"
55*e4b17023SJohn Marino #include "except.h"
56*e4b17023SJohn Marino #include "params.h"
57*e4b17023SJohn Marino #include "regs.h"
58*e4b17023SJohn Marino #include "ira.h"
59*e4b17023SJohn Marino
60*e4b17023SJohn Marino /* The data stored for the loop. */
61*e4b17023SJohn Marino
62*e4b17023SJohn Marino struct loop_data
63*e4b17023SJohn Marino {
64*e4b17023SJohn Marino struct loop *outermost_exit; /* The outermost exit of the loop. */
65*e4b17023SJohn Marino bool has_call; /* True if the loop contains a call. */
66*e4b17023SJohn Marino /* Maximal register pressure inside loop for given register class
67*e4b17023SJohn Marino (defined only for the pressure classes). */
68*e4b17023SJohn Marino int max_reg_pressure[N_REG_CLASSES];
69*e4b17023SJohn Marino /* Loop regs referenced and live pseudo-registers. */
70*e4b17023SJohn Marino bitmap_head regs_ref;
71*e4b17023SJohn Marino bitmap_head regs_live;
72*e4b17023SJohn Marino };
73*e4b17023SJohn Marino
74*e4b17023SJohn Marino #define LOOP_DATA(LOOP) ((struct loop_data *) (LOOP)->aux)
75*e4b17023SJohn Marino
76*e4b17023SJohn Marino /* The description of an use. */
77*e4b17023SJohn Marino
78*e4b17023SJohn Marino struct use
79*e4b17023SJohn Marino {
80*e4b17023SJohn Marino rtx *pos; /* Position of the use. */
81*e4b17023SJohn Marino rtx insn; /* The insn in that the use occurs. */
82*e4b17023SJohn Marino unsigned addr_use_p; /* Whether the use occurs in an address. */
83*e4b17023SJohn Marino struct use *next; /* Next use in the list. */
84*e4b17023SJohn Marino };
85*e4b17023SJohn Marino
86*e4b17023SJohn Marino /* The description of a def. */
87*e4b17023SJohn Marino
88*e4b17023SJohn Marino struct def
89*e4b17023SJohn Marino {
90*e4b17023SJohn Marino struct use *uses; /* The list of uses that are uniquely reached
91*e4b17023SJohn Marino by it. */
92*e4b17023SJohn Marino unsigned n_uses; /* Number of such uses. */
93*e4b17023SJohn Marino unsigned n_addr_uses; /* Number of uses in addresses. */
94*e4b17023SJohn Marino unsigned invno; /* The corresponding invariant. */
95*e4b17023SJohn Marino };
96*e4b17023SJohn Marino
97*e4b17023SJohn Marino /* The data stored for each invariant. */
98*e4b17023SJohn Marino
99*e4b17023SJohn Marino struct invariant
100*e4b17023SJohn Marino {
101*e4b17023SJohn Marino /* The number of the invariant. */
102*e4b17023SJohn Marino unsigned invno;
103*e4b17023SJohn Marino
104*e4b17023SJohn Marino /* The number of the invariant with the same value. */
105*e4b17023SJohn Marino unsigned eqto;
106*e4b17023SJohn Marino
107*e4b17023SJohn Marino /* If we moved the invariant out of the loop, the register that contains its
108*e4b17023SJohn Marino value. */
109*e4b17023SJohn Marino rtx reg;
110*e4b17023SJohn Marino
111*e4b17023SJohn Marino /* If we moved the invariant out of the loop, the original regno
112*e4b17023SJohn Marino that contained its value. */
113*e4b17023SJohn Marino int orig_regno;
114*e4b17023SJohn Marino
115*e4b17023SJohn Marino /* The definition of the invariant. */
116*e4b17023SJohn Marino struct def *def;
117*e4b17023SJohn Marino
118*e4b17023SJohn Marino /* The insn in that it is defined. */
119*e4b17023SJohn Marino rtx insn;
120*e4b17023SJohn Marino
121*e4b17023SJohn Marino /* Whether it is always executed. */
122*e4b17023SJohn Marino bool always_executed;
123*e4b17023SJohn Marino
124*e4b17023SJohn Marino /* Whether to move the invariant. */
125*e4b17023SJohn Marino bool move;
126*e4b17023SJohn Marino
127*e4b17023SJohn Marino /* Whether the invariant is cheap when used as an address. */
128*e4b17023SJohn Marino bool cheap_address;
129*e4b17023SJohn Marino
130*e4b17023SJohn Marino /* Cost of the invariant. */
131*e4b17023SJohn Marino unsigned cost;
132*e4b17023SJohn Marino
133*e4b17023SJohn Marino /* The invariants it depends on. */
134*e4b17023SJohn Marino bitmap depends_on;
135*e4b17023SJohn Marino
136*e4b17023SJohn Marino /* Used for detecting already visited invariants during determining
137*e4b17023SJohn Marino costs of movements. */
138*e4b17023SJohn Marino unsigned stamp;
139*e4b17023SJohn Marino };
140*e4b17023SJohn Marino
141*e4b17023SJohn Marino /* Currently processed loop. */
142*e4b17023SJohn Marino static struct loop *curr_loop;
143*e4b17023SJohn Marino
144*e4b17023SJohn Marino /* Table of invariants indexed by the df_ref uid field. */
145*e4b17023SJohn Marino
146*e4b17023SJohn Marino static unsigned int invariant_table_size = 0;
147*e4b17023SJohn Marino static struct invariant ** invariant_table;
148*e4b17023SJohn Marino
149*e4b17023SJohn Marino /* Entry for hash table of invariant expressions. */
150*e4b17023SJohn Marino
151*e4b17023SJohn Marino struct invariant_expr_entry
152*e4b17023SJohn Marino {
153*e4b17023SJohn Marino /* The invariant. */
154*e4b17023SJohn Marino struct invariant *inv;
155*e4b17023SJohn Marino
156*e4b17023SJohn Marino /* Its value. */
157*e4b17023SJohn Marino rtx expr;
158*e4b17023SJohn Marino
159*e4b17023SJohn Marino /* Its mode. */
160*e4b17023SJohn Marino enum machine_mode mode;
161*e4b17023SJohn Marino
162*e4b17023SJohn Marino /* Its hash. */
163*e4b17023SJohn Marino hashval_t hash;
164*e4b17023SJohn Marino };
165*e4b17023SJohn Marino
166*e4b17023SJohn Marino /* The actual stamp for marking already visited invariants during determining
167*e4b17023SJohn Marino costs of movements. */
168*e4b17023SJohn Marino
169*e4b17023SJohn Marino static unsigned actual_stamp;
170*e4b17023SJohn Marino
171*e4b17023SJohn Marino typedef struct invariant *invariant_p;
172*e4b17023SJohn Marino
173*e4b17023SJohn Marino DEF_VEC_P(invariant_p);
174*e4b17023SJohn Marino DEF_VEC_ALLOC_P(invariant_p, heap);
175*e4b17023SJohn Marino
176*e4b17023SJohn Marino /* The invariants. */
177*e4b17023SJohn Marino
VEC(invariant_p,heap)178*e4b17023SJohn Marino static VEC(invariant_p,heap) *invariants;
179*e4b17023SJohn Marino
180*e4b17023SJohn Marino /* Check the size of the invariant table and realloc if necessary. */
181*e4b17023SJohn Marino
182*e4b17023SJohn Marino static void
183*e4b17023SJohn Marino check_invariant_table_size (void)
184*e4b17023SJohn Marino {
185*e4b17023SJohn Marino if (invariant_table_size < DF_DEFS_TABLE_SIZE())
186*e4b17023SJohn Marino {
187*e4b17023SJohn Marino unsigned int new_size = DF_DEFS_TABLE_SIZE () + (DF_DEFS_TABLE_SIZE () / 4);
188*e4b17023SJohn Marino invariant_table = XRESIZEVEC (struct invariant *, invariant_table, new_size);
189*e4b17023SJohn Marino memset (&invariant_table[invariant_table_size], 0,
190*e4b17023SJohn Marino (new_size - invariant_table_size) * sizeof (struct rtx_iv *));
191*e4b17023SJohn Marino invariant_table_size = new_size;
192*e4b17023SJohn Marino }
193*e4b17023SJohn Marino }
194*e4b17023SJohn Marino
195*e4b17023SJohn Marino /* Test for possibility of invariantness of X. */
196*e4b17023SJohn Marino
197*e4b17023SJohn Marino static bool
check_maybe_invariant(rtx x)198*e4b17023SJohn Marino check_maybe_invariant (rtx x)
199*e4b17023SJohn Marino {
200*e4b17023SJohn Marino enum rtx_code code = GET_CODE (x);
201*e4b17023SJohn Marino int i, j;
202*e4b17023SJohn Marino const char *fmt;
203*e4b17023SJohn Marino
204*e4b17023SJohn Marino switch (code)
205*e4b17023SJohn Marino {
206*e4b17023SJohn Marino case CONST_INT:
207*e4b17023SJohn Marino case CONST_DOUBLE:
208*e4b17023SJohn Marino case CONST_FIXED:
209*e4b17023SJohn Marino case SYMBOL_REF:
210*e4b17023SJohn Marino case CONST:
211*e4b17023SJohn Marino case LABEL_REF:
212*e4b17023SJohn Marino return true;
213*e4b17023SJohn Marino
214*e4b17023SJohn Marino case PC:
215*e4b17023SJohn Marino case CC0:
216*e4b17023SJohn Marino case UNSPEC_VOLATILE:
217*e4b17023SJohn Marino case CALL:
218*e4b17023SJohn Marino return false;
219*e4b17023SJohn Marino
220*e4b17023SJohn Marino case REG:
221*e4b17023SJohn Marino return true;
222*e4b17023SJohn Marino
223*e4b17023SJohn Marino case MEM:
224*e4b17023SJohn Marino /* Load/store motion is done elsewhere. ??? Perhaps also add it here?
225*e4b17023SJohn Marino It should not be hard, and might be faster than "elsewhere". */
226*e4b17023SJohn Marino
227*e4b17023SJohn Marino /* Just handle the most trivial case where we load from an unchanging
228*e4b17023SJohn Marino location (most importantly, pic tables). */
229*e4b17023SJohn Marino if (MEM_READONLY_P (x) && !MEM_VOLATILE_P (x))
230*e4b17023SJohn Marino break;
231*e4b17023SJohn Marino
232*e4b17023SJohn Marino return false;
233*e4b17023SJohn Marino
234*e4b17023SJohn Marino case ASM_OPERANDS:
235*e4b17023SJohn Marino /* Don't mess with insns declared volatile. */
236*e4b17023SJohn Marino if (MEM_VOLATILE_P (x))
237*e4b17023SJohn Marino return false;
238*e4b17023SJohn Marino break;
239*e4b17023SJohn Marino
240*e4b17023SJohn Marino default:
241*e4b17023SJohn Marino break;
242*e4b17023SJohn Marino }
243*e4b17023SJohn Marino
244*e4b17023SJohn Marino fmt = GET_RTX_FORMAT (code);
245*e4b17023SJohn Marino for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
246*e4b17023SJohn Marino {
247*e4b17023SJohn Marino if (fmt[i] == 'e')
248*e4b17023SJohn Marino {
249*e4b17023SJohn Marino if (!check_maybe_invariant (XEXP (x, i)))
250*e4b17023SJohn Marino return false;
251*e4b17023SJohn Marino }
252*e4b17023SJohn Marino else if (fmt[i] == 'E')
253*e4b17023SJohn Marino {
254*e4b17023SJohn Marino for (j = 0; j < XVECLEN (x, i); j++)
255*e4b17023SJohn Marino if (!check_maybe_invariant (XVECEXP (x, i, j)))
256*e4b17023SJohn Marino return false;
257*e4b17023SJohn Marino }
258*e4b17023SJohn Marino }
259*e4b17023SJohn Marino
260*e4b17023SJohn Marino return true;
261*e4b17023SJohn Marino }
262*e4b17023SJohn Marino
263*e4b17023SJohn Marino /* Returns the invariant definition for USE, or NULL if USE is not
264*e4b17023SJohn Marino invariant. */
265*e4b17023SJohn Marino
266*e4b17023SJohn Marino static struct invariant *
invariant_for_use(df_ref use)267*e4b17023SJohn Marino invariant_for_use (df_ref use)
268*e4b17023SJohn Marino {
269*e4b17023SJohn Marino struct df_link *defs;
270*e4b17023SJohn Marino df_ref def;
271*e4b17023SJohn Marino basic_block bb = DF_REF_BB (use), def_bb;
272*e4b17023SJohn Marino
273*e4b17023SJohn Marino if (DF_REF_FLAGS (use) & DF_REF_READ_WRITE)
274*e4b17023SJohn Marino return NULL;
275*e4b17023SJohn Marino
276*e4b17023SJohn Marino defs = DF_REF_CHAIN (use);
277*e4b17023SJohn Marino if (!defs || defs->next)
278*e4b17023SJohn Marino return NULL;
279*e4b17023SJohn Marino def = defs->ref;
280*e4b17023SJohn Marino check_invariant_table_size ();
281*e4b17023SJohn Marino if (!invariant_table[DF_REF_ID(def)])
282*e4b17023SJohn Marino return NULL;
283*e4b17023SJohn Marino
284*e4b17023SJohn Marino def_bb = DF_REF_BB (def);
285*e4b17023SJohn Marino if (!dominated_by_p (CDI_DOMINATORS, bb, def_bb))
286*e4b17023SJohn Marino return NULL;
287*e4b17023SJohn Marino return invariant_table[DF_REF_ID(def)];
288*e4b17023SJohn Marino }
289*e4b17023SJohn Marino
290*e4b17023SJohn Marino /* Computes hash value for invariant expression X in INSN. */
291*e4b17023SJohn Marino
292*e4b17023SJohn Marino static hashval_t
hash_invariant_expr_1(rtx insn,rtx x)293*e4b17023SJohn Marino hash_invariant_expr_1 (rtx insn, rtx x)
294*e4b17023SJohn Marino {
295*e4b17023SJohn Marino enum rtx_code code = GET_CODE (x);
296*e4b17023SJohn Marino int i, j;
297*e4b17023SJohn Marino const char *fmt;
298*e4b17023SJohn Marino hashval_t val = code;
299*e4b17023SJohn Marino int do_not_record_p;
300*e4b17023SJohn Marino df_ref use;
301*e4b17023SJohn Marino struct invariant *inv;
302*e4b17023SJohn Marino
303*e4b17023SJohn Marino switch (code)
304*e4b17023SJohn Marino {
305*e4b17023SJohn Marino case CONST_INT:
306*e4b17023SJohn Marino case CONST_DOUBLE:
307*e4b17023SJohn Marino case CONST_FIXED:
308*e4b17023SJohn Marino case SYMBOL_REF:
309*e4b17023SJohn Marino case CONST:
310*e4b17023SJohn Marino case LABEL_REF:
311*e4b17023SJohn Marino return hash_rtx (x, GET_MODE (x), &do_not_record_p, NULL, false);
312*e4b17023SJohn Marino
313*e4b17023SJohn Marino case REG:
314*e4b17023SJohn Marino use = df_find_use (insn, x);
315*e4b17023SJohn Marino if (!use)
316*e4b17023SJohn Marino return hash_rtx (x, GET_MODE (x), &do_not_record_p, NULL, false);
317*e4b17023SJohn Marino inv = invariant_for_use (use);
318*e4b17023SJohn Marino if (!inv)
319*e4b17023SJohn Marino return hash_rtx (x, GET_MODE (x), &do_not_record_p, NULL, false);
320*e4b17023SJohn Marino
321*e4b17023SJohn Marino gcc_assert (inv->eqto != ~0u);
322*e4b17023SJohn Marino return inv->eqto;
323*e4b17023SJohn Marino
324*e4b17023SJohn Marino default:
325*e4b17023SJohn Marino break;
326*e4b17023SJohn Marino }
327*e4b17023SJohn Marino
328*e4b17023SJohn Marino fmt = GET_RTX_FORMAT (code);
329*e4b17023SJohn Marino for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
330*e4b17023SJohn Marino {
331*e4b17023SJohn Marino if (fmt[i] == 'e')
332*e4b17023SJohn Marino val ^= hash_invariant_expr_1 (insn, XEXP (x, i));
333*e4b17023SJohn Marino else if (fmt[i] == 'E')
334*e4b17023SJohn Marino {
335*e4b17023SJohn Marino for (j = 0; j < XVECLEN (x, i); j++)
336*e4b17023SJohn Marino val ^= hash_invariant_expr_1 (insn, XVECEXP (x, i, j));
337*e4b17023SJohn Marino }
338*e4b17023SJohn Marino else if (fmt[i] == 'i' || fmt[i] == 'n')
339*e4b17023SJohn Marino val ^= XINT (x, i);
340*e4b17023SJohn Marino }
341*e4b17023SJohn Marino
342*e4b17023SJohn Marino return val;
343*e4b17023SJohn Marino }
344*e4b17023SJohn Marino
345*e4b17023SJohn Marino /* Returns true if the invariant expressions E1 and E2 used in insns INSN1
346*e4b17023SJohn Marino and INSN2 have always the same value. */
347*e4b17023SJohn Marino
348*e4b17023SJohn Marino static bool
invariant_expr_equal_p(rtx insn1,rtx e1,rtx insn2,rtx e2)349*e4b17023SJohn Marino invariant_expr_equal_p (rtx insn1, rtx e1, rtx insn2, rtx e2)
350*e4b17023SJohn Marino {
351*e4b17023SJohn Marino enum rtx_code code = GET_CODE (e1);
352*e4b17023SJohn Marino int i, j;
353*e4b17023SJohn Marino const char *fmt;
354*e4b17023SJohn Marino df_ref use1, use2;
355*e4b17023SJohn Marino struct invariant *inv1 = NULL, *inv2 = NULL;
356*e4b17023SJohn Marino rtx sub1, sub2;
357*e4b17023SJohn Marino
358*e4b17023SJohn Marino /* If mode of only one of the operands is VOIDmode, it is not equivalent to
359*e4b17023SJohn Marino the other one. If both are VOIDmode, we rely on the caller of this
360*e4b17023SJohn Marino function to verify that their modes are the same. */
361*e4b17023SJohn Marino if (code != GET_CODE (e2) || GET_MODE (e1) != GET_MODE (e2))
362*e4b17023SJohn Marino return false;
363*e4b17023SJohn Marino
364*e4b17023SJohn Marino switch (code)
365*e4b17023SJohn Marino {
366*e4b17023SJohn Marino case CONST_INT:
367*e4b17023SJohn Marino case CONST_DOUBLE:
368*e4b17023SJohn Marino case CONST_FIXED:
369*e4b17023SJohn Marino case SYMBOL_REF:
370*e4b17023SJohn Marino case CONST:
371*e4b17023SJohn Marino case LABEL_REF:
372*e4b17023SJohn Marino return rtx_equal_p (e1, e2);
373*e4b17023SJohn Marino
374*e4b17023SJohn Marino case REG:
375*e4b17023SJohn Marino use1 = df_find_use (insn1, e1);
376*e4b17023SJohn Marino use2 = df_find_use (insn2, e2);
377*e4b17023SJohn Marino if (use1)
378*e4b17023SJohn Marino inv1 = invariant_for_use (use1);
379*e4b17023SJohn Marino if (use2)
380*e4b17023SJohn Marino inv2 = invariant_for_use (use2);
381*e4b17023SJohn Marino
382*e4b17023SJohn Marino if (!inv1 && !inv2)
383*e4b17023SJohn Marino return rtx_equal_p (e1, e2);
384*e4b17023SJohn Marino
385*e4b17023SJohn Marino if (!inv1 || !inv2)
386*e4b17023SJohn Marino return false;
387*e4b17023SJohn Marino
388*e4b17023SJohn Marino gcc_assert (inv1->eqto != ~0u);
389*e4b17023SJohn Marino gcc_assert (inv2->eqto != ~0u);
390*e4b17023SJohn Marino return inv1->eqto == inv2->eqto;
391*e4b17023SJohn Marino
392*e4b17023SJohn Marino default:
393*e4b17023SJohn Marino break;
394*e4b17023SJohn Marino }
395*e4b17023SJohn Marino
396*e4b17023SJohn Marino fmt = GET_RTX_FORMAT (code);
397*e4b17023SJohn Marino for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
398*e4b17023SJohn Marino {
399*e4b17023SJohn Marino if (fmt[i] == 'e')
400*e4b17023SJohn Marino {
401*e4b17023SJohn Marino sub1 = XEXP (e1, i);
402*e4b17023SJohn Marino sub2 = XEXP (e2, i);
403*e4b17023SJohn Marino
404*e4b17023SJohn Marino if (!invariant_expr_equal_p (insn1, sub1, insn2, sub2))
405*e4b17023SJohn Marino return false;
406*e4b17023SJohn Marino }
407*e4b17023SJohn Marino
408*e4b17023SJohn Marino else if (fmt[i] == 'E')
409*e4b17023SJohn Marino {
410*e4b17023SJohn Marino if (XVECLEN (e1, i) != XVECLEN (e2, i))
411*e4b17023SJohn Marino return false;
412*e4b17023SJohn Marino
413*e4b17023SJohn Marino for (j = 0; j < XVECLEN (e1, i); j++)
414*e4b17023SJohn Marino {
415*e4b17023SJohn Marino sub1 = XVECEXP (e1, i, j);
416*e4b17023SJohn Marino sub2 = XVECEXP (e2, i, j);
417*e4b17023SJohn Marino
418*e4b17023SJohn Marino if (!invariant_expr_equal_p (insn1, sub1, insn2, sub2))
419*e4b17023SJohn Marino return false;
420*e4b17023SJohn Marino }
421*e4b17023SJohn Marino }
422*e4b17023SJohn Marino else if (fmt[i] == 'i' || fmt[i] == 'n')
423*e4b17023SJohn Marino {
424*e4b17023SJohn Marino if (XINT (e1, i) != XINT (e2, i))
425*e4b17023SJohn Marino return false;
426*e4b17023SJohn Marino }
427*e4b17023SJohn Marino /* Unhandled type of subexpression, we fail conservatively. */
428*e4b17023SJohn Marino else
429*e4b17023SJohn Marino return false;
430*e4b17023SJohn Marino }
431*e4b17023SJohn Marino
432*e4b17023SJohn Marino return true;
433*e4b17023SJohn Marino }
434*e4b17023SJohn Marino
435*e4b17023SJohn Marino /* Returns hash value for invariant expression entry E. */
436*e4b17023SJohn Marino
437*e4b17023SJohn Marino static hashval_t
hash_invariant_expr(const void * e)438*e4b17023SJohn Marino hash_invariant_expr (const void *e)
439*e4b17023SJohn Marino {
440*e4b17023SJohn Marino const struct invariant_expr_entry *const entry =
441*e4b17023SJohn Marino (const struct invariant_expr_entry *) e;
442*e4b17023SJohn Marino
443*e4b17023SJohn Marino return entry->hash;
444*e4b17023SJohn Marino }
445*e4b17023SJohn Marino
446*e4b17023SJohn Marino /* Compares invariant expression entries E1 and E2. */
447*e4b17023SJohn Marino
448*e4b17023SJohn Marino static int
eq_invariant_expr(const void * e1,const void * e2)449*e4b17023SJohn Marino eq_invariant_expr (const void *e1, const void *e2)
450*e4b17023SJohn Marino {
451*e4b17023SJohn Marino const struct invariant_expr_entry *const entry1 =
452*e4b17023SJohn Marino (const struct invariant_expr_entry *) e1;
453*e4b17023SJohn Marino const struct invariant_expr_entry *const entry2 =
454*e4b17023SJohn Marino (const struct invariant_expr_entry *) e2;
455*e4b17023SJohn Marino
456*e4b17023SJohn Marino if (entry1->mode != entry2->mode)
457*e4b17023SJohn Marino return 0;
458*e4b17023SJohn Marino
459*e4b17023SJohn Marino return invariant_expr_equal_p (entry1->inv->insn, entry1->expr,
460*e4b17023SJohn Marino entry2->inv->insn, entry2->expr);
461*e4b17023SJohn Marino }
462*e4b17023SJohn Marino
463*e4b17023SJohn Marino /* Checks whether invariant with value EXPR in machine mode MODE is
464*e4b17023SJohn Marino recorded in EQ. If this is the case, return the invariant. Otherwise
465*e4b17023SJohn Marino insert INV to the table for this expression and return INV. */
466*e4b17023SJohn Marino
467*e4b17023SJohn Marino static struct invariant *
find_or_insert_inv(htab_t eq,rtx expr,enum machine_mode mode,struct invariant * inv)468*e4b17023SJohn Marino find_or_insert_inv (htab_t eq, rtx expr, enum machine_mode mode,
469*e4b17023SJohn Marino struct invariant *inv)
470*e4b17023SJohn Marino {
471*e4b17023SJohn Marino hashval_t hash = hash_invariant_expr_1 (inv->insn, expr);
472*e4b17023SJohn Marino struct invariant_expr_entry *entry;
473*e4b17023SJohn Marino struct invariant_expr_entry pentry;
474*e4b17023SJohn Marino PTR *slot;
475*e4b17023SJohn Marino
476*e4b17023SJohn Marino pentry.expr = expr;
477*e4b17023SJohn Marino pentry.inv = inv;
478*e4b17023SJohn Marino pentry.mode = mode;
479*e4b17023SJohn Marino slot = htab_find_slot_with_hash (eq, &pentry, hash, INSERT);
480*e4b17023SJohn Marino entry = (struct invariant_expr_entry *) *slot;
481*e4b17023SJohn Marino
482*e4b17023SJohn Marino if (entry)
483*e4b17023SJohn Marino return entry->inv;
484*e4b17023SJohn Marino
485*e4b17023SJohn Marino entry = XNEW (struct invariant_expr_entry);
486*e4b17023SJohn Marino entry->inv = inv;
487*e4b17023SJohn Marino entry->expr = expr;
488*e4b17023SJohn Marino entry->mode = mode;
489*e4b17023SJohn Marino entry->hash = hash;
490*e4b17023SJohn Marino *slot = entry;
491*e4b17023SJohn Marino
492*e4b17023SJohn Marino return inv;
493*e4b17023SJohn Marino }
494*e4b17023SJohn Marino
495*e4b17023SJohn Marino /* Finds invariants identical to INV and records the equivalence. EQ is the
496*e4b17023SJohn Marino hash table of the invariants. */
497*e4b17023SJohn Marino
498*e4b17023SJohn Marino static void
find_identical_invariants(htab_t eq,struct invariant * inv)499*e4b17023SJohn Marino find_identical_invariants (htab_t eq, struct invariant *inv)
500*e4b17023SJohn Marino {
501*e4b17023SJohn Marino unsigned depno;
502*e4b17023SJohn Marino bitmap_iterator bi;
503*e4b17023SJohn Marino struct invariant *dep;
504*e4b17023SJohn Marino rtx expr, set;
505*e4b17023SJohn Marino enum machine_mode mode;
506*e4b17023SJohn Marino
507*e4b17023SJohn Marino if (inv->eqto != ~0u)
508*e4b17023SJohn Marino return;
509*e4b17023SJohn Marino
510*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, depno, bi)
511*e4b17023SJohn Marino {
512*e4b17023SJohn Marino dep = VEC_index (invariant_p, invariants, depno);
513*e4b17023SJohn Marino find_identical_invariants (eq, dep);
514*e4b17023SJohn Marino }
515*e4b17023SJohn Marino
516*e4b17023SJohn Marino set = single_set (inv->insn);
517*e4b17023SJohn Marino expr = SET_SRC (set);
518*e4b17023SJohn Marino mode = GET_MODE (expr);
519*e4b17023SJohn Marino if (mode == VOIDmode)
520*e4b17023SJohn Marino mode = GET_MODE (SET_DEST (set));
521*e4b17023SJohn Marino inv->eqto = find_or_insert_inv (eq, expr, mode, inv)->invno;
522*e4b17023SJohn Marino
523*e4b17023SJohn Marino if (dump_file && inv->eqto != inv->invno)
524*e4b17023SJohn Marino fprintf (dump_file,
525*e4b17023SJohn Marino "Invariant %d is equivalent to invariant %d.\n",
526*e4b17023SJohn Marino inv->invno, inv->eqto);
527*e4b17023SJohn Marino }
528*e4b17023SJohn Marino
529*e4b17023SJohn Marino /* Find invariants with the same value and record the equivalences. */
530*e4b17023SJohn Marino
531*e4b17023SJohn Marino static void
merge_identical_invariants(void)532*e4b17023SJohn Marino merge_identical_invariants (void)
533*e4b17023SJohn Marino {
534*e4b17023SJohn Marino unsigned i;
535*e4b17023SJohn Marino struct invariant *inv;
536*e4b17023SJohn Marino htab_t eq = htab_create (VEC_length (invariant_p, invariants),
537*e4b17023SJohn Marino hash_invariant_expr, eq_invariant_expr, free);
538*e4b17023SJohn Marino
539*e4b17023SJohn Marino FOR_EACH_VEC_ELT (invariant_p, invariants, i, inv)
540*e4b17023SJohn Marino find_identical_invariants (eq, inv);
541*e4b17023SJohn Marino
542*e4b17023SJohn Marino htab_delete (eq);
543*e4b17023SJohn Marino }
544*e4b17023SJohn Marino
545*e4b17023SJohn Marino /* Determines the basic blocks inside LOOP that are always executed and
546*e4b17023SJohn Marino stores their bitmap to ALWAYS_REACHED. MAY_EXIT is a bitmap of
547*e4b17023SJohn Marino basic blocks that may either exit the loop, or contain the call that
548*e4b17023SJohn Marino does not have to return. BODY is body of the loop obtained by
549*e4b17023SJohn Marino get_loop_body_in_dom_order. */
550*e4b17023SJohn Marino
551*e4b17023SJohn Marino static void
compute_always_reached(struct loop * loop,basic_block * body,bitmap may_exit,bitmap always_reached)552*e4b17023SJohn Marino compute_always_reached (struct loop *loop, basic_block *body,
553*e4b17023SJohn Marino bitmap may_exit, bitmap always_reached)
554*e4b17023SJohn Marino {
555*e4b17023SJohn Marino unsigned i;
556*e4b17023SJohn Marino
557*e4b17023SJohn Marino for (i = 0; i < loop->num_nodes; i++)
558*e4b17023SJohn Marino {
559*e4b17023SJohn Marino if (dominated_by_p (CDI_DOMINATORS, loop->latch, body[i]))
560*e4b17023SJohn Marino bitmap_set_bit (always_reached, i);
561*e4b17023SJohn Marino
562*e4b17023SJohn Marino if (bitmap_bit_p (may_exit, i))
563*e4b17023SJohn Marino return;
564*e4b17023SJohn Marino }
565*e4b17023SJohn Marino }
566*e4b17023SJohn Marino
567*e4b17023SJohn Marino /* Finds exits out of the LOOP with body BODY. Marks blocks in that we may
568*e4b17023SJohn Marino exit the loop by cfg edge to HAS_EXIT and MAY_EXIT. In MAY_EXIT
569*e4b17023SJohn Marino additionally mark blocks that may exit due to a call. */
570*e4b17023SJohn Marino
571*e4b17023SJohn Marino static void
find_exits(struct loop * loop,basic_block * body,bitmap may_exit,bitmap has_exit)572*e4b17023SJohn Marino find_exits (struct loop *loop, basic_block *body,
573*e4b17023SJohn Marino bitmap may_exit, bitmap has_exit)
574*e4b17023SJohn Marino {
575*e4b17023SJohn Marino unsigned i;
576*e4b17023SJohn Marino edge_iterator ei;
577*e4b17023SJohn Marino edge e;
578*e4b17023SJohn Marino struct loop *outermost_exit = loop, *aexit;
579*e4b17023SJohn Marino bool has_call = false;
580*e4b17023SJohn Marino rtx insn;
581*e4b17023SJohn Marino
582*e4b17023SJohn Marino for (i = 0; i < loop->num_nodes; i++)
583*e4b17023SJohn Marino {
584*e4b17023SJohn Marino if (body[i]->loop_father == loop)
585*e4b17023SJohn Marino {
586*e4b17023SJohn Marino FOR_BB_INSNS (body[i], insn)
587*e4b17023SJohn Marino {
588*e4b17023SJohn Marino if (CALL_P (insn)
589*e4b17023SJohn Marino && (RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
590*e4b17023SJohn Marino || !RTL_CONST_OR_PURE_CALL_P (insn)))
591*e4b17023SJohn Marino {
592*e4b17023SJohn Marino has_call = true;
593*e4b17023SJohn Marino bitmap_set_bit (may_exit, i);
594*e4b17023SJohn Marino break;
595*e4b17023SJohn Marino }
596*e4b17023SJohn Marino }
597*e4b17023SJohn Marino
598*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, body[i]->succs)
599*e4b17023SJohn Marino {
600*e4b17023SJohn Marino if (flow_bb_inside_loop_p (loop, e->dest))
601*e4b17023SJohn Marino continue;
602*e4b17023SJohn Marino
603*e4b17023SJohn Marino bitmap_set_bit (may_exit, i);
604*e4b17023SJohn Marino bitmap_set_bit (has_exit, i);
605*e4b17023SJohn Marino outermost_exit = find_common_loop (outermost_exit,
606*e4b17023SJohn Marino e->dest->loop_father);
607*e4b17023SJohn Marino }
608*e4b17023SJohn Marino continue;
609*e4b17023SJohn Marino }
610*e4b17023SJohn Marino
611*e4b17023SJohn Marino /* Use the data stored for the subloop to decide whether we may exit
612*e4b17023SJohn Marino through it. It is sufficient to do this for header of the loop,
613*e4b17023SJohn Marino as other basic blocks inside it must be dominated by it. */
614*e4b17023SJohn Marino if (body[i]->loop_father->header != body[i])
615*e4b17023SJohn Marino continue;
616*e4b17023SJohn Marino
617*e4b17023SJohn Marino if (LOOP_DATA (body[i]->loop_father)->has_call)
618*e4b17023SJohn Marino {
619*e4b17023SJohn Marino has_call = true;
620*e4b17023SJohn Marino bitmap_set_bit (may_exit, i);
621*e4b17023SJohn Marino }
622*e4b17023SJohn Marino aexit = LOOP_DATA (body[i]->loop_father)->outermost_exit;
623*e4b17023SJohn Marino if (aexit != loop)
624*e4b17023SJohn Marino {
625*e4b17023SJohn Marino bitmap_set_bit (may_exit, i);
626*e4b17023SJohn Marino bitmap_set_bit (has_exit, i);
627*e4b17023SJohn Marino
628*e4b17023SJohn Marino if (flow_loop_nested_p (aexit, outermost_exit))
629*e4b17023SJohn Marino outermost_exit = aexit;
630*e4b17023SJohn Marino }
631*e4b17023SJohn Marino }
632*e4b17023SJohn Marino
633*e4b17023SJohn Marino if (loop->aux == NULL)
634*e4b17023SJohn Marino {
635*e4b17023SJohn Marino loop->aux = xcalloc (1, sizeof (struct loop_data));
636*e4b17023SJohn Marino bitmap_initialize (&LOOP_DATA (loop)->regs_ref, ®_obstack);
637*e4b17023SJohn Marino bitmap_initialize (&LOOP_DATA (loop)->regs_live, ®_obstack);
638*e4b17023SJohn Marino }
639*e4b17023SJohn Marino LOOP_DATA (loop)->outermost_exit = outermost_exit;
640*e4b17023SJohn Marino LOOP_DATA (loop)->has_call = has_call;
641*e4b17023SJohn Marino }
642*e4b17023SJohn Marino
643*e4b17023SJohn Marino /* Check whether we may assign a value to X from a register. */
644*e4b17023SJohn Marino
645*e4b17023SJohn Marino static bool
may_assign_reg_p(rtx x)646*e4b17023SJohn Marino may_assign_reg_p (rtx x)
647*e4b17023SJohn Marino {
648*e4b17023SJohn Marino return (GET_MODE (x) != VOIDmode
649*e4b17023SJohn Marino && GET_MODE (x) != BLKmode
650*e4b17023SJohn Marino && can_copy_p (GET_MODE (x))
651*e4b17023SJohn Marino && (!REG_P (x)
652*e4b17023SJohn Marino || !HARD_REGISTER_P (x)
653*e4b17023SJohn Marino || REGNO_REG_CLASS (REGNO (x)) != NO_REGS));
654*e4b17023SJohn Marino }
655*e4b17023SJohn Marino
656*e4b17023SJohn Marino /* Finds definitions that may correspond to invariants in LOOP with body
657*e4b17023SJohn Marino BODY. */
658*e4b17023SJohn Marino
659*e4b17023SJohn Marino static void
find_defs(struct loop * loop,basic_block * body)660*e4b17023SJohn Marino find_defs (struct loop *loop, basic_block *body)
661*e4b17023SJohn Marino {
662*e4b17023SJohn Marino unsigned i;
663*e4b17023SJohn Marino bitmap blocks = BITMAP_ALLOC (NULL);
664*e4b17023SJohn Marino
665*e4b17023SJohn Marino for (i = 0; i < loop->num_nodes; i++)
666*e4b17023SJohn Marino bitmap_set_bit (blocks, body[i]->index);
667*e4b17023SJohn Marino
668*e4b17023SJohn Marino df_remove_problem (df_chain);
669*e4b17023SJohn Marino df_process_deferred_rescans ();
670*e4b17023SJohn Marino df_chain_add_problem (DF_UD_CHAIN);
671*e4b17023SJohn Marino df_set_blocks (blocks);
672*e4b17023SJohn Marino df_analyze ();
673*e4b17023SJohn Marino
674*e4b17023SJohn Marino if (dump_file)
675*e4b17023SJohn Marino {
676*e4b17023SJohn Marino df_dump_region (dump_file);
677*e4b17023SJohn Marino fprintf (dump_file, "*****starting processing of loop ******\n");
678*e4b17023SJohn Marino print_rtl_with_bb (dump_file, get_insns ());
679*e4b17023SJohn Marino fprintf (dump_file, "*****ending processing of loop ******\n");
680*e4b17023SJohn Marino }
681*e4b17023SJohn Marino check_invariant_table_size ();
682*e4b17023SJohn Marino
683*e4b17023SJohn Marino BITMAP_FREE (blocks);
684*e4b17023SJohn Marino }
685*e4b17023SJohn Marino
686*e4b17023SJohn Marino /* Creates a new invariant for definition DEF in INSN, depending on invariants
687*e4b17023SJohn Marino in DEPENDS_ON. ALWAYS_EXECUTED is true if the insn is always executed,
688*e4b17023SJohn Marino unless the program ends due to a function call. The newly created invariant
689*e4b17023SJohn Marino is returned. */
690*e4b17023SJohn Marino
691*e4b17023SJohn Marino static struct invariant *
create_new_invariant(struct def * def,rtx insn,bitmap depends_on,bool always_executed)692*e4b17023SJohn Marino create_new_invariant (struct def *def, rtx insn, bitmap depends_on,
693*e4b17023SJohn Marino bool always_executed)
694*e4b17023SJohn Marino {
695*e4b17023SJohn Marino struct invariant *inv = XNEW (struct invariant);
696*e4b17023SJohn Marino rtx set = single_set (insn);
697*e4b17023SJohn Marino bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
698*e4b17023SJohn Marino
699*e4b17023SJohn Marino inv->def = def;
700*e4b17023SJohn Marino inv->always_executed = always_executed;
701*e4b17023SJohn Marino inv->depends_on = depends_on;
702*e4b17023SJohn Marino
703*e4b17023SJohn Marino /* If the set is simple, usually by moving it we move the whole store out of
704*e4b17023SJohn Marino the loop. Otherwise we save only cost of the computation. */
705*e4b17023SJohn Marino if (def)
706*e4b17023SJohn Marino {
707*e4b17023SJohn Marino inv->cost = set_rtx_cost (set, speed);
708*e4b17023SJohn Marino /* ??? Try to determine cheapness of address computation. Unfortunately
709*e4b17023SJohn Marino the address cost is only a relative measure, we can't really compare
710*e4b17023SJohn Marino it with any absolute number, but only with other address costs.
711*e4b17023SJohn Marino But here we don't have any other addresses, so compare with a magic
712*e4b17023SJohn Marino number anyway. It has to be large enough to not regress PR33928
713*e4b17023SJohn Marino (by avoiding to move reg+8,reg+16,reg+24 invariants), but small
714*e4b17023SJohn Marino enough to not regress 410.bwaves either (by still moving reg+reg
715*e4b17023SJohn Marino invariants).
716*e4b17023SJohn Marino See http://gcc.gnu.org/ml/gcc-patches/2009-10/msg01210.html . */
717*e4b17023SJohn Marino inv->cheap_address = address_cost (SET_SRC (set), word_mode,
718*e4b17023SJohn Marino ADDR_SPACE_GENERIC, speed) < 3;
719*e4b17023SJohn Marino }
720*e4b17023SJohn Marino else
721*e4b17023SJohn Marino {
722*e4b17023SJohn Marino inv->cost = set_src_cost (SET_SRC (set), speed);
723*e4b17023SJohn Marino inv->cheap_address = false;
724*e4b17023SJohn Marino }
725*e4b17023SJohn Marino
726*e4b17023SJohn Marino inv->move = false;
727*e4b17023SJohn Marino inv->reg = NULL_RTX;
728*e4b17023SJohn Marino inv->orig_regno = -1;
729*e4b17023SJohn Marino inv->stamp = 0;
730*e4b17023SJohn Marino inv->insn = insn;
731*e4b17023SJohn Marino
732*e4b17023SJohn Marino inv->invno = VEC_length (invariant_p, invariants);
733*e4b17023SJohn Marino inv->eqto = ~0u;
734*e4b17023SJohn Marino if (def)
735*e4b17023SJohn Marino def->invno = inv->invno;
736*e4b17023SJohn Marino VEC_safe_push (invariant_p, heap, invariants, inv);
737*e4b17023SJohn Marino
738*e4b17023SJohn Marino if (dump_file)
739*e4b17023SJohn Marino {
740*e4b17023SJohn Marino fprintf (dump_file,
741*e4b17023SJohn Marino "Set in insn %d is invariant (%d), cost %d, depends on ",
742*e4b17023SJohn Marino INSN_UID (insn), inv->invno, inv->cost);
743*e4b17023SJohn Marino dump_bitmap (dump_file, inv->depends_on);
744*e4b17023SJohn Marino }
745*e4b17023SJohn Marino
746*e4b17023SJohn Marino return inv;
747*e4b17023SJohn Marino }
748*e4b17023SJohn Marino
749*e4b17023SJohn Marino /* Record USE at DEF. */
750*e4b17023SJohn Marino
751*e4b17023SJohn Marino static void
record_use(struct def * def,df_ref use)752*e4b17023SJohn Marino record_use (struct def *def, df_ref use)
753*e4b17023SJohn Marino {
754*e4b17023SJohn Marino struct use *u = XNEW (struct use);
755*e4b17023SJohn Marino
756*e4b17023SJohn Marino u->pos = DF_REF_REAL_LOC (use);
757*e4b17023SJohn Marino u->insn = DF_REF_INSN (use);
758*e4b17023SJohn Marino u->addr_use_p = (DF_REF_TYPE (use) == DF_REF_REG_MEM_LOAD
759*e4b17023SJohn Marino || DF_REF_TYPE (use) == DF_REF_REG_MEM_STORE);
760*e4b17023SJohn Marino u->next = def->uses;
761*e4b17023SJohn Marino def->uses = u;
762*e4b17023SJohn Marino def->n_uses++;
763*e4b17023SJohn Marino if (u->addr_use_p)
764*e4b17023SJohn Marino def->n_addr_uses++;
765*e4b17023SJohn Marino }
766*e4b17023SJohn Marino
767*e4b17023SJohn Marino /* Finds the invariants USE depends on and store them to the DEPENDS_ON
768*e4b17023SJohn Marino bitmap. Returns true if all dependencies of USE are known to be
769*e4b17023SJohn Marino loop invariants, false otherwise. */
770*e4b17023SJohn Marino
771*e4b17023SJohn Marino static bool
check_dependency(basic_block bb,df_ref use,bitmap depends_on)772*e4b17023SJohn Marino check_dependency (basic_block bb, df_ref use, bitmap depends_on)
773*e4b17023SJohn Marino {
774*e4b17023SJohn Marino df_ref def;
775*e4b17023SJohn Marino basic_block def_bb;
776*e4b17023SJohn Marino struct df_link *defs;
777*e4b17023SJohn Marino struct def *def_data;
778*e4b17023SJohn Marino struct invariant *inv;
779*e4b17023SJohn Marino
780*e4b17023SJohn Marino if (DF_REF_FLAGS (use) & DF_REF_READ_WRITE)
781*e4b17023SJohn Marino return false;
782*e4b17023SJohn Marino
783*e4b17023SJohn Marino defs = DF_REF_CHAIN (use);
784*e4b17023SJohn Marino if (!defs)
785*e4b17023SJohn Marino return true;
786*e4b17023SJohn Marino
787*e4b17023SJohn Marino if (defs->next)
788*e4b17023SJohn Marino return false;
789*e4b17023SJohn Marino
790*e4b17023SJohn Marino def = defs->ref;
791*e4b17023SJohn Marino check_invariant_table_size ();
792*e4b17023SJohn Marino inv = invariant_table[DF_REF_ID(def)];
793*e4b17023SJohn Marino if (!inv)
794*e4b17023SJohn Marino return false;
795*e4b17023SJohn Marino
796*e4b17023SJohn Marino def_data = inv->def;
797*e4b17023SJohn Marino gcc_assert (def_data != NULL);
798*e4b17023SJohn Marino
799*e4b17023SJohn Marino def_bb = DF_REF_BB (def);
800*e4b17023SJohn Marino /* Note that in case bb == def_bb, we know that the definition
801*e4b17023SJohn Marino dominates insn, because def has invariant_table[DF_REF_ID(def)]
802*e4b17023SJohn Marino defined and we process the insns in the basic block bb
803*e4b17023SJohn Marino sequentially. */
804*e4b17023SJohn Marino if (!dominated_by_p (CDI_DOMINATORS, bb, def_bb))
805*e4b17023SJohn Marino return false;
806*e4b17023SJohn Marino
807*e4b17023SJohn Marino bitmap_set_bit (depends_on, def_data->invno);
808*e4b17023SJohn Marino return true;
809*e4b17023SJohn Marino }
810*e4b17023SJohn Marino
811*e4b17023SJohn Marino
812*e4b17023SJohn Marino /* Finds the invariants INSN depends on and store them to the DEPENDS_ON
813*e4b17023SJohn Marino bitmap. Returns true if all dependencies of INSN are known to be
814*e4b17023SJohn Marino loop invariants, false otherwise. */
815*e4b17023SJohn Marino
816*e4b17023SJohn Marino static bool
check_dependencies(rtx insn,bitmap depends_on)817*e4b17023SJohn Marino check_dependencies (rtx insn, bitmap depends_on)
818*e4b17023SJohn Marino {
819*e4b17023SJohn Marino struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
820*e4b17023SJohn Marino df_ref *use_rec;
821*e4b17023SJohn Marino basic_block bb = BLOCK_FOR_INSN (insn);
822*e4b17023SJohn Marino
823*e4b17023SJohn Marino for (use_rec = DF_INSN_INFO_USES (insn_info); *use_rec; use_rec++)
824*e4b17023SJohn Marino if (!check_dependency (bb, *use_rec, depends_on))
825*e4b17023SJohn Marino return false;
826*e4b17023SJohn Marino for (use_rec = DF_INSN_INFO_EQ_USES (insn_info); *use_rec; use_rec++)
827*e4b17023SJohn Marino if (!check_dependency (bb, *use_rec, depends_on))
828*e4b17023SJohn Marino return false;
829*e4b17023SJohn Marino
830*e4b17023SJohn Marino return true;
831*e4b17023SJohn Marino }
832*e4b17023SJohn Marino
833*e4b17023SJohn Marino /* Finds invariant in INSN. ALWAYS_REACHED is true if the insn is always
834*e4b17023SJohn Marino executed. ALWAYS_EXECUTED is true if the insn is always executed,
835*e4b17023SJohn Marino unless the program ends due to a function call. */
836*e4b17023SJohn Marino
837*e4b17023SJohn Marino static void
find_invariant_insn(rtx insn,bool always_reached,bool always_executed)838*e4b17023SJohn Marino find_invariant_insn (rtx insn, bool always_reached, bool always_executed)
839*e4b17023SJohn Marino {
840*e4b17023SJohn Marino df_ref ref;
841*e4b17023SJohn Marino struct def *def;
842*e4b17023SJohn Marino bitmap depends_on;
843*e4b17023SJohn Marino rtx set, dest;
844*e4b17023SJohn Marino bool simple = true;
845*e4b17023SJohn Marino struct invariant *inv;
846*e4b17023SJohn Marino
847*e4b17023SJohn Marino #ifdef HAVE_cc0
848*e4b17023SJohn Marino /* We can't move a CC0 setter without the user. */
849*e4b17023SJohn Marino if (sets_cc0_p (insn))
850*e4b17023SJohn Marino return;
851*e4b17023SJohn Marino #endif
852*e4b17023SJohn Marino
853*e4b17023SJohn Marino set = single_set (insn);
854*e4b17023SJohn Marino if (!set)
855*e4b17023SJohn Marino return;
856*e4b17023SJohn Marino dest = SET_DEST (set);
857*e4b17023SJohn Marino
858*e4b17023SJohn Marino if (!REG_P (dest)
859*e4b17023SJohn Marino || HARD_REGISTER_P (dest))
860*e4b17023SJohn Marino simple = false;
861*e4b17023SJohn Marino
862*e4b17023SJohn Marino if (!may_assign_reg_p (SET_DEST (set))
863*e4b17023SJohn Marino || !check_maybe_invariant (SET_SRC (set)))
864*e4b17023SJohn Marino return;
865*e4b17023SJohn Marino
866*e4b17023SJohn Marino /* If the insn can throw exception, we cannot move it at all without changing
867*e4b17023SJohn Marino cfg. */
868*e4b17023SJohn Marino if (can_throw_internal (insn))
869*e4b17023SJohn Marino return;
870*e4b17023SJohn Marino
871*e4b17023SJohn Marino /* We cannot make trapping insn executed, unless it was executed before. */
872*e4b17023SJohn Marino if (may_trap_or_fault_p (PATTERN (insn)) && !always_reached)
873*e4b17023SJohn Marino return;
874*e4b17023SJohn Marino
875*e4b17023SJohn Marino depends_on = BITMAP_ALLOC (NULL);
876*e4b17023SJohn Marino if (!check_dependencies (insn, depends_on))
877*e4b17023SJohn Marino {
878*e4b17023SJohn Marino BITMAP_FREE (depends_on);
879*e4b17023SJohn Marino return;
880*e4b17023SJohn Marino }
881*e4b17023SJohn Marino
882*e4b17023SJohn Marino if (simple)
883*e4b17023SJohn Marino def = XCNEW (struct def);
884*e4b17023SJohn Marino else
885*e4b17023SJohn Marino def = NULL;
886*e4b17023SJohn Marino
887*e4b17023SJohn Marino inv = create_new_invariant (def, insn, depends_on, always_executed);
888*e4b17023SJohn Marino
889*e4b17023SJohn Marino if (simple)
890*e4b17023SJohn Marino {
891*e4b17023SJohn Marino ref = df_find_def (insn, dest);
892*e4b17023SJohn Marino check_invariant_table_size ();
893*e4b17023SJohn Marino invariant_table[DF_REF_ID(ref)] = inv;
894*e4b17023SJohn Marino }
895*e4b17023SJohn Marino }
896*e4b17023SJohn Marino
897*e4b17023SJohn Marino /* Record registers used in INSN that have a unique invariant definition. */
898*e4b17023SJohn Marino
899*e4b17023SJohn Marino static void
record_uses(rtx insn)900*e4b17023SJohn Marino record_uses (rtx insn)
901*e4b17023SJohn Marino {
902*e4b17023SJohn Marino struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
903*e4b17023SJohn Marino df_ref *use_rec;
904*e4b17023SJohn Marino struct invariant *inv;
905*e4b17023SJohn Marino
906*e4b17023SJohn Marino for (use_rec = DF_INSN_INFO_USES (insn_info); *use_rec; use_rec++)
907*e4b17023SJohn Marino {
908*e4b17023SJohn Marino df_ref use = *use_rec;
909*e4b17023SJohn Marino inv = invariant_for_use (use);
910*e4b17023SJohn Marino if (inv)
911*e4b17023SJohn Marino record_use (inv->def, use);
912*e4b17023SJohn Marino }
913*e4b17023SJohn Marino for (use_rec = DF_INSN_INFO_EQ_USES (insn_info); *use_rec; use_rec++)
914*e4b17023SJohn Marino {
915*e4b17023SJohn Marino df_ref use = *use_rec;
916*e4b17023SJohn Marino inv = invariant_for_use (use);
917*e4b17023SJohn Marino if (inv)
918*e4b17023SJohn Marino record_use (inv->def, use);
919*e4b17023SJohn Marino }
920*e4b17023SJohn Marino }
921*e4b17023SJohn Marino
922*e4b17023SJohn Marino /* Finds invariants in INSN. ALWAYS_REACHED is true if the insn is always
923*e4b17023SJohn Marino executed. ALWAYS_EXECUTED is true if the insn is always executed,
924*e4b17023SJohn Marino unless the program ends due to a function call. */
925*e4b17023SJohn Marino
926*e4b17023SJohn Marino static void
find_invariants_insn(rtx insn,bool always_reached,bool always_executed)927*e4b17023SJohn Marino find_invariants_insn (rtx insn, bool always_reached, bool always_executed)
928*e4b17023SJohn Marino {
929*e4b17023SJohn Marino find_invariant_insn (insn, always_reached, always_executed);
930*e4b17023SJohn Marino record_uses (insn);
931*e4b17023SJohn Marino }
932*e4b17023SJohn Marino
933*e4b17023SJohn Marino /* Finds invariants in basic block BB. ALWAYS_REACHED is true if the
934*e4b17023SJohn Marino basic block is always executed. ALWAYS_EXECUTED is true if the basic
935*e4b17023SJohn Marino block is always executed, unless the program ends due to a function
936*e4b17023SJohn Marino call. */
937*e4b17023SJohn Marino
938*e4b17023SJohn Marino static void
find_invariants_bb(basic_block bb,bool always_reached,bool always_executed)939*e4b17023SJohn Marino find_invariants_bb (basic_block bb, bool always_reached, bool always_executed)
940*e4b17023SJohn Marino {
941*e4b17023SJohn Marino rtx insn;
942*e4b17023SJohn Marino
943*e4b17023SJohn Marino FOR_BB_INSNS (bb, insn)
944*e4b17023SJohn Marino {
945*e4b17023SJohn Marino if (!NONDEBUG_INSN_P (insn))
946*e4b17023SJohn Marino continue;
947*e4b17023SJohn Marino
948*e4b17023SJohn Marino find_invariants_insn (insn, always_reached, always_executed);
949*e4b17023SJohn Marino
950*e4b17023SJohn Marino if (always_reached
951*e4b17023SJohn Marino && CALL_P (insn)
952*e4b17023SJohn Marino && (RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
953*e4b17023SJohn Marino || ! RTL_CONST_OR_PURE_CALL_P (insn)))
954*e4b17023SJohn Marino always_reached = false;
955*e4b17023SJohn Marino }
956*e4b17023SJohn Marino }
957*e4b17023SJohn Marino
958*e4b17023SJohn Marino /* Finds invariants in LOOP with body BODY. ALWAYS_REACHED is the bitmap of
959*e4b17023SJohn Marino basic blocks in BODY that are always executed. ALWAYS_EXECUTED is the
960*e4b17023SJohn Marino bitmap of basic blocks in BODY that are always executed unless the program
961*e4b17023SJohn Marino ends due to a function call. */
962*e4b17023SJohn Marino
963*e4b17023SJohn Marino static void
find_invariants_body(struct loop * loop,basic_block * body,bitmap always_reached,bitmap always_executed)964*e4b17023SJohn Marino find_invariants_body (struct loop *loop, basic_block *body,
965*e4b17023SJohn Marino bitmap always_reached, bitmap always_executed)
966*e4b17023SJohn Marino {
967*e4b17023SJohn Marino unsigned i;
968*e4b17023SJohn Marino
969*e4b17023SJohn Marino for (i = 0; i < loop->num_nodes; i++)
970*e4b17023SJohn Marino find_invariants_bb (body[i],
971*e4b17023SJohn Marino bitmap_bit_p (always_reached, i),
972*e4b17023SJohn Marino bitmap_bit_p (always_executed, i));
973*e4b17023SJohn Marino }
974*e4b17023SJohn Marino
975*e4b17023SJohn Marino /* Finds invariants in LOOP. */
976*e4b17023SJohn Marino
977*e4b17023SJohn Marino static void
find_invariants(struct loop * loop)978*e4b17023SJohn Marino find_invariants (struct loop *loop)
979*e4b17023SJohn Marino {
980*e4b17023SJohn Marino bitmap may_exit = BITMAP_ALLOC (NULL);
981*e4b17023SJohn Marino bitmap always_reached = BITMAP_ALLOC (NULL);
982*e4b17023SJohn Marino bitmap has_exit = BITMAP_ALLOC (NULL);
983*e4b17023SJohn Marino bitmap always_executed = BITMAP_ALLOC (NULL);
984*e4b17023SJohn Marino basic_block *body = get_loop_body_in_dom_order (loop);
985*e4b17023SJohn Marino
986*e4b17023SJohn Marino find_exits (loop, body, may_exit, has_exit);
987*e4b17023SJohn Marino compute_always_reached (loop, body, may_exit, always_reached);
988*e4b17023SJohn Marino compute_always_reached (loop, body, has_exit, always_executed);
989*e4b17023SJohn Marino
990*e4b17023SJohn Marino find_defs (loop, body);
991*e4b17023SJohn Marino find_invariants_body (loop, body, always_reached, always_executed);
992*e4b17023SJohn Marino merge_identical_invariants ();
993*e4b17023SJohn Marino
994*e4b17023SJohn Marino BITMAP_FREE (always_reached);
995*e4b17023SJohn Marino BITMAP_FREE (always_executed);
996*e4b17023SJohn Marino BITMAP_FREE (may_exit);
997*e4b17023SJohn Marino BITMAP_FREE (has_exit);
998*e4b17023SJohn Marino free (body);
999*e4b17023SJohn Marino }
1000*e4b17023SJohn Marino
1001*e4b17023SJohn Marino /* Frees a list of uses USE. */
1002*e4b17023SJohn Marino
1003*e4b17023SJohn Marino static void
free_use_list(struct use * use)1004*e4b17023SJohn Marino free_use_list (struct use *use)
1005*e4b17023SJohn Marino {
1006*e4b17023SJohn Marino struct use *next;
1007*e4b17023SJohn Marino
1008*e4b17023SJohn Marino for (; use; use = next)
1009*e4b17023SJohn Marino {
1010*e4b17023SJohn Marino next = use->next;
1011*e4b17023SJohn Marino free (use);
1012*e4b17023SJohn Marino }
1013*e4b17023SJohn Marino }
1014*e4b17023SJohn Marino
1015*e4b17023SJohn Marino /* Return pressure class and number of hard registers (through *NREGS)
1016*e4b17023SJohn Marino for destination of INSN. */
1017*e4b17023SJohn Marino static enum reg_class
get_pressure_class_and_nregs(rtx insn,int * nregs)1018*e4b17023SJohn Marino get_pressure_class_and_nregs (rtx insn, int *nregs)
1019*e4b17023SJohn Marino {
1020*e4b17023SJohn Marino rtx reg;
1021*e4b17023SJohn Marino enum reg_class pressure_class;
1022*e4b17023SJohn Marino rtx set = single_set (insn);
1023*e4b17023SJohn Marino
1024*e4b17023SJohn Marino /* Considered invariant insns have only one set. */
1025*e4b17023SJohn Marino gcc_assert (set != NULL_RTX);
1026*e4b17023SJohn Marino reg = SET_DEST (set);
1027*e4b17023SJohn Marino if (GET_CODE (reg) == SUBREG)
1028*e4b17023SJohn Marino reg = SUBREG_REG (reg);
1029*e4b17023SJohn Marino if (MEM_P (reg))
1030*e4b17023SJohn Marino {
1031*e4b17023SJohn Marino *nregs = 0;
1032*e4b17023SJohn Marino pressure_class = NO_REGS;
1033*e4b17023SJohn Marino }
1034*e4b17023SJohn Marino else
1035*e4b17023SJohn Marino {
1036*e4b17023SJohn Marino if (! REG_P (reg))
1037*e4b17023SJohn Marino reg = NULL_RTX;
1038*e4b17023SJohn Marino if (reg == NULL_RTX)
1039*e4b17023SJohn Marino pressure_class = GENERAL_REGS;
1040*e4b17023SJohn Marino else
1041*e4b17023SJohn Marino {
1042*e4b17023SJohn Marino pressure_class = reg_allocno_class (REGNO (reg));
1043*e4b17023SJohn Marino pressure_class = ira_pressure_class_translate[pressure_class];
1044*e4b17023SJohn Marino }
1045*e4b17023SJohn Marino *nregs
1046*e4b17023SJohn Marino = ira_reg_class_max_nregs[pressure_class][GET_MODE (SET_SRC (set))];
1047*e4b17023SJohn Marino }
1048*e4b17023SJohn Marino return pressure_class;
1049*e4b17023SJohn Marino }
1050*e4b17023SJohn Marino
1051*e4b17023SJohn Marino /* Calculates cost and number of registers needed for moving invariant INV
1052*e4b17023SJohn Marino out of the loop and stores them to *COST and *REGS_NEEDED. */
1053*e4b17023SJohn Marino
1054*e4b17023SJohn Marino static void
get_inv_cost(struct invariant * inv,int * comp_cost,unsigned * regs_needed)1055*e4b17023SJohn Marino get_inv_cost (struct invariant *inv, int *comp_cost, unsigned *regs_needed)
1056*e4b17023SJohn Marino {
1057*e4b17023SJohn Marino int i, acomp_cost;
1058*e4b17023SJohn Marino unsigned aregs_needed[N_REG_CLASSES];
1059*e4b17023SJohn Marino unsigned depno;
1060*e4b17023SJohn Marino struct invariant *dep;
1061*e4b17023SJohn Marino bitmap_iterator bi;
1062*e4b17023SJohn Marino
1063*e4b17023SJohn Marino /* Find the representative of the class of the equivalent invariants. */
1064*e4b17023SJohn Marino inv = VEC_index (invariant_p, invariants, inv->eqto);
1065*e4b17023SJohn Marino
1066*e4b17023SJohn Marino *comp_cost = 0;
1067*e4b17023SJohn Marino if (! flag_ira_loop_pressure)
1068*e4b17023SJohn Marino regs_needed[0] = 0;
1069*e4b17023SJohn Marino else
1070*e4b17023SJohn Marino {
1071*e4b17023SJohn Marino for (i = 0; i < ira_pressure_classes_num; i++)
1072*e4b17023SJohn Marino regs_needed[ira_pressure_classes[i]] = 0;
1073*e4b17023SJohn Marino }
1074*e4b17023SJohn Marino
1075*e4b17023SJohn Marino if (inv->move
1076*e4b17023SJohn Marino || inv->stamp == actual_stamp)
1077*e4b17023SJohn Marino return;
1078*e4b17023SJohn Marino inv->stamp = actual_stamp;
1079*e4b17023SJohn Marino
1080*e4b17023SJohn Marino if (! flag_ira_loop_pressure)
1081*e4b17023SJohn Marino regs_needed[0]++;
1082*e4b17023SJohn Marino else
1083*e4b17023SJohn Marino {
1084*e4b17023SJohn Marino int nregs;
1085*e4b17023SJohn Marino enum reg_class pressure_class;
1086*e4b17023SJohn Marino
1087*e4b17023SJohn Marino pressure_class = get_pressure_class_and_nregs (inv->insn, &nregs);
1088*e4b17023SJohn Marino regs_needed[pressure_class] += nregs;
1089*e4b17023SJohn Marino }
1090*e4b17023SJohn Marino
1091*e4b17023SJohn Marino if (!inv->cheap_address
1092*e4b17023SJohn Marino || inv->def->n_addr_uses < inv->def->n_uses)
1093*e4b17023SJohn Marino (*comp_cost) += inv->cost;
1094*e4b17023SJohn Marino
1095*e4b17023SJohn Marino #ifdef STACK_REGS
1096*e4b17023SJohn Marino {
1097*e4b17023SJohn Marino /* Hoisting constant pool constants into stack regs may cost more than
1098*e4b17023SJohn Marino just single register. On x87, the balance is affected both by the
1099*e4b17023SJohn Marino small number of FP registers, and by its register stack organization,
1100*e4b17023SJohn Marino that forces us to add compensation code in and around the loop to
1101*e4b17023SJohn Marino shuffle the operands to the top of stack before use, and pop them
1102*e4b17023SJohn Marino from the stack after the loop finishes.
1103*e4b17023SJohn Marino
1104*e4b17023SJohn Marino To model this effect, we increase the number of registers needed for
1105*e4b17023SJohn Marino stack registers by two: one register push, and one register pop.
1106*e4b17023SJohn Marino This usually has the effect that FP constant loads from the constant
1107*e4b17023SJohn Marino pool are not moved out of the loop.
1108*e4b17023SJohn Marino
1109*e4b17023SJohn Marino Note that this also means that dependent invariants can not be moved.
1110*e4b17023SJohn Marino However, the primary purpose of this pass is to move loop invariant
1111*e4b17023SJohn Marino address arithmetic out of loops, and address arithmetic that depends
1112*e4b17023SJohn Marino on floating point constants is unlikely to ever occur. */
1113*e4b17023SJohn Marino rtx set = single_set (inv->insn);
1114*e4b17023SJohn Marino if (set
1115*e4b17023SJohn Marino && IS_STACK_MODE (GET_MODE (SET_SRC (set)))
1116*e4b17023SJohn Marino && constant_pool_constant_p (SET_SRC (set)))
1117*e4b17023SJohn Marino {
1118*e4b17023SJohn Marino if (flag_ira_loop_pressure)
1119*e4b17023SJohn Marino regs_needed[ira_stack_reg_pressure_class] += 2;
1120*e4b17023SJohn Marino else
1121*e4b17023SJohn Marino regs_needed[0] += 2;
1122*e4b17023SJohn Marino }
1123*e4b17023SJohn Marino }
1124*e4b17023SJohn Marino #endif
1125*e4b17023SJohn Marino
1126*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, depno, bi)
1127*e4b17023SJohn Marino {
1128*e4b17023SJohn Marino bool check_p;
1129*e4b17023SJohn Marino
1130*e4b17023SJohn Marino dep = VEC_index (invariant_p, invariants, depno);
1131*e4b17023SJohn Marino
1132*e4b17023SJohn Marino get_inv_cost (dep, &acomp_cost, aregs_needed);
1133*e4b17023SJohn Marino
1134*e4b17023SJohn Marino if (! flag_ira_loop_pressure)
1135*e4b17023SJohn Marino check_p = aregs_needed[0] != 0;
1136*e4b17023SJohn Marino else
1137*e4b17023SJohn Marino {
1138*e4b17023SJohn Marino for (i = 0; i < ira_pressure_classes_num; i++)
1139*e4b17023SJohn Marino if (aregs_needed[ira_pressure_classes[i]] != 0)
1140*e4b17023SJohn Marino break;
1141*e4b17023SJohn Marino check_p = i < ira_pressure_classes_num;
1142*e4b17023SJohn Marino }
1143*e4b17023SJohn Marino if (check_p
1144*e4b17023SJohn Marino /* We need to check always_executed, since if the original value of
1145*e4b17023SJohn Marino the invariant may be preserved, we may need to keep it in a
1146*e4b17023SJohn Marino separate register. TODO check whether the register has an
1147*e4b17023SJohn Marino use outside of the loop. */
1148*e4b17023SJohn Marino && dep->always_executed
1149*e4b17023SJohn Marino && !dep->def->uses->next)
1150*e4b17023SJohn Marino {
1151*e4b17023SJohn Marino /* If this is a single use, after moving the dependency we will not
1152*e4b17023SJohn Marino need a new register. */
1153*e4b17023SJohn Marino if (! flag_ira_loop_pressure)
1154*e4b17023SJohn Marino aregs_needed[0]--;
1155*e4b17023SJohn Marino else
1156*e4b17023SJohn Marino {
1157*e4b17023SJohn Marino int nregs;
1158*e4b17023SJohn Marino enum reg_class pressure_class;
1159*e4b17023SJohn Marino
1160*e4b17023SJohn Marino pressure_class = get_pressure_class_and_nregs (inv->insn, &nregs);
1161*e4b17023SJohn Marino aregs_needed[pressure_class] -= nregs;
1162*e4b17023SJohn Marino }
1163*e4b17023SJohn Marino }
1164*e4b17023SJohn Marino
1165*e4b17023SJohn Marino if (! flag_ira_loop_pressure)
1166*e4b17023SJohn Marino regs_needed[0] += aregs_needed[0];
1167*e4b17023SJohn Marino else
1168*e4b17023SJohn Marino {
1169*e4b17023SJohn Marino for (i = 0; i < ira_pressure_classes_num; i++)
1170*e4b17023SJohn Marino regs_needed[ira_pressure_classes[i]]
1171*e4b17023SJohn Marino += aregs_needed[ira_pressure_classes[i]];
1172*e4b17023SJohn Marino }
1173*e4b17023SJohn Marino (*comp_cost) += acomp_cost;
1174*e4b17023SJohn Marino }
1175*e4b17023SJohn Marino }
1176*e4b17023SJohn Marino
1177*e4b17023SJohn Marino /* Calculates gain for eliminating invariant INV. REGS_USED is the number
1178*e4b17023SJohn Marino of registers used in the loop, NEW_REGS is the number of new variables
1179*e4b17023SJohn Marino already added due to the invariant motion. The number of registers needed
1180*e4b17023SJohn Marino for it is stored in *REGS_NEEDED. SPEED and CALL_P are flags passed
1181*e4b17023SJohn Marino through to estimate_reg_pressure_cost. */
1182*e4b17023SJohn Marino
1183*e4b17023SJohn Marino static int
gain_for_invariant(struct invariant * inv,unsigned * regs_needed,unsigned * new_regs,unsigned regs_used,bool speed,bool call_p)1184*e4b17023SJohn Marino gain_for_invariant (struct invariant *inv, unsigned *regs_needed,
1185*e4b17023SJohn Marino unsigned *new_regs, unsigned regs_used,
1186*e4b17023SJohn Marino bool speed, bool call_p)
1187*e4b17023SJohn Marino {
1188*e4b17023SJohn Marino int comp_cost, size_cost;
1189*e4b17023SJohn Marino
1190*e4b17023SJohn Marino actual_stamp++;
1191*e4b17023SJohn Marino
1192*e4b17023SJohn Marino get_inv_cost (inv, &comp_cost, regs_needed);
1193*e4b17023SJohn Marino
1194*e4b17023SJohn Marino if (! flag_ira_loop_pressure)
1195*e4b17023SJohn Marino {
1196*e4b17023SJohn Marino size_cost = (estimate_reg_pressure_cost (new_regs[0] + regs_needed[0],
1197*e4b17023SJohn Marino regs_used, speed, call_p)
1198*e4b17023SJohn Marino - estimate_reg_pressure_cost (new_regs[0],
1199*e4b17023SJohn Marino regs_used, speed, call_p));
1200*e4b17023SJohn Marino }
1201*e4b17023SJohn Marino else
1202*e4b17023SJohn Marino {
1203*e4b17023SJohn Marino int i;
1204*e4b17023SJohn Marino enum reg_class pressure_class;
1205*e4b17023SJohn Marino
1206*e4b17023SJohn Marino for (i = 0; i < ira_pressure_classes_num; i++)
1207*e4b17023SJohn Marino {
1208*e4b17023SJohn Marino pressure_class = ira_pressure_classes[i];
1209*e4b17023SJohn Marino if ((int) new_regs[pressure_class]
1210*e4b17023SJohn Marino + (int) regs_needed[pressure_class]
1211*e4b17023SJohn Marino + LOOP_DATA (curr_loop)->max_reg_pressure[pressure_class]
1212*e4b17023SJohn Marino + IRA_LOOP_RESERVED_REGS
1213*e4b17023SJohn Marino > ira_available_class_regs[pressure_class])
1214*e4b17023SJohn Marino break;
1215*e4b17023SJohn Marino }
1216*e4b17023SJohn Marino if (i < ira_pressure_classes_num)
1217*e4b17023SJohn Marino /* There will be register pressure excess and we want not to
1218*e4b17023SJohn Marino make this loop invariant motion. All loop invariants with
1219*e4b17023SJohn Marino non-positive gains will be rejected in function
1220*e4b17023SJohn Marino find_invariants_to_move. Therefore we return the negative
1221*e4b17023SJohn Marino number here.
1222*e4b17023SJohn Marino
1223*e4b17023SJohn Marino One could think that this rejects also expensive loop
1224*e4b17023SJohn Marino invariant motions and this will hurt code performance.
1225*e4b17023SJohn Marino However numerous experiments with different heuristics
1226*e4b17023SJohn Marino taking invariant cost into account did not confirm this
1227*e4b17023SJohn Marino assumption. There are possible explanations for this
1228*e4b17023SJohn Marino result:
1229*e4b17023SJohn Marino o probably all expensive invariants were already moved out
1230*e4b17023SJohn Marino of the loop by PRE and gimple invariant motion pass.
1231*e4b17023SJohn Marino o expensive invariant execution will be hidden by insn
1232*e4b17023SJohn Marino scheduling or OOO processor hardware because usually such
1233*e4b17023SJohn Marino invariants have a lot of freedom to be executed
1234*e4b17023SJohn Marino out-of-order.
1235*e4b17023SJohn Marino Another reason for ignoring invariant cost vs spilling cost
1236*e4b17023SJohn Marino heuristics is also in difficulties to evaluate accurately
1237*e4b17023SJohn Marino spill cost at this stage. */
1238*e4b17023SJohn Marino return -1;
1239*e4b17023SJohn Marino else
1240*e4b17023SJohn Marino size_cost = 0;
1241*e4b17023SJohn Marino }
1242*e4b17023SJohn Marino
1243*e4b17023SJohn Marino return comp_cost - size_cost;
1244*e4b17023SJohn Marino }
1245*e4b17023SJohn Marino
1246*e4b17023SJohn Marino /* Finds invariant with best gain for moving. Returns the gain, stores
1247*e4b17023SJohn Marino the invariant in *BEST and number of registers needed for it to
1248*e4b17023SJohn Marino *REGS_NEEDED. REGS_USED is the number of registers used in the loop.
1249*e4b17023SJohn Marino NEW_REGS is the number of new variables already added due to invariant
1250*e4b17023SJohn Marino motion. */
1251*e4b17023SJohn Marino
1252*e4b17023SJohn Marino static int
best_gain_for_invariant(struct invariant ** best,unsigned * regs_needed,unsigned * new_regs,unsigned regs_used,bool speed,bool call_p)1253*e4b17023SJohn Marino best_gain_for_invariant (struct invariant **best, unsigned *regs_needed,
1254*e4b17023SJohn Marino unsigned *new_regs, unsigned regs_used,
1255*e4b17023SJohn Marino bool speed, bool call_p)
1256*e4b17023SJohn Marino {
1257*e4b17023SJohn Marino struct invariant *inv;
1258*e4b17023SJohn Marino int i, gain = 0, again;
1259*e4b17023SJohn Marino unsigned aregs_needed[N_REG_CLASSES], invno;
1260*e4b17023SJohn Marino
1261*e4b17023SJohn Marino FOR_EACH_VEC_ELT (invariant_p, invariants, invno, inv)
1262*e4b17023SJohn Marino {
1263*e4b17023SJohn Marino if (inv->move)
1264*e4b17023SJohn Marino continue;
1265*e4b17023SJohn Marino
1266*e4b17023SJohn Marino /* Only consider the "representatives" of equivalent invariants. */
1267*e4b17023SJohn Marino if (inv->eqto != inv->invno)
1268*e4b17023SJohn Marino continue;
1269*e4b17023SJohn Marino
1270*e4b17023SJohn Marino again = gain_for_invariant (inv, aregs_needed, new_regs, regs_used,
1271*e4b17023SJohn Marino speed, call_p);
1272*e4b17023SJohn Marino if (again > gain)
1273*e4b17023SJohn Marino {
1274*e4b17023SJohn Marino gain = again;
1275*e4b17023SJohn Marino *best = inv;
1276*e4b17023SJohn Marino if (! flag_ira_loop_pressure)
1277*e4b17023SJohn Marino regs_needed[0] = aregs_needed[0];
1278*e4b17023SJohn Marino else
1279*e4b17023SJohn Marino {
1280*e4b17023SJohn Marino for (i = 0; i < ira_pressure_classes_num; i++)
1281*e4b17023SJohn Marino regs_needed[ira_pressure_classes[i]]
1282*e4b17023SJohn Marino = aregs_needed[ira_pressure_classes[i]];
1283*e4b17023SJohn Marino }
1284*e4b17023SJohn Marino }
1285*e4b17023SJohn Marino }
1286*e4b17023SJohn Marino
1287*e4b17023SJohn Marino return gain;
1288*e4b17023SJohn Marino }
1289*e4b17023SJohn Marino
1290*e4b17023SJohn Marino /* Marks invariant INVNO and all its dependencies for moving. */
1291*e4b17023SJohn Marino
1292*e4b17023SJohn Marino static void
set_move_mark(unsigned invno,int gain)1293*e4b17023SJohn Marino set_move_mark (unsigned invno, int gain)
1294*e4b17023SJohn Marino {
1295*e4b17023SJohn Marino struct invariant *inv = VEC_index (invariant_p, invariants, invno);
1296*e4b17023SJohn Marino bitmap_iterator bi;
1297*e4b17023SJohn Marino
1298*e4b17023SJohn Marino /* Find the representative of the class of the equivalent invariants. */
1299*e4b17023SJohn Marino inv = VEC_index (invariant_p, invariants, inv->eqto);
1300*e4b17023SJohn Marino
1301*e4b17023SJohn Marino if (inv->move)
1302*e4b17023SJohn Marino return;
1303*e4b17023SJohn Marino inv->move = true;
1304*e4b17023SJohn Marino
1305*e4b17023SJohn Marino if (dump_file)
1306*e4b17023SJohn Marino {
1307*e4b17023SJohn Marino if (gain >= 0)
1308*e4b17023SJohn Marino fprintf (dump_file, "Decided to move invariant %d -- gain %d\n",
1309*e4b17023SJohn Marino invno, gain);
1310*e4b17023SJohn Marino else
1311*e4b17023SJohn Marino fprintf (dump_file, "Decided to move dependent invariant %d\n",
1312*e4b17023SJohn Marino invno);
1313*e4b17023SJohn Marino };
1314*e4b17023SJohn Marino
1315*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, invno, bi)
1316*e4b17023SJohn Marino {
1317*e4b17023SJohn Marino set_move_mark (invno, -1);
1318*e4b17023SJohn Marino }
1319*e4b17023SJohn Marino }
1320*e4b17023SJohn Marino
1321*e4b17023SJohn Marino /* Determines which invariants to move. */
1322*e4b17023SJohn Marino
1323*e4b17023SJohn Marino static void
find_invariants_to_move(bool speed,bool call_p)1324*e4b17023SJohn Marino find_invariants_to_move (bool speed, bool call_p)
1325*e4b17023SJohn Marino {
1326*e4b17023SJohn Marino int gain;
1327*e4b17023SJohn Marino unsigned i, regs_used, regs_needed[N_REG_CLASSES], new_regs[N_REG_CLASSES];
1328*e4b17023SJohn Marino struct invariant *inv = NULL;
1329*e4b17023SJohn Marino
1330*e4b17023SJohn Marino if (!VEC_length (invariant_p, invariants))
1331*e4b17023SJohn Marino return;
1332*e4b17023SJohn Marino
1333*e4b17023SJohn Marino if (flag_ira_loop_pressure)
1334*e4b17023SJohn Marino /* REGS_USED is actually never used when the flag is on. */
1335*e4b17023SJohn Marino regs_used = 0;
1336*e4b17023SJohn Marino else
1337*e4b17023SJohn Marino /* We do not really do a good job in estimating number of
1338*e4b17023SJohn Marino registers used; we put some initial bound here to stand for
1339*e4b17023SJohn Marino induction variables etc. that we do not detect. */
1340*e4b17023SJohn Marino {
1341*e4b17023SJohn Marino unsigned int n_regs = DF_REG_SIZE (df);
1342*e4b17023SJohn Marino
1343*e4b17023SJohn Marino regs_used = 2;
1344*e4b17023SJohn Marino
1345*e4b17023SJohn Marino for (i = 0; i < n_regs; i++)
1346*e4b17023SJohn Marino {
1347*e4b17023SJohn Marino if (!DF_REGNO_FIRST_DEF (i) && DF_REGNO_LAST_USE (i))
1348*e4b17023SJohn Marino {
1349*e4b17023SJohn Marino /* This is a value that is used but not changed inside loop. */
1350*e4b17023SJohn Marino regs_used++;
1351*e4b17023SJohn Marino }
1352*e4b17023SJohn Marino }
1353*e4b17023SJohn Marino }
1354*e4b17023SJohn Marino
1355*e4b17023SJohn Marino if (! flag_ira_loop_pressure)
1356*e4b17023SJohn Marino new_regs[0] = regs_needed[0] = 0;
1357*e4b17023SJohn Marino else
1358*e4b17023SJohn Marino {
1359*e4b17023SJohn Marino for (i = 0; (int) i < ira_pressure_classes_num; i++)
1360*e4b17023SJohn Marino new_regs[ira_pressure_classes[i]] = 0;
1361*e4b17023SJohn Marino }
1362*e4b17023SJohn Marino while ((gain = best_gain_for_invariant (&inv, regs_needed,
1363*e4b17023SJohn Marino new_regs, regs_used,
1364*e4b17023SJohn Marino speed, call_p)) > 0)
1365*e4b17023SJohn Marino {
1366*e4b17023SJohn Marino set_move_mark (inv->invno, gain);
1367*e4b17023SJohn Marino if (! flag_ira_loop_pressure)
1368*e4b17023SJohn Marino new_regs[0] += regs_needed[0];
1369*e4b17023SJohn Marino else
1370*e4b17023SJohn Marino {
1371*e4b17023SJohn Marino for (i = 0; (int) i < ira_pressure_classes_num; i++)
1372*e4b17023SJohn Marino new_regs[ira_pressure_classes[i]]
1373*e4b17023SJohn Marino += regs_needed[ira_pressure_classes[i]];
1374*e4b17023SJohn Marino }
1375*e4b17023SJohn Marino }
1376*e4b17023SJohn Marino }
1377*e4b17023SJohn Marino
1378*e4b17023SJohn Marino /* Replace the uses, reached by the definition of invariant INV, by REG.
1379*e4b17023SJohn Marino
1380*e4b17023SJohn Marino IN_GROUP is nonzero if this is part of a group of changes that must be
1381*e4b17023SJohn Marino performed as a group. In that case, the changes will be stored. The
1382*e4b17023SJohn Marino function `apply_change_group' will validate and apply the changes. */
1383*e4b17023SJohn Marino
1384*e4b17023SJohn Marino static int
replace_uses(struct invariant * inv,rtx reg,bool in_group)1385*e4b17023SJohn Marino replace_uses (struct invariant *inv, rtx reg, bool in_group)
1386*e4b17023SJohn Marino {
1387*e4b17023SJohn Marino /* Replace the uses we know to be dominated. It saves work for copy
1388*e4b17023SJohn Marino propagation, and also it is necessary so that dependent invariants
1389*e4b17023SJohn Marino are computed right. */
1390*e4b17023SJohn Marino if (inv->def)
1391*e4b17023SJohn Marino {
1392*e4b17023SJohn Marino struct use *use;
1393*e4b17023SJohn Marino for (use = inv->def->uses; use; use = use->next)
1394*e4b17023SJohn Marino validate_change (use->insn, use->pos, reg, true);
1395*e4b17023SJohn Marino
1396*e4b17023SJohn Marino /* If we aren't part of a larger group, apply the changes now. */
1397*e4b17023SJohn Marino if (!in_group)
1398*e4b17023SJohn Marino return apply_change_group ();
1399*e4b17023SJohn Marino }
1400*e4b17023SJohn Marino
1401*e4b17023SJohn Marino return 1;
1402*e4b17023SJohn Marino }
1403*e4b17023SJohn Marino
1404*e4b17023SJohn Marino /* Move invariant INVNO out of the LOOP. Returns true if this succeeds, false
1405*e4b17023SJohn Marino otherwise. */
1406*e4b17023SJohn Marino
1407*e4b17023SJohn Marino static bool
move_invariant_reg(struct loop * loop,unsigned invno)1408*e4b17023SJohn Marino move_invariant_reg (struct loop *loop, unsigned invno)
1409*e4b17023SJohn Marino {
1410*e4b17023SJohn Marino struct invariant *inv = VEC_index (invariant_p, invariants, invno);
1411*e4b17023SJohn Marino struct invariant *repr = VEC_index (invariant_p, invariants, inv->eqto);
1412*e4b17023SJohn Marino unsigned i;
1413*e4b17023SJohn Marino basic_block preheader = loop_preheader_edge (loop)->src;
1414*e4b17023SJohn Marino rtx reg, set, dest, note;
1415*e4b17023SJohn Marino bitmap_iterator bi;
1416*e4b17023SJohn Marino int regno = -1;
1417*e4b17023SJohn Marino
1418*e4b17023SJohn Marino if (inv->reg)
1419*e4b17023SJohn Marino return true;
1420*e4b17023SJohn Marino if (!repr->move)
1421*e4b17023SJohn Marino return false;
1422*e4b17023SJohn Marino
1423*e4b17023SJohn Marino /* If this is a representative of the class of equivalent invariants,
1424*e4b17023SJohn Marino really move the invariant. Otherwise just replace its use with
1425*e4b17023SJohn Marino the register used for the representative. */
1426*e4b17023SJohn Marino if (inv == repr)
1427*e4b17023SJohn Marino {
1428*e4b17023SJohn Marino if (inv->depends_on)
1429*e4b17023SJohn Marino {
1430*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, i, bi)
1431*e4b17023SJohn Marino {
1432*e4b17023SJohn Marino if (!move_invariant_reg (loop, i))
1433*e4b17023SJohn Marino goto fail;
1434*e4b17023SJohn Marino }
1435*e4b17023SJohn Marino }
1436*e4b17023SJohn Marino
1437*e4b17023SJohn Marino /* Move the set out of the loop. If the set is always executed (we could
1438*e4b17023SJohn Marino omit this condition if we know that the register is unused outside of
1439*e4b17023SJohn Marino the loop, but it does not seem worth finding out) and it has no uses
1440*e4b17023SJohn Marino that would not be dominated by it, we may just move it (TODO).
1441*e4b17023SJohn Marino Otherwise we need to create a temporary register. */
1442*e4b17023SJohn Marino set = single_set (inv->insn);
1443*e4b17023SJohn Marino reg = dest = SET_DEST (set);
1444*e4b17023SJohn Marino if (GET_CODE (reg) == SUBREG)
1445*e4b17023SJohn Marino reg = SUBREG_REG (reg);
1446*e4b17023SJohn Marino if (REG_P (reg))
1447*e4b17023SJohn Marino regno = REGNO (reg);
1448*e4b17023SJohn Marino
1449*e4b17023SJohn Marino reg = gen_reg_rtx_and_attrs (dest);
1450*e4b17023SJohn Marino
1451*e4b17023SJohn Marino /* Try replacing the destination by a new pseudoregister. */
1452*e4b17023SJohn Marino validate_change (inv->insn, &SET_DEST (set), reg, true);
1453*e4b17023SJohn Marino
1454*e4b17023SJohn Marino /* As well as all the dominated uses. */
1455*e4b17023SJohn Marino replace_uses (inv, reg, true);
1456*e4b17023SJohn Marino
1457*e4b17023SJohn Marino /* And validate all the changes. */
1458*e4b17023SJohn Marino if (!apply_change_group ())
1459*e4b17023SJohn Marino goto fail;
1460*e4b17023SJohn Marino
1461*e4b17023SJohn Marino emit_insn_after (gen_move_insn (dest, reg), inv->insn);
1462*e4b17023SJohn Marino reorder_insns (inv->insn, inv->insn, BB_END (preheader));
1463*e4b17023SJohn Marino
1464*e4b17023SJohn Marino /* If there is a REG_EQUAL note on the insn we just moved, and the
1465*e4b17023SJohn Marino insn is in a basic block that is not always executed or the note
1466*e4b17023SJohn Marino contains something for which we don't know the invariant status,
1467*e4b17023SJohn Marino the note may no longer be valid after we move the insn. Note that
1468*e4b17023SJohn Marino uses in REG_EQUAL notes are taken into account in the computation
1469*e4b17023SJohn Marino of invariants, so it is safe to retain the note even if it contains
1470*e4b17023SJohn Marino register references for which we know the invariant status. */
1471*e4b17023SJohn Marino if ((note = find_reg_note (inv->insn, REG_EQUAL, NULL_RTX))
1472*e4b17023SJohn Marino && (!inv->always_executed
1473*e4b17023SJohn Marino || !check_maybe_invariant (XEXP (note, 0))))
1474*e4b17023SJohn Marino remove_note (inv->insn, note);
1475*e4b17023SJohn Marino }
1476*e4b17023SJohn Marino else
1477*e4b17023SJohn Marino {
1478*e4b17023SJohn Marino if (!move_invariant_reg (loop, repr->invno))
1479*e4b17023SJohn Marino goto fail;
1480*e4b17023SJohn Marino reg = repr->reg;
1481*e4b17023SJohn Marino regno = repr->orig_regno;
1482*e4b17023SJohn Marino if (!replace_uses (inv, reg, false))
1483*e4b17023SJohn Marino goto fail;
1484*e4b17023SJohn Marino set = single_set (inv->insn);
1485*e4b17023SJohn Marino emit_insn_after (gen_move_insn (SET_DEST (set), reg), inv->insn);
1486*e4b17023SJohn Marino delete_insn (inv->insn);
1487*e4b17023SJohn Marino }
1488*e4b17023SJohn Marino
1489*e4b17023SJohn Marino inv->reg = reg;
1490*e4b17023SJohn Marino inv->orig_regno = regno;
1491*e4b17023SJohn Marino
1492*e4b17023SJohn Marino return true;
1493*e4b17023SJohn Marino
1494*e4b17023SJohn Marino fail:
1495*e4b17023SJohn Marino /* If we failed, clear move flag, so that we do not try to move inv
1496*e4b17023SJohn Marino again. */
1497*e4b17023SJohn Marino if (dump_file)
1498*e4b17023SJohn Marino fprintf (dump_file, "Failed to move invariant %d\n", invno);
1499*e4b17023SJohn Marino inv->move = false;
1500*e4b17023SJohn Marino inv->reg = NULL_RTX;
1501*e4b17023SJohn Marino inv->orig_regno = -1;
1502*e4b17023SJohn Marino
1503*e4b17023SJohn Marino return false;
1504*e4b17023SJohn Marino }
1505*e4b17023SJohn Marino
1506*e4b17023SJohn Marino /* Move selected invariant out of the LOOP. Newly created regs are marked
1507*e4b17023SJohn Marino in TEMPORARY_REGS. */
1508*e4b17023SJohn Marino
1509*e4b17023SJohn Marino static void
move_invariants(struct loop * loop)1510*e4b17023SJohn Marino move_invariants (struct loop *loop)
1511*e4b17023SJohn Marino {
1512*e4b17023SJohn Marino struct invariant *inv;
1513*e4b17023SJohn Marino unsigned i;
1514*e4b17023SJohn Marino
1515*e4b17023SJohn Marino FOR_EACH_VEC_ELT (invariant_p, invariants, i, inv)
1516*e4b17023SJohn Marino move_invariant_reg (loop, i);
1517*e4b17023SJohn Marino if (flag_ira_loop_pressure && resize_reg_info ())
1518*e4b17023SJohn Marino {
1519*e4b17023SJohn Marino FOR_EACH_VEC_ELT (invariant_p, invariants, i, inv)
1520*e4b17023SJohn Marino if (inv->reg != NULL_RTX)
1521*e4b17023SJohn Marino {
1522*e4b17023SJohn Marino if (inv->orig_regno >= 0)
1523*e4b17023SJohn Marino setup_reg_classes (REGNO (inv->reg),
1524*e4b17023SJohn Marino reg_preferred_class (inv->orig_regno),
1525*e4b17023SJohn Marino reg_alternate_class (inv->orig_regno),
1526*e4b17023SJohn Marino reg_allocno_class (inv->orig_regno));
1527*e4b17023SJohn Marino else
1528*e4b17023SJohn Marino setup_reg_classes (REGNO (inv->reg),
1529*e4b17023SJohn Marino GENERAL_REGS, NO_REGS, GENERAL_REGS);
1530*e4b17023SJohn Marino }
1531*e4b17023SJohn Marino }
1532*e4b17023SJohn Marino }
1533*e4b17023SJohn Marino
1534*e4b17023SJohn Marino /* Initializes invariant motion data. */
1535*e4b17023SJohn Marino
1536*e4b17023SJohn Marino static void
init_inv_motion_data(void)1537*e4b17023SJohn Marino init_inv_motion_data (void)
1538*e4b17023SJohn Marino {
1539*e4b17023SJohn Marino actual_stamp = 1;
1540*e4b17023SJohn Marino
1541*e4b17023SJohn Marino invariants = VEC_alloc (invariant_p, heap, 100);
1542*e4b17023SJohn Marino }
1543*e4b17023SJohn Marino
1544*e4b17023SJohn Marino /* Frees the data allocated by invariant motion. */
1545*e4b17023SJohn Marino
1546*e4b17023SJohn Marino static void
free_inv_motion_data(void)1547*e4b17023SJohn Marino free_inv_motion_data (void)
1548*e4b17023SJohn Marino {
1549*e4b17023SJohn Marino unsigned i;
1550*e4b17023SJohn Marino struct def *def;
1551*e4b17023SJohn Marino struct invariant *inv;
1552*e4b17023SJohn Marino
1553*e4b17023SJohn Marino check_invariant_table_size ();
1554*e4b17023SJohn Marino for (i = 0; i < DF_DEFS_TABLE_SIZE (); i++)
1555*e4b17023SJohn Marino {
1556*e4b17023SJohn Marino inv = invariant_table[i];
1557*e4b17023SJohn Marino if (inv)
1558*e4b17023SJohn Marino {
1559*e4b17023SJohn Marino def = inv->def;
1560*e4b17023SJohn Marino gcc_assert (def != NULL);
1561*e4b17023SJohn Marino
1562*e4b17023SJohn Marino free_use_list (def->uses);
1563*e4b17023SJohn Marino free (def);
1564*e4b17023SJohn Marino invariant_table[i] = NULL;
1565*e4b17023SJohn Marino }
1566*e4b17023SJohn Marino }
1567*e4b17023SJohn Marino
1568*e4b17023SJohn Marino FOR_EACH_VEC_ELT (invariant_p, invariants, i, inv)
1569*e4b17023SJohn Marino {
1570*e4b17023SJohn Marino BITMAP_FREE (inv->depends_on);
1571*e4b17023SJohn Marino free (inv);
1572*e4b17023SJohn Marino }
1573*e4b17023SJohn Marino VEC_free (invariant_p, heap, invariants);
1574*e4b17023SJohn Marino }
1575*e4b17023SJohn Marino
1576*e4b17023SJohn Marino /* Move the invariants out of the LOOP. */
1577*e4b17023SJohn Marino
1578*e4b17023SJohn Marino static void
move_single_loop_invariants(struct loop * loop)1579*e4b17023SJohn Marino move_single_loop_invariants (struct loop *loop)
1580*e4b17023SJohn Marino {
1581*e4b17023SJohn Marino init_inv_motion_data ();
1582*e4b17023SJohn Marino
1583*e4b17023SJohn Marino find_invariants (loop);
1584*e4b17023SJohn Marino find_invariants_to_move (optimize_loop_for_speed_p (loop),
1585*e4b17023SJohn Marino LOOP_DATA (loop)->has_call);
1586*e4b17023SJohn Marino move_invariants (loop);
1587*e4b17023SJohn Marino
1588*e4b17023SJohn Marino free_inv_motion_data ();
1589*e4b17023SJohn Marino }
1590*e4b17023SJohn Marino
1591*e4b17023SJohn Marino /* Releases the auxiliary data for LOOP. */
1592*e4b17023SJohn Marino
1593*e4b17023SJohn Marino static void
free_loop_data(struct loop * loop)1594*e4b17023SJohn Marino free_loop_data (struct loop *loop)
1595*e4b17023SJohn Marino {
1596*e4b17023SJohn Marino struct loop_data *data = LOOP_DATA (loop);
1597*e4b17023SJohn Marino if (!data)
1598*e4b17023SJohn Marino return;
1599*e4b17023SJohn Marino
1600*e4b17023SJohn Marino bitmap_clear (&LOOP_DATA (loop)->regs_ref);
1601*e4b17023SJohn Marino bitmap_clear (&LOOP_DATA (loop)->regs_live);
1602*e4b17023SJohn Marino free (data);
1603*e4b17023SJohn Marino loop->aux = NULL;
1604*e4b17023SJohn Marino }
1605*e4b17023SJohn Marino
1606*e4b17023SJohn Marino
1607*e4b17023SJohn Marino
1608*e4b17023SJohn Marino /* Registers currently living. */
1609*e4b17023SJohn Marino static bitmap_head curr_regs_live;
1610*e4b17023SJohn Marino
1611*e4b17023SJohn Marino /* Current reg pressure for each pressure class. */
1612*e4b17023SJohn Marino static int curr_reg_pressure[N_REG_CLASSES];
1613*e4b17023SJohn Marino
1614*e4b17023SJohn Marino /* Record all regs that are set in any one insn. Communication from
1615*e4b17023SJohn Marino mark_reg_{store,clobber} and global_conflicts. Asm can refer to
1616*e4b17023SJohn Marino all hard-registers. */
1617*e4b17023SJohn Marino static rtx regs_set[(FIRST_PSEUDO_REGISTER > MAX_RECOG_OPERANDS
1618*e4b17023SJohn Marino ? FIRST_PSEUDO_REGISTER : MAX_RECOG_OPERANDS) * 2];
1619*e4b17023SJohn Marino /* Number of regs stored in the previous array. */
1620*e4b17023SJohn Marino static int n_regs_set;
1621*e4b17023SJohn Marino
1622*e4b17023SJohn Marino /* Return pressure class and number of needed hard registers (through
1623*e4b17023SJohn Marino *NREGS) of register REGNO. */
1624*e4b17023SJohn Marino static enum reg_class
get_regno_pressure_class(int regno,int * nregs)1625*e4b17023SJohn Marino get_regno_pressure_class (int regno, int *nregs)
1626*e4b17023SJohn Marino {
1627*e4b17023SJohn Marino if (regno >= FIRST_PSEUDO_REGISTER)
1628*e4b17023SJohn Marino {
1629*e4b17023SJohn Marino enum reg_class pressure_class;
1630*e4b17023SJohn Marino
1631*e4b17023SJohn Marino pressure_class = reg_allocno_class (regno);
1632*e4b17023SJohn Marino pressure_class = ira_pressure_class_translate[pressure_class];
1633*e4b17023SJohn Marino *nregs
1634*e4b17023SJohn Marino = ira_reg_class_max_nregs[pressure_class][PSEUDO_REGNO_MODE (regno)];
1635*e4b17023SJohn Marino return pressure_class;
1636*e4b17023SJohn Marino }
1637*e4b17023SJohn Marino else if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno)
1638*e4b17023SJohn Marino && ! TEST_HARD_REG_BIT (eliminable_regset, regno))
1639*e4b17023SJohn Marino {
1640*e4b17023SJohn Marino *nregs = 1;
1641*e4b17023SJohn Marino return ira_pressure_class_translate[REGNO_REG_CLASS (regno)];
1642*e4b17023SJohn Marino }
1643*e4b17023SJohn Marino else
1644*e4b17023SJohn Marino {
1645*e4b17023SJohn Marino *nregs = 0;
1646*e4b17023SJohn Marino return NO_REGS;
1647*e4b17023SJohn Marino }
1648*e4b17023SJohn Marino }
1649*e4b17023SJohn Marino
1650*e4b17023SJohn Marino /* Increase (if INCR_P) or decrease current register pressure for
1651*e4b17023SJohn Marino register REGNO. */
1652*e4b17023SJohn Marino static void
change_pressure(int regno,bool incr_p)1653*e4b17023SJohn Marino change_pressure (int regno, bool incr_p)
1654*e4b17023SJohn Marino {
1655*e4b17023SJohn Marino int nregs;
1656*e4b17023SJohn Marino enum reg_class pressure_class;
1657*e4b17023SJohn Marino
1658*e4b17023SJohn Marino pressure_class = get_regno_pressure_class (regno, &nregs);
1659*e4b17023SJohn Marino if (! incr_p)
1660*e4b17023SJohn Marino curr_reg_pressure[pressure_class] -= nregs;
1661*e4b17023SJohn Marino else
1662*e4b17023SJohn Marino {
1663*e4b17023SJohn Marino curr_reg_pressure[pressure_class] += nregs;
1664*e4b17023SJohn Marino if (LOOP_DATA (curr_loop)->max_reg_pressure[pressure_class]
1665*e4b17023SJohn Marino < curr_reg_pressure[pressure_class])
1666*e4b17023SJohn Marino LOOP_DATA (curr_loop)->max_reg_pressure[pressure_class]
1667*e4b17023SJohn Marino = curr_reg_pressure[pressure_class];
1668*e4b17023SJohn Marino }
1669*e4b17023SJohn Marino }
1670*e4b17023SJohn Marino
1671*e4b17023SJohn Marino /* Mark REGNO birth. */
1672*e4b17023SJohn Marino static void
mark_regno_live(int regno)1673*e4b17023SJohn Marino mark_regno_live (int regno)
1674*e4b17023SJohn Marino {
1675*e4b17023SJohn Marino struct loop *loop;
1676*e4b17023SJohn Marino
1677*e4b17023SJohn Marino for (loop = curr_loop;
1678*e4b17023SJohn Marino loop != current_loops->tree_root;
1679*e4b17023SJohn Marino loop = loop_outer (loop))
1680*e4b17023SJohn Marino bitmap_set_bit (&LOOP_DATA (loop)->regs_live, regno);
1681*e4b17023SJohn Marino if (!bitmap_set_bit (&curr_regs_live, regno))
1682*e4b17023SJohn Marino return;
1683*e4b17023SJohn Marino change_pressure (regno, true);
1684*e4b17023SJohn Marino }
1685*e4b17023SJohn Marino
1686*e4b17023SJohn Marino /* Mark REGNO death. */
1687*e4b17023SJohn Marino static void
mark_regno_death(int regno)1688*e4b17023SJohn Marino mark_regno_death (int regno)
1689*e4b17023SJohn Marino {
1690*e4b17023SJohn Marino if (! bitmap_clear_bit (&curr_regs_live, regno))
1691*e4b17023SJohn Marino return;
1692*e4b17023SJohn Marino change_pressure (regno, false);
1693*e4b17023SJohn Marino }
1694*e4b17023SJohn Marino
1695*e4b17023SJohn Marino /* Mark setting register REG. */
1696*e4b17023SJohn Marino static void
mark_reg_store(rtx reg,const_rtx setter ATTRIBUTE_UNUSED,void * data ATTRIBUTE_UNUSED)1697*e4b17023SJohn Marino mark_reg_store (rtx reg, const_rtx setter ATTRIBUTE_UNUSED,
1698*e4b17023SJohn Marino void *data ATTRIBUTE_UNUSED)
1699*e4b17023SJohn Marino {
1700*e4b17023SJohn Marino int regno;
1701*e4b17023SJohn Marino
1702*e4b17023SJohn Marino if (GET_CODE (reg) == SUBREG)
1703*e4b17023SJohn Marino reg = SUBREG_REG (reg);
1704*e4b17023SJohn Marino
1705*e4b17023SJohn Marino if (! REG_P (reg))
1706*e4b17023SJohn Marino return;
1707*e4b17023SJohn Marino
1708*e4b17023SJohn Marino regs_set[n_regs_set++] = reg;
1709*e4b17023SJohn Marino
1710*e4b17023SJohn Marino regno = REGNO (reg);
1711*e4b17023SJohn Marino
1712*e4b17023SJohn Marino if (regno >= FIRST_PSEUDO_REGISTER)
1713*e4b17023SJohn Marino mark_regno_live (regno);
1714*e4b17023SJohn Marino else
1715*e4b17023SJohn Marino {
1716*e4b17023SJohn Marino int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
1717*e4b17023SJohn Marino
1718*e4b17023SJohn Marino while (regno < last)
1719*e4b17023SJohn Marino {
1720*e4b17023SJohn Marino mark_regno_live (regno);
1721*e4b17023SJohn Marino regno++;
1722*e4b17023SJohn Marino }
1723*e4b17023SJohn Marino }
1724*e4b17023SJohn Marino }
1725*e4b17023SJohn Marino
1726*e4b17023SJohn Marino /* Mark clobbering register REG. */
1727*e4b17023SJohn Marino static void
mark_reg_clobber(rtx reg,const_rtx setter,void * data)1728*e4b17023SJohn Marino mark_reg_clobber (rtx reg, const_rtx setter, void *data)
1729*e4b17023SJohn Marino {
1730*e4b17023SJohn Marino if (GET_CODE (setter) == CLOBBER)
1731*e4b17023SJohn Marino mark_reg_store (reg, setter, data);
1732*e4b17023SJohn Marino }
1733*e4b17023SJohn Marino
1734*e4b17023SJohn Marino /* Mark register REG death. */
1735*e4b17023SJohn Marino static void
mark_reg_death(rtx reg)1736*e4b17023SJohn Marino mark_reg_death (rtx reg)
1737*e4b17023SJohn Marino {
1738*e4b17023SJohn Marino int regno = REGNO (reg);
1739*e4b17023SJohn Marino
1740*e4b17023SJohn Marino if (regno >= FIRST_PSEUDO_REGISTER)
1741*e4b17023SJohn Marino mark_regno_death (regno);
1742*e4b17023SJohn Marino else
1743*e4b17023SJohn Marino {
1744*e4b17023SJohn Marino int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
1745*e4b17023SJohn Marino
1746*e4b17023SJohn Marino while (regno < last)
1747*e4b17023SJohn Marino {
1748*e4b17023SJohn Marino mark_regno_death (regno);
1749*e4b17023SJohn Marino regno++;
1750*e4b17023SJohn Marino }
1751*e4b17023SJohn Marino }
1752*e4b17023SJohn Marino }
1753*e4b17023SJohn Marino
1754*e4b17023SJohn Marino /* Mark occurrence of registers in X for the current loop. */
1755*e4b17023SJohn Marino static void
mark_ref_regs(rtx x)1756*e4b17023SJohn Marino mark_ref_regs (rtx x)
1757*e4b17023SJohn Marino {
1758*e4b17023SJohn Marino RTX_CODE code;
1759*e4b17023SJohn Marino int i;
1760*e4b17023SJohn Marino const char *fmt;
1761*e4b17023SJohn Marino
1762*e4b17023SJohn Marino if (!x)
1763*e4b17023SJohn Marino return;
1764*e4b17023SJohn Marino
1765*e4b17023SJohn Marino code = GET_CODE (x);
1766*e4b17023SJohn Marino if (code == REG)
1767*e4b17023SJohn Marino {
1768*e4b17023SJohn Marino struct loop *loop;
1769*e4b17023SJohn Marino
1770*e4b17023SJohn Marino for (loop = curr_loop;
1771*e4b17023SJohn Marino loop != current_loops->tree_root;
1772*e4b17023SJohn Marino loop = loop_outer (loop))
1773*e4b17023SJohn Marino bitmap_set_bit (&LOOP_DATA (loop)->regs_ref, REGNO (x));
1774*e4b17023SJohn Marino return;
1775*e4b17023SJohn Marino }
1776*e4b17023SJohn Marino
1777*e4b17023SJohn Marino fmt = GET_RTX_FORMAT (code);
1778*e4b17023SJohn Marino for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1779*e4b17023SJohn Marino if (fmt[i] == 'e')
1780*e4b17023SJohn Marino mark_ref_regs (XEXP (x, i));
1781*e4b17023SJohn Marino else if (fmt[i] == 'E')
1782*e4b17023SJohn Marino {
1783*e4b17023SJohn Marino int j;
1784*e4b17023SJohn Marino
1785*e4b17023SJohn Marino for (j = 0; j < XVECLEN (x, i); j++)
1786*e4b17023SJohn Marino mark_ref_regs (XVECEXP (x, i, j));
1787*e4b17023SJohn Marino }
1788*e4b17023SJohn Marino }
1789*e4b17023SJohn Marino
1790*e4b17023SJohn Marino /* Calculate register pressure in the loops. */
1791*e4b17023SJohn Marino static void
calculate_loop_reg_pressure(void)1792*e4b17023SJohn Marino calculate_loop_reg_pressure (void)
1793*e4b17023SJohn Marino {
1794*e4b17023SJohn Marino int i;
1795*e4b17023SJohn Marino unsigned int j;
1796*e4b17023SJohn Marino bitmap_iterator bi;
1797*e4b17023SJohn Marino basic_block bb;
1798*e4b17023SJohn Marino rtx insn, link;
1799*e4b17023SJohn Marino struct loop *loop, *parent;
1800*e4b17023SJohn Marino loop_iterator li;
1801*e4b17023SJohn Marino
1802*e4b17023SJohn Marino FOR_EACH_LOOP (li, loop, 0)
1803*e4b17023SJohn Marino if (loop->aux == NULL)
1804*e4b17023SJohn Marino {
1805*e4b17023SJohn Marino loop->aux = xcalloc (1, sizeof (struct loop_data));
1806*e4b17023SJohn Marino bitmap_initialize (&LOOP_DATA (loop)->regs_ref, ®_obstack);
1807*e4b17023SJohn Marino bitmap_initialize (&LOOP_DATA (loop)->regs_live, ®_obstack);
1808*e4b17023SJohn Marino }
1809*e4b17023SJohn Marino ira_setup_eliminable_regset ();
1810*e4b17023SJohn Marino bitmap_initialize (&curr_regs_live, ®_obstack);
1811*e4b17023SJohn Marino FOR_EACH_BB (bb)
1812*e4b17023SJohn Marino {
1813*e4b17023SJohn Marino curr_loop = bb->loop_father;
1814*e4b17023SJohn Marino if (curr_loop == current_loops->tree_root)
1815*e4b17023SJohn Marino continue;
1816*e4b17023SJohn Marino
1817*e4b17023SJohn Marino for (loop = curr_loop;
1818*e4b17023SJohn Marino loop != current_loops->tree_root;
1819*e4b17023SJohn Marino loop = loop_outer (loop))
1820*e4b17023SJohn Marino bitmap_ior_into (&LOOP_DATA (loop)->regs_live, DF_LR_IN (bb));
1821*e4b17023SJohn Marino
1822*e4b17023SJohn Marino bitmap_copy (&curr_regs_live, DF_LR_IN (bb));
1823*e4b17023SJohn Marino for (i = 0; i < ira_pressure_classes_num; i++)
1824*e4b17023SJohn Marino curr_reg_pressure[ira_pressure_classes[i]] = 0;
1825*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (&curr_regs_live, 0, j, bi)
1826*e4b17023SJohn Marino change_pressure (j, true);
1827*e4b17023SJohn Marino
1828*e4b17023SJohn Marino FOR_BB_INSNS (bb, insn)
1829*e4b17023SJohn Marino {
1830*e4b17023SJohn Marino if (! NONDEBUG_INSN_P (insn))
1831*e4b17023SJohn Marino continue;
1832*e4b17023SJohn Marino
1833*e4b17023SJohn Marino mark_ref_regs (PATTERN (insn));
1834*e4b17023SJohn Marino n_regs_set = 0;
1835*e4b17023SJohn Marino note_stores (PATTERN (insn), mark_reg_clobber, NULL);
1836*e4b17023SJohn Marino
1837*e4b17023SJohn Marino /* Mark any registers dead after INSN as dead now. */
1838*e4b17023SJohn Marino
1839*e4b17023SJohn Marino for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1840*e4b17023SJohn Marino if (REG_NOTE_KIND (link) == REG_DEAD)
1841*e4b17023SJohn Marino mark_reg_death (XEXP (link, 0));
1842*e4b17023SJohn Marino
1843*e4b17023SJohn Marino /* Mark any registers set in INSN as live,
1844*e4b17023SJohn Marino and mark them as conflicting with all other live regs.
1845*e4b17023SJohn Marino Clobbers are processed again, so they conflict with
1846*e4b17023SJohn Marino the registers that are set. */
1847*e4b17023SJohn Marino
1848*e4b17023SJohn Marino note_stores (PATTERN (insn), mark_reg_store, NULL);
1849*e4b17023SJohn Marino
1850*e4b17023SJohn Marino #ifdef AUTO_INC_DEC
1851*e4b17023SJohn Marino for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1852*e4b17023SJohn Marino if (REG_NOTE_KIND (link) == REG_INC)
1853*e4b17023SJohn Marino mark_reg_store (XEXP (link, 0), NULL_RTX, NULL);
1854*e4b17023SJohn Marino #endif
1855*e4b17023SJohn Marino while (n_regs_set-- > 0)
1856*e4b17023SJohn Marino {
1857*e4b17023SJohn Marino rtx note = find_regno_note (insn, REG_UNUSED,
1858*e4b17023SJohn Marino REGNO (regs_set[n_regs_set]));
1859*e4b17023SJohn Marino if (! note)
1860*e4b17023SJohn Marino continue;
1861*e4b17023SJohn Marino
1862*e4b17023SJohn Marino mark_reg_death (XEXP (note, 0));
1863*e4b17023SJohn Marino }
1864*e4b17023SJohn Marino }
1865*e4b17023SJohn Marino }
1866*e4b17023SJohn Marino bitmap_clear (&curr_regs_live);
1867*e4b17023SJohn Marino if (flag_ira_region == IRA_REGION_MIXED
1868*e4b17023SJohn Marino || flag_ira_region == IRA_REGION_ALL)
1869*e4b17023SJohn Marino FOR_EACH_LOOP (li, loop, 0)
1870*e4b17023SJohn Marino {
1871*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (&LOOP_DATA (loop)->regs_live, 0, j, bi)
1872*e4b17023SJohn Marino if (! bitmap_bit_p (&LOOP_DATA (loop)->regs_ref, j))
1873*e4b17023SJohn Marino {
1874*e4b17023SJohn Marino enum reg_class pressure_class;
1875*e4b17023SJohn Marino int nregs;
1876*e4b17023SJohn Marino
1877*e4b17023SJohn Marino pressure_class = get_regno_pressure_class (j, &nregs);
1878*e4b17023SJohn Marino LOOP_DATA (loop)->max_reg_pressure[pressure_class] -= nregs;
1879*e4b17023SJohn Marino }
1880*e4b17023SJohn Marino }
1881*e4b17023SJohn Marino if (dump_file == NULL)
1882*e4b17023SJohn Marino return;
1883*e4b17023SJohn Marino FOR_EACH_LOOP (li, loop, 0)
1884*e4b17023SJohn Marino {
1885*e4b17023SJohn Marino parent = loop_outer (loop);
1886*e4b17023SJohn Marino fprintf (dump_file, "\n Loop %d (parent %d, header bb%d, depth %d)\n",
1887*e4b17023SJohn Marino loop->num, (parent == NULL ? -1 : parent->num),
1888*e4b17023SJohn Marino loop->header->index, loop_depth (loop));
1889*e4b17023SJohn Marino fprintf (dump_file, "\n ref. regnos:");
1890*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (&LOOP_DATA (loop)->regs_ref, 0, j, bi)
1891*e4b17023SJohn Marino fprintf (dump_file, " %d", j);
1892*e4b17023SJohn Marino fprintf (dump_file, "\n live regnos:");
1893*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (&LOOP_DATA (loop)->regs_live, 0, j, bi)
1894*e4b17023SJohn Marino fprintf (dump_file, " %d", j);
1895*e4b17023SJohn Marino fprintf (dump_file, "\n Pressure:");
1896*e4b17023SJohn Marino for (i = 0; (int) i < ira_pressure_classes_num; i++)
1897*e4b17023SJohn Marino {
1898*e4b17023SJohn Marino enum reg_class pressure_class;
1899*e4b17023SJohn Marino
1900*e4b17023SJohn Marino pressure_class = ira_pressure_classes[i];
1901*e4b17023SJohn Marino if (LOOP_DATA (loop)->max_reg_pressure[pressure_class] == 0)
1902*e4b17023SJohn Marino continue;
1903*e4b17023SJohn Marino fprintf (dump_file, " %s=%d", reg_class_names[pressure_class],
1904*e4b17023SJohn Marino LOOP_DATA (loop)->max_reg_pressure[pressure_class]);
1905*e4b17023SJohn Marino }
1906*e4b17023SJohn Marino fprintf (dump_file, "\n");
1907*e4b17023SJohn Marino }
1908*e4b17023SJohn Marino }
1909*e4b17023SJohn Marino
1910*e4b17023SJohn Marino
1911*e4b17023SJohn Marino
1912*e4b17023SJohn Marino /* Move the invariants out of the loops. */
1913*e4b17023SJohn Marino
1914*e4b17023SJohn Marino void
move_loop_invariants(void)1915*e4b17023SJohn Marino move_loop_invariants (void)
1916*e4b17023SJohn Marino {
1917*e4b17023SJohn Marino struct loop *loop;
1918*e4b17023SJohn Marino loop_iterator li;
1919*e4b17023SJohn Marino
1920*e4b17023SJohn Marino if (flag_ira_loop_pressure)
1921*e4b17023SJohn Marino {
1922*e4b17023SJohn Marino df_analyze ();
1923*e4b17023SJohn Marino regstat_init_n_sets_and_refs ();
1924*e4b17023SJohn Marino ira_set_pseudo_classes (dump_file);
1925*e4b17023SJohn Marino calculate_loop_reg_pressure ();
1926*e4b17023SJohn Marino regstat_free_n_sets_and_refs ();
1927*e4b17023SJohn Marino }
1928*e4b17023SJohn Marino df_set_flags (DF_EQ_NOTES + DF_DEFER_INSN_RESCAN);
1929*e4b17023SJohn Marino /* Process the loops, innermost first. */
1930*e4b17023SJohn Marino FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
1931*e4b17023SJohn Marino {
1932*e4b17023SJohn Marino curr_loop = loop;
1933*e4b17023SJohn Marino /* move_single_loop_invariants for very large loops
1934*e4b17023SJohn Marino is time consuming and might need a lot of memory. */
1935*e4b17023SJohn Marino if (loop->num_nodes <= (unsigned) LOOP_INVARIANT_MAX_BBS_IN_LOOP)
1936*e4b17023SJohn Marino move_single_loop_invariants (loop);
1937*e4b17023SJohn Marino }
1938*e4b17023SJohn Marino
1939*e4b17023SJohn Marino FOR_EACH_LOOP (li, loop, 0)
1940*e4b17023SJohn Marino {
1941*e4b17023SJohn Marino free_loop_data (loop);
1942*e4b17023SJohn Marino }
1943*e4b17023SJohn Marino
1944*e4b17023SJohn Marino if (flag_ira_loop_pressure)
1945*e4b17023SJohn Marino /* There is no sense to keep this info because it was most
1946*e4b17023SJohn Marino probably outdated by subsequent passes. */
1947*e4b17023SJohn Marino free_reg_info ();
1948*e4b17023SJohn Marino free (invariant_table);
1949*e4b17023SJohn Marino invariant_table = NULL;
1950*e4b17023SJohn Marino invariant_table_size = 0;
1951*e4b17023SJohn Marino
1952*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
1953*e4b17023SJohn Marino verify_flow_info ();
1954*e4b17023SJohn Marino #endif
1955*e4b17023SJohn Marino }
1956