xref: /dflybsd-src/contrib/gcc-4.7/gcc/loop-invariant.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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, &reg_obstack);
637*e4b17023SJohn Marino       bitmap_initialize (&LOOP_DATA (loop)->regs_live, &reg_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, &reg_obstack);
1807*e4b17023SJohn Marino 	bitmap_initialize (&LOOP_DATA (loop)->regs_live, &reg_obstack);
1808*e4b17023SJohn Marino       }
1809*e4b17023SJohn Marino   ira_setup_eliminable_regset ();
1810*e4b17023SJohn Marino   bitmap_initialize (&curr_regs_live, &reg_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