1*404b540aSrobert /* Register renaming for the GNU compiler.
2*404b540aSrobert Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
3*404b540aSrobert Free Software Foundation, Inc.
4*404b540aSrobert
5*404b540aSrobert This file is part of GCC.
6*404b540aSrobert
7*404b540aSrobert GCC is free software; you can redistribute it and/or modify it
8*404b540aSrobert under the terms of the GNU General Public License as published by
9*404b540aSrobert the Free Software Foundation; either version 2, or (at your option)
10*404b540aSrobert any later version.
11*404b540aSrobert
12*404b540aSrobert GCC is distributed in the hope that it will be useful, but WITHOUT
13*404b540aSrobert ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14*404b540aSrobert or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15*404b540aSrobert License for more details.
16*404b540aSrobert
17*404b540aSrobert You should have received a copy of the GNU General Public License
18*404b540aSrobert along with GCC; see the file COPYING. If not, write to the Free
19*404b540aSrobert Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20*404b540aSrobert 02110-1301, USA. */
21*404b540aSrobert
22*404b540aSrobert #include "config.h"
23*404b540aSrobert #include "system.h"
24*404b540aSrobert #include "coretypes.h"
25*404b540aSrobert #include "tm.h"
26*404b540aSrobert #include "rtl.h"
27*404b540aSrobert #include "tm_p.h"
28*404b540aSrobert #include "insn-config.h"
29*404b540aSrobert #include "regs.h"
30*404b540aSrobert #include "addresses.h"
31*404b540aSrobert #include "hard-reg-set.h"
32*404b540aSrobert #include "basic-block.h"
33*404b540aSrobert #include "reload.h"
34*404b540aSrobert #include "output.h"
35*404b540aSrobert #include "function.h"
36*404b540aSrobert #include "recog.h"
37*404b540aSrobert #include "flags.h"
38*404b540aSrobert #include "toplev.h"
39*404b540aSrobert #include "obstack.h"
40*404b540aSrobert #include "timevar.h"
41*404b540aSrobert #include "tree-pass.h"
42*404b540aSrobert
43*404b540aSrobert struct du_chain
44*404b540aSrobert {
45*404b540aSrobert struct du_chain *next_chain;
46*404b540aSrobert struct du_chain *next_use;
47*404b540aSrobert
48*404b540aSrobert rtx insn;
49*404b540aSrobert rtx *loc;
50*404b540aSrobert ENUM_BITFIELD(reg_class) cl : 16;
51*404b540aSrobert unsigned int need_caller_save_reg:1;
52*404b540aSrobert unsigned int earlyclobber:1;
53*404b540aSrobert };
54*404b540aSrobert
55*404b540aSrobert enum scan_actions
56*404b540aSrobert {
57*404b540aSrobert terminate_all_read,
58*404b540aSrobert terminate_overlapping_read,
59*404b540aSrobert terminate_write,
60*404b540aSrobert terminate_dead,
61*404b540aSrobert mark_read,
62*404b540aSrobert mark_write,
63*404b540aSrobert /* mark_access is for marking the destination regs in
64*404b540aSrobert REG_FRAME_RELATED_EXPR notes (as if they were read) so that the
65*404b540aSrobert note is updated properly. */
66*404b540aSrobert mark_access
67*404b540aSrobert };
68*404b540aSrobert
69*404b540aSrobert static const char * const scan_actions_name[] =
70*404b540aSrobert {
71*404b540aSrobert "terminate_all_read",
72*404b540aSrobert "terminate_overlapping_read",
73*404b540aSrobert "terminate_write",
74*404b540aSrobert "terminate_dead",
75*404b540aSrobert "mark_read",
76*404b540aSrobert "mark_write",
77*404b540aSrobert "mark_access"
78*404b540aSrobert };
79*404b540aSrobert
80*404b540aSrobert static struct obstack rename_obstack;
81*404b540aSrobert
82*404b540aSrobert static void do_replace (struct du_chain *, int);
83*404b540aSrobert static void scan_rtx_reg (rtx, rtx *, enum reg_class,
84*404b540aSrobert enum scan_actions, enum op_type, int);
85*404b540aSrobert static void scan_rtx_address (rtx, rtx *, enum reg_class,
86*404b540aSrobert enum scan_actions, enum machine_mode);
87*404b540aSrobert static void scan_rtx (rtx, rtx *, enum reg_class, enum scan_actions,
88*404b540aSrobert enum op_type, int);
89*404b540aSrobert static struct du_chain *build_def_use (basic_block);
90*404b540aSrobert static void dump_def_use_chain (struct du_chain *);
91*404b540aSrobert static void note_sets (rtx, rtx, void *);
92*404b540aSrobert static void clear_dead_regs (HARD_REG_SET *, enum machine_mode, rtx);
93*404b540aSrobert static void merge_overlapping_regs (basic_block, HARD_REG_SET *,
94*404b540aSrobert struct du_chain *);
95*404b540aSrobert
96*404b540aSrobert /* Called through note_stores from update_life. Find sets of registers, and
97*404b540aSrobert record them in *DATA (which is actually a HARD_REG_SET *). */
98*404b540aSrobert
99*404b540aSrobert static void
note_sets(rtx x,rtx set ATTRIBUTE_UNUSED,void * data)100*404b540aSrobert note_sets (rtx x, rtx set ATTRIBUTE_UNUSED, void *data)
101*404b540aSrobert {
102*404b540aSrobert HARD_REG_SET *pset = (HARD_REG_SET *) data;
103*404b540aSrobert unsigned int regno;
104*404b540aSrobert int nregs;
105*404b540aSrobert
106*404b540aSrobert if (GET_CODE (x) == SUBREG)
107*404b540aSrobert x = SUBREG_REG (x);
108*404b540aSrobert if (!REG_P (x))
109*404b540aSrobert return;
110*404b540aSrobert regno = REGNO (x);
111*404b540aSrobert nregs = hard_regno_nregs[regno][GET_MODE (x)];
112*404b540aSrobert
113*404b540aSrobert /* There must not be pseudos at this point. */
114*404b540aSrobert gcc_assert (regno + nregs <= FIRST_PSEUDO_REGISTER);
115*404b540aSrobert
116*404b540aSrobert while (nregs-- > 0)
117*404b540aSrobert SET_HARD_REG_BIT (*pset, regno + nregs);
118*404b540aSrobert }
119*404b540aSrobert
120*404b540aSrobert /* Clear all registers from *PSET for which a note of kind KIND can be found
121*404b540aSrobert in the list NOTES. */
122*404b540aSrobert
123*404b540aSrobert static void
clear_dead_regs(HARD_REG_SET * pset,enum machine_mode kind,rtx notes)124*404b540aSrobert clear_dead_regs (HARD_REG_SET *pset, enum machine_mode kind, rtx notes)
125*404b540aSrobert {
126*404b540aSrobert rtx note;
127*404b540aSrobert for (note = notes; note; note = XEXP (note, 1))
128*404b540aSrobert if (REG_NOTE_KIND (note) == kind && REG_P (XEXP (note, 0)))
129*404b540aSrobert {
130*404b540aSrobert rtx reg = XEXP (note, 0);
131*404b540aSrobert unsigned int regno = REGNO (reg);
132*404b540aSrobert int nregs = hard_regno_nregs[regno][GET_MODE (reg)];
133*404b540aSrobert
134*404b540aSrobert /* There must not be pseudos at this point. */
135*404b540aSrobert gcc_assert (regno + nregs <= FIRST_PSEUDO_REGISTER);
136*404b540aSrobert
137*404b540aSrobert while (nregs-- > 0)
138*404b540aSrobert CLEAR_HARD_REG_BIT (*pset, regno + nregs);
139*404b540aSrobert }
140*404b540aSrobert }
141*404b540aSrobert
142*404b540aSrobert /* For a def-use chain CHAIN in basic block B, find which registers overlap
143*404b540aSrobert its lifetime and set the corresponding bits in *PSET. */
144*404b540aSrobert
145*404b540aSrobert static void
merge_overlapping_regs(basic_block b,HARD_REG_SET * pset,struct du_chain * chain)146*404b540aSrobert merge_overlapping_regs (basic_block b, HARD_REG_SET *pset,
147*404b540aSrobert struct du_chain *chain)
148*404b540aSrobert {
149*404b540aSrobert struct du_chain *t = chain;
150*404b540aSrobert rtx insn;
151*404b540aSrobert HARD_REG_SET live;
152*404b540aSrobert
153*404b540aSrobert REG_SET_TO_HARD_REG_SET (live, b->il.rtl->global_live_at_start);
154*404b540aSrobert insn = BB_HEAD (b);
155*404b540aSrobert while (t)
156*404b540aSrobert {
157*404b540aSrobert /* Search forward until the next reference to the register to be
158*404b540aSrobert renamed. */
159*404b540aSrobert while (insn != t->insn)
160*404b540aSrobert {
161*404b540aSrobert if (INSN_P (insn))
162*404b540aSrobert {
163*404b540aSrobert clear_dead_regs (&live, REG_DEAD, REG_NOTES (insn));
164*404b540aSrobert note_stores (PATTERN (insn), note_sets, (void *) &live);
165*404b540aSrobert /* Only record currently live regs if we are inside the
166*404b540aSrobert reg's live range. */
167*404b540aSrobert if (t != chain)
168*404b540aSrobert IOR_HARD_REG_SET (*pset, live);
169*404b540aSrobert clear_dead_regs (&live, REG_UNUSED, REG_NOTES (insn));
170*404b540aSrobert }
171*404b540aSrobert insn = NEXT_INSN (insn);
172*404b540aSrobert }
173*404b540aSrobert
174*404b540aSrobert IOR_HARD_REG_SET (*pset, live);
175*404b540aSrobert
176*404b540aSrobert /* For the last reference, also merge in all registers set in the
177*404b540aSrobert same insn.
178*404b540aSrobert @@@ We only have take earlyclobbered sets into account. */
179*404b540aSrobert if (! t->next_use)
180*404b540aSrobert note_stores (PATTERN (insn), note_sets, (void *) pset);
181*404b540aSrobert
182*404b540aSrobert t = t->next_use;
183*404b540aSrobert }
184*404b540aSrobert }
185*404b540aSrobert
186*404b540aSrobert /* Perform register renaming on the current function. */
187*404b540aSrobert
188*404b540aSrobert static void
regrename_optimize(void)189*404b540aSrobert regrename_optimize (void)
190*404b540aSrobert {
191*404b540aSrobert int tick[FIRST_PSEUDO_REGISTER];
192*404b540aSrobert int this_tick = 0;
193*404b540aSrobert basic_block bb;
194*404b540aSrobert char *first_obj;
195*404b540aSrobert
196*404b540aSrobert memset (tick, 0, sizeof tick);
197*404b540aSrobert
198*404b540aSrobert gcc_obstack_init (&rename_obstack);
199*404b540aSrobert first_obj = obstack_alloc (&rename_obstack, 0);
200*404b540aSrobert
201*404b540aSrobert FOR_EACH_BB (bb)
202*404b540aSrobert {
203*404b540aSrobert struct du_chain *all_chains = 0;
204*404b540aSrobert HARD_REG_SET unavailable;
205*404b540aSrobert HARD_REG_SET regs_seen;
206*404b540aSrobert
207*404b540aSrobert CLEAR_HARD_REG_SET (unavailable);
208*404b540aSrobert
209*404b540aSrobert if (dump_file)
210*404b540aSrobert fprintf (dump_file, "\nBasic block %d:\n", bb->index);
211*404b540aSrobert
212*404b540aSrobert all_chains = build_def_use (bb);
213*404b540aSrobert
214*404b540aSrobert if (dump_file)
215*404b540aSrobert dump_def_use_chain (all_chains);
216*404b540aSrobert
217*404b540aSrobert CLEAR_HARD_REG_SET (unavailable);
218*404b540aSrobert /* Don't clobber traceback for noreturn functions. */
219*404b540aSrobert if (frame_pointer_needed)
220*404b540aSrobert {
221*404b540aSrobert int i;
222*404b540aSrobert
223*404b540aSrobert for (i = hard_regno_nregs[FRAME_POINTER_REGNUM][Pmode]; i--;)
224*404b540aSrobert SET_HARD_REG_BIT (unavailable, FRAME_POINTER_REGNUM + i);
225*404b540aSrobert
226*404b540aSrobert #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
227*404b540aSrobert for (i = hard_regno_nregs[HARD_FRAME_POINTER_REGNUM][Pmode]; i--;)
228*404b540aSrobert SET_HARD_REG_BIT (unavailable, HARD_FRAME_POINTER_REGNUM + i);
229*404b540aSrobert #endif
230*404b540aSrobert }
231*404b540aSrobert
232*404b540aSrobert CLEAR_HARD_REG_SET (regs_seen);
233*404b540aSrobert while (all_chains)
234*404b540aSrobert {
235*404b540aSrobert int new_reg, best_new_reg;
236*404b540aSrobert int n_uses;
237*404b540aSrobert struct du_chain *this = all_chains;
238*404b540aSrobert struct du_chain *tmp, *last;
239*404b540aSrobert HARD_REG_SET this_unavailable;
240*404b540aSrobert int reg = REGNO (*this->loc);
241*404b540aSrobert int i;
242*404b540aSrobert
243*404b540aSrobert all_chains = this->next_chain;
244*404b540aSrobert
245*404b540aSrobert best_new_reg = reg;
246*404b540aSrobert
247*404b540aSrobert #if 0 /* This just disables optimization opportunities. */
248*404b540aSrobert /* Only rename once we've seen the reg more than once. */
249*404b540aSrobert if (! TEST_HARD_REG_BIT (regs_seen, reg))
250*404b540aSrobert {
251*404b540aSrobert SET_HARD_REG_BIT (regs_seen, reg);
252*404b540aSrobert continue;
253*404b540aSrobert }
254*404b540aSrobert #endif
255*404b540aSrobert
256*404b540aSrobert if (fixed_regs[reg] || global_regs[reg]
257*404b540aSrobert #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
258*404b540aSrobert || (frame_pointer_needed && reg == HARD_FRAME_POINTER_REGNUM)
259*404b540aSrobert #else
260*404b540aSrobert || (frame_pointer_needed && reg == FRAME_POINTER_REGNUM)
261*404b540aSrobert #endif
262*404b540aSrobert )
263*404b540aSrobert continue;
264*404b540aSrobert
265*404b540aSrobert COPY_HARD_REG_SET (this_unavailable, unavailable);
266*404b540aSrobert
267*404b540aSrobert /* Find last entry on chain (which has the need_caller_save bit),
268*404b540aSrobert count number of uses, and narrow the set of registers we can
269*404b540aSrobert use for renaming. */
270*404b540aSrobert n_uses = 0;
271*404b540aSrobert for (last = this; last->next_use; last = last->next_use)
272*404b540aSrobert {
273*404b540aSrobert n_uses++;
274*404b540aSrobert IOR_COMPL_HARD_REG_SET (this_unavailable,
275*404b540aSrobert reg_class_contents[last->cl]);
276*404b540aSrobert }
277*404b540aSrobert if (n_uses < 1)
278*404b540aSrobert continue;
279*404b540aSrobert
280*404b540aSrobert IOR_COMPL_HARD_REG_SET (this_unavailable,
281*404b540aSrobert reg_class_contents[last->cl]);
282*404b540aSrobert
283*404b540aSrobert if (this->need_caller_save_reg)
284*404b540aSrobert IOR_HARD_REG_SET (this_unavailable, call_used_reg_set);
285*404b540aSrobert
286*404b540aSrobert merge_overlapping_regs (bb, &this_unavailable, this);
287*404b540aSrobert
288*404b540aSrobert /* Now potential_regs is a reasonable approximation, let's
289*404b540aSrobert have a closer look at each register still in there. */
290*404b540aSrobert for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
291*404b540aSrobert {
292*404b540aSrobert int nregs = hard_regno_nregs[new_reg][GET_MODE (*this->loc)];
293*404b540aSrobert
294*404b540aSrobert for (i = nregs - 1; i >= 0; --i)
295*404b540aSrobert if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i)
296*404b540aSrobert || fixed_regs[new_reg + i]
297*404b540aSrobert || global_regs[new_reg + i]
298*404b540aSrobert /* Can't use regs which aren't saved by the prologue. */
299*404b540aSrobert || (! regs_ever_live[new_reg + i]
300*404b540aSrobert && ! call_used_regs[new_reg + i])
301*404b540aSrobert #ifdef LEAF_REGISTERS
302*404b540aSrobert /* We can't use a non-leaf register if we're in a
303*404b540aSrobert leaf function. */
304*404b540aSrobert || (current_function_is_leaf
305*404b540aSrobert && !LEAF_REGISTERS[new_reg + i])
306*404b540aSrobert #endif
307*404b540aSrobert #ifdef HARD_REGNO_RENAME_OK
308*404b540aSrobert || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i)
309*404b540aSrobert #endif
310*404b540aSrobert )
311*404b540aSrobert break;
312*404b540aSrobert if (i >= 0)
313*404b540aSrobert continue;
314*404b540aSrobert
315*404b540aSrobert /* See whether it accepts all modes that occur in
316*404b540aSrobert definition and uses. */
317*404b540aSrobert for (tmp = this; tmp; tmp = tmp->next_use)
318*404b540aSrobert if (! HARD_REGNO_MODE_OK (new_reg, GET_MODE (*tmp->loc))
319*404b540aSrobert || (tmp->need_caller_save_reg
320*404b540aSrobert && ! (HARD_REGNO_CALL_PART_CLOBBERED
321*404b540aSrobert (reg, GET_MODE (*tmp->loc)))
322*404b540aSrobert && (HARD_REGNO_CALL_PART_CLOBBERED
323*404b540aSrobert (new_reg, GET_MODE (*tmp->loc)))))
324*404b540aSrobert break;
325*404b540aSrobert if (! tmp)
326*404b540aSrobert {
327*404b540aSrobert if (tick[best_new_reg] > tick[new_reg])
328*404b540aSrobert best_new_reg = new_reg;
329*404b540aSrobert }
330*404b540aSrobert }
331*404b540aSrobert
332*404b540aSrobert if (dump_file)
333*404b540aSrobert {
334*404b540aSrobert fprintf (dump_file, "Register %s in insn %d",
335*404b540aSrobert reg_names[reg], INSN_UID (last->insn));
336*404b540aSrobert if (last->need_caller_save_reg)
337*404b540aSrobert fprintf (dump_file, " crosses a call");
338*404b540aSrobert }
339*404b540aSrobert
340*404b540aSrobert if (best_new_reg == reg)
341*404b540aSrobert {
342*404b540aSrobert tick[reg] = ++this_tick;
343*404b540aSrobert if (dump_file)
344*404b540aSrobert fprintf (dump_file, "; no available better choice\n");
345*404b540aSrobert continue;
346*404b540aSrobert }
347*404b540aSrobert
348*404b540aSrobert do_replace (this, best_new_reg);
349*404b540aSrobert tick[best_new_reg] = ++this_tick;
350*404b540aSrobert regs_ever_live[best_new_reg] = 1;
351*404b540aSrobert
352*404b540aSrobert if (dump_file)
353*404b540aSrobert fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
354*404b540aSrobert }
355*404b540aSrobert
356*404b540aSrobert obstack_free (&rename_obstack, first_obj);
357*404b540aSrobert }
358*404b540aSrobert
359*404b540aSrobert obstack_free (&rename_obstack, NULL);
360*404b540aSrobert
361*404b540aSrobert if (dump_file)
362*404b540aSrobert fputc ('\n', dump_file);
363*404b540aSrobert
364*404b540aSrobert count_or_remove_death_notes (NULL, 1);
365*404b540aSrobert update_life_info (NULL, UPDATE_LIFE_LOCAL,
366*404b540aSrobert PROP_DEATH_NOTES);
367*404b540aSrobert }
368*404b540aSrobert
369*404b540aSrobert static void
do_replace(struct du_chain * chain,int reg)370*404b540aSrobert do_replace (struct du_chain *chain, int reg)
371*404b540aSrobert {
372*404b540aSrobert while (chain)
373*404b540aSrobert {
374*404b540aSrobert unsigned int regno = ORIGINAL_REGNO (*chain->loc);
375*404b540aSrobert struct reg_attrs * attr = REG_ATTRS (*chain->loc);
376*404b540aSrobert
377*404b540aSrobert *chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg);
378*404b540aSrobert if (regno >= FIRST_PSEUDO_REGISTER)
379*404b540aSrobert ORIGINAL_REGNO (*chain->loc) = regno;
380*404b540aSrobert REG_ATTRS (*chain->loc) = attr;
381*404b540aSrobert chain = chain->next_use;
382*404b540aSrobert }
383*404b540aSrobert }
384*404b540aSrobert
385*404b540aSrobert
386*404b540aSrobert static struct du_chain *open_chains;
387*404b540aSrobert static struct du_chain *closed_chains;
388*404b540aSrobert
389*404b540aSrobert static void
scan_rtx_reg(rtx insn,rtx * loc,enum reg_class cl,enum scan_actions action,enum op_type type,int earlyclobber)390*404b540aSrobert scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl,
391*404b540aSrobert enum scan_actions action, enum op_type type, int earlyclobber)
392*404b540aSrobert {
393*404b540aSrobert struct du_chain **p;
394*404b540aSrobert rtx x = *loc;
395*404b540aSrobert enum machine_mode mode = GET_MODE (x);
396*404b540aSrobert int this_regno = REGNO (x);
397*404b540aSrobert int this_nregs = hard_regno_nregs[this_regno][mode];
398*404b540aSrobert
399*404b540aSrobert if (action == mark_write)
400*404b540aSrobert {
401*404b540aSrobert if (type == OP_OUT)
402*404b540aSrobert {
403*404b540aSrobert struct du_chain *this
404*404b540aSrobert = obstack_alloc (&rename_obstack, sizeof (struct du_chain));
405*404b540aSrobert this->next_use = 0;
406*404b540aSrobert this->next_chain = open_chains;
407*404b540aSrobert this->loc = loc;
408*404b540aSrobert this->insn = insn;
409*404b540aSrobert this->cl = cl;
410*404b540aSrobert this->need_caller_save_reg = 0;
411*404b540aSrobert this->earlyclobber = earlyclobber;
412*404b540aSrobert open_chains = this;
413*404b540aSrobert }
414*404b540aSrobert return;
415*404b540aSrobert }
416*404b540aSrobert
417*404b540aSrobert if ((type == OP_OUT) != (action == terminate_write || action == mark_access))
418*404b540aSrobert return;
419*404b540aSrobert
420*404b540aSrobert for (p = &open_chains; *p;)
421*404b540aSrobert {
422*404b540aSrobert struct du_chain *this = *p;
423*404b540aSrobert
424*404b540aSrobert /* Check if the chain has been terminated if it has then skip to
425*404b540aSrobert the next chain.
426*404b540aSrobert
427*404b540aSrobert This can happen when we've already appended the location to
428*404b540aSrobert the chain in Step 3, but are trying to hide in-out operands
429*404b540aSrobert from terminate_write in Step 5. */
430*404b540aSrobert
431*404b540aSrobert if (*this->loc == cc0_rtx)
432*404b540aSrobert p = &this->next_chain;
433*404b540aSrobert else
434*404b540aSrobert {
435*404b540aSrobert int regno = REGNO (*this->loc);
436*404b540aSrobert int nregs = hard_regno_nregs[regno][GET_MODE (*this->loc)];
437*404b540aSrobert int exact_match = (regno == this_regno && nregs == this_nregs);
438*404b540aSrobert
439*404b540aSrobert if (regno + nregs <= this_regno
440*404b540aSrobert || this_regno + this_nregs <= regno)
441*404b540aSrobert {
442*404b540aSrobert p = &this->next_chain;
443*404b540aSrobert continue;
444*404b540aSrobert }
445*404b540aSrobert
446*404b540aSrobert if (action == mark_read || action == mark_access)
447*404b540aSrobert {
448*404b540aSrobert gcc_assert (exact_match);
449*404b540aSrobert
450*404b540aSrobert /* ??? Class NO_REGS can happen if the md file makes use of
451*404b540aSrobert EXTRA_CONSTRAINTS to match registers. Which is arguably
452*404b540aSrobert wrong, but there we are. Since we know not what this may
453*404b540aSrobert be replaced with, terminate the chain. */
454*404b540aSrobert if (cl != NO_REGS)
455*404b540aSrobert {
456*404b540aSrobert this = obstack_alloc (&rename_obstack, sizeof (struct du_chain));
457*404b540aSrobert this->next_use = 0;
458*404b540aSrobert this->next_chain = (*p)->next_chain;
459*404b540aSrobert this->loc = loc;
460*404b540aSrobert this->insn = insn;
461*404b540aSrobert this->cl = cl;
462*404b540aSrobert this->need_caller_save_reg = 0;
463*404b540aSrobert while (*p)
464*404b540aSrobert p = &(*p)->next_use;
465*404b540aSrobert *p = this;
466*404b540aSrobert return;
467*404b540aSrobert }
468*404b540aSrobert }
469*404b540aSrobert
470*404b540aSrobert if (action != terminate_overlapping_read || ! exact_match)
471*404b540aSrobert {
472*404b540aSrobert struct du_chain *next = this->next_chain;
473*404b540aSrobert
474*404b540aSrobert /* Whether the terminated chain can be used for renaming
475*404b540aSrobert depends on the action and this being an exact match.
476*404b540aSrobert In either case, we remove this element from open_chains. */
477*404b540aSrobert
478*404b540aSrobert if ((action == terminate_dead || action == terminate_write)
479*404b540aSrobert && exact_match)
480*404b540aSrobert {
481*404b540aSrobert this->next_chain = closed_chains;
482*404b540aSrobert closed_chains = this;
483*404b540aSrobert if (dump_file)
484*404b540aSrobert fprintf (dump_file,
485*404b540aSrobert "Closing chain %s at insn %d (%s)\n",
486*404b540aSrobert reg_names[REGNO (*this->loc)], INSN_UID (insn),
487*404b540aSrobert scan_actions_name[(int) action]);
488*404b540aSrobert }
489*404b540aSrobert else
490*404b540aSrobert {
491*404b540aSrobert if (dump_file)
492*404b540aSrobert fprintf (dump_file,
493*404b540aSrobert "Discarding chain %s at insn %d (%s)\n",
494*404b540aSrobert reg_names[REGNO (*this->loc)], INSN_UID (insn),
495*404b540aSrobert scan_actions_name[(int) action]);
496*404b540aSrobert }
497*404b540aSrobert *p = next;
498*404b540aSrobert }
499*404b540aSrobert else
500*404b540aSrobert p = &this->next_chain;
501*404b540aSrobert }
502*404b540aSrobert }
503*404b540aSrobert }
504*404b540aSrobert
505*404b540aSrobert /* Adapted from find_reloads_address_1. CL is INDEX_REG_CLASS or
506*404b540aSrobert BASE_REG_CLASS depending on how the register is being considered. */
507*404b540aSrobert
508*404b540aSrobert static void
scan_rtx_address(rtx insn,rtx * loc,enum reg_class cl,enum scan_actions action,enum machine_mode mode)509*404b540aSrobert scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl,
510*404b540aSrobert enum scan_actions action, enum machine_mode mode)
511*404b540aSrobert {
512*404b540aSrobert rtx x = *loc;
513*404b540aSrobert RTX_CODE code = GET_CODE (x);
514*404b540aSrobert const char *fmt;
515*404b540aSrobert int i, j;
516*404b540aSrobert
517*404b540aSrobert if (action == mark_write || action == mark_access)
518*404b540aSrobert return;
519*404b540aSrobert
520*404b540aSrobert switch (code)
521*404b540aSrobert {
522*404b540aSrobert case PLUS:
523*404b540aSrobert {
524*404b540aSrobert rtx orig_op0 = XEXP (x, 0);
525*404b540aSrobert rtx orig_op1 = XEXP (x, 1);
526*404b540aSrobert RTX_CODE code0 = GET_CODE (orig_op0);
527*404b540aSrobert RTX_CODE code1 = GET_CODE (orig_op1);
528*404b540aSrobert rtx op0 = orig_op0;
529*404b540aSrobert rtx op1 = orig_op1;
530*404b540aSrobert rtx *locI = NULL;
531*404b540aSrobert rtx *locB = NULL;
532*404b540aSrobert enum rtx_code index_code = SCRATCH;
533*404b540aSrobert
534*404b540aSrobert if (GET_CODE (op0) == SUBREG)
535*404b540aSrobert {
536*404b540aSrobert op0 = SUBREG_REG (op0);
537*404b540aSrobert code0 = GET_CODE (op0);
538*404b540aSrobert }
539*404b540aSrobert
540*404b540aSrobert if (GET_CODE (op1) == SUBREG)
541*404b540aSrobert {
542*404b540aSrobert op1 = SUBREG_REG (op1);
543*404b540aSrobert code1 = GET_CODE (op1);
544*404b540aSrobert }
545*404b540aSrobert
546*404b540aSrobert if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
547*404b540aSrobert || code0 == ZERO_EXTEND || code1 == MEM)
548*404b540aSrobert {
549*404b540aSrobert locI = &XEXP (x, 0);
550*404b540aSrobert locB = &XEXP (x, 1);
551*404b540aSrobert index_code = GET_CODE (*locI);
552*404b540aSrobert }
553*404b540aSrobert else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
554*404b540aSrobert || code1 == ZERO_EXTEND || code0 == MEM)
555*404b540aSrobert {
556*404b540aSrobert locI = &XEXP (x, 1);
557*404b540aSrobert locB = &XEXP (x, 0);
558*404b540aSrobert index_code = GET_CODE (*locI);
559*404b540aSrobert }
560*404b540aSrobert else if (code0 == CONST_INT || code0 == CONST
561*404b540aSrobert || code0 == SYMBOL_REF || code0 == LABEL_REF)
562*404b540aSrobert {
563*404b540aSrobert locB = &XEXP (x, 1);
564*404b540aSrobert index_code = GET_CODE (XEXP (x, 0));
565*404b540aSrobert }
566*404b540aSrobert else if (code1 == CONST_INT || code1 == CONST
567*404b540aSrobert || code1 == SYMBOL_REF || code1 == LABEL_REF)
568*404b540aSrobert {
569*404b540aSrobert locB = &XEXP (x, 0);
570*404b540aSrobert index_code = GET_CODE (XEXP (x, 1));
571*404b540aSrobert }
572*404b540aSrobert else if (code0 == REG && code1 == REG)
573*404b540aSrobert {
574*404b540aSrobert int index_op;
575*404b540aSrobert unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
576*404b540aSrobert
577*404b540aSrobert if (REGNO_OK_FOR_INDEX_P (regno0)
578*404b540aSrobert && regno_ok_for_base_p (regno1, mode, PLUS, REG))
579*404b540aSrobert index_op = 0;
580*404b540aSrobert else if (REGNO_OK_FOR_INDEX_P (regno1)
581*404b540aSrobert && regno_ok_for_base_p (regno0, mode, PLUS, REG))
582*404b540aSrobert index_op = 1;
583*404b540aSrobert else if (regno_ok_for_base_p (regno1, mode, PLUS, REG))
584*404b540aSrobert index_op = 0;
585*404b540aSrobert else if (regno_ok_for_base_p (regno0, mode, PLUS, REG))
586*404b540aSrobert index_op = 1;
587*404b540aSrobert else if (REGNO_OK_FOR_INDEX_P (regno1))
588*404b540aSrobert index_op = 1;
589*404b540aSrobert else
590*404b540aSrobert index_op = 0;
591*404b540aSrobert
592*404b540aSrobert locI = &XEXP (x, index_op);
593*404b540aSrobert locB = &XEXP (x, !index_op);
594*404b540aSrobert index_code = GET_CODE (*locI);
595*404b540aSrobert }
596*404b540aSrobert else if (code0 == REG)
597*404b540aSrobert {
598*404b540aSrobert locI = &XEXP (x, 0);
599*404b540aSrobert locB = &XEXP (x, 1);
600*404b540aSrobert index_code = GET_CODE (*locI);
601*404b540aSrobert }
602*404b540aSrobert else if (code1 == REG)
603*404b540aSrobert {
604*404b540aSrobert locI = &XEXP (x, 1);
605*404b540aSrobert locB = &XEXP (x, 0);
606*404b540aSrobert index_code = GET_CODE (*locI);
607*404b540aSrobert }
608*404b540aSrobert
609*404b540aSrobert if (locI)
610*404b540aSrobert scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode);
611*404b540aSrobert if (locB)
612*404b540aSrobert scan_rtx_address (insn, locB, base_reg_class (mode, PLUS, index_code),
613*404b540aSrobert action, mode);
614*404b540aSrobert
615*404b540aSrobert return;
616*404b540aSrobert }
617*404b540aSrobert
618*404b540aSrobert case POST_INC:
619*404b540aSrobert case POST_DEC:
620*404b540aSrobert case POST_MODIFY:
621*404b540aSrobert case PRE_INC:
622*404b540aSrobert case PRE_DEC:
623*404b540aSrobert case PRE_MODIFY:
624*404b540aSrobert #ifndef AUTO_INC_DEC
625*404b540aSrobert /* If the target doesn't claim to handle autoinc, this must be
626*404b540aSrobert something special, like a stack push. Kill this chain. */
627*404b540aSrobert action = terminate_all_read;
628*404b540aSrobert #endif
629*404b540aSrobert break;
630*404b540aSrobert
631*404b540aSrobert case MEM:
632*404b540aSrobert scan_rtx_address (insn, &XEXP (x, 0),
633*404b540aSrobert base_reg_class (GET_MODE (x), MEM, SCRATCH), action,
634*404b540aSrobert GET_MODE (x));
635*404b540aSrobert return;
636*404b540aSrobert
637*404b540aSrobert case REG:
638*404b540aSrobert scan_rtx_reg (insn, loc, cl, action, OP_IN, 0);
639*404b540aSrobert return;
640*404b540aSrobert
641*404b540aSrobert default:
642*404b540aSrobert break;
643*404b540aSrobert }
644*404b540aSrobert
645*404b540aSrobert fmt = GET_RTX_FORMAT (code);
646*404b540aSrobert for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
647*404b540aSrobert {
648*404b540aSrobert if (fmt[i] == 'e')
649*404b540aSrobert scan_rtx_address (insn, &XEXP (x, i), cl, action, mode);
650*404b540aSrobert else if (fmt[i] == 'E')
651*404b540aSrobert for (j = XVECLEN (x, i) - 1; j >= 0; j--)
652*404b540aSrobert scan_rtx_address (insn, &XVECEXP (x, i, j), cl, action, mode);
653*404b540aSrobert }
654*404b540aSrobert }
655*404b540aSrobert
656*404b540aSrobert static void
scan_rtx(rtx insn,rtx * loc,enum reg_class cl,enum scan_actions action,enum op_type type,int earlyclobber)657*404b540aSrobert scan_rtx (rtx insn, rtx *loc, enum reg_class cl,
658*404b540aSrobert enum scan_actions action, enum op_type type, int earlyclobber)
659*404b540aSrobert {
660*404b540aSrobert const char *fmt;
661*404b540aSrobert rtx x = *loc;
662*404b540aSrobert enum rtx_code code = GET_CODE (x);
663*404b540aSrobert int i, j;
664*404b540aSrobert
665*404b540aSrobert code = GET_CODE (x);
666*404b540aSrobert switch (code)
667*404b540aSrobert {
668*404b540aSrobert case CONST:
669*404b540aSrobert case CONST_INT:
670*404b540aSrobert case CONST_DOUBLE:
671*404b540aSrobert case CONST_VECTOR:
672*404b540aSrobert case SYMBOL_REF:
673*404b540aSrobert case LABEL_REF:
674*404b540aSrobert case CC0:
675*404b540aSrobert case PC:
676*404b540aSrobert return;
677*404b540aSrobert
678*404b540aSrobert case REG:
679*404b540aSrobert scan_rtx_reg (insn, loc, cl, action, type, earlyclobber);
680*404b540aSrobert return;
681*404b540aSrobert
682*404b540aSrobert case MEM:
683*404b540aSrobert scan_rtx_address (insn, &XEXP (x, 0),
684*404b540aSrobert base_reg_class (GET_MODE (x), MEM, SCRATCH), action,
685*404b540aSrobert GET_MODE (x));
686*404b540aSrobert return;
687*404b540aSrobert
688*404b540aSrobert case SET:
689*404b540aSrobert scan_rtx (insn, &SET_SRC (x), cl, action, OP_IN, 0);
690*404b540aSrobert scan_rtx (insn, &SET_DEST (x), cl, action,
691*404b540aSrobert GET_CODE (PATTERN (insn)) == COND_EXEC ? OP_INOUT : OP_OUT, 0);
692*404b540aSrobert return;
693*404b540aSrobert
694*404b540aSrobert case STRICT_LOW_PART:
695*404b540aSrobert scan_rtx (insn, &XEXP (x, 0), cl, action, OP_INOUT, earlyclobber);
696*404b540aSrobert return;
697*404b540aSrobert
698*404b540aSrobert case ZERO_EXTRACT:
699*404b540aSrobert case SIGN_EXTRACT:
700*404b540aSrobert scan_rtx (insn, &XEXP (x, 0), cl, action,
701*404b540aSrobert type == OP_IN ? OP_IN : OP_INOUT, earlyclobber);
702*404b540aSrobert scan_rtx (insn, &XEXP (x, 1), cl, action, OP_IN, 0);
703*404b540aSrobert scan_rtx (insn, &XEXP (x, 2), cl, action, OP_IN, 0);
704*404b540aSrobert return;
705*404b540aSrobert
706*404b540aSrobert case POST_INC:
707*404b540aSrobert case PRE_INC:
708*404b540aSrobert case POST_DEC:
709*404b540aSrobert case PRE_DEC:
710*404b540aSrobert case POST_MODIFY:
711*404b540aSrobert case PRE_MODIFY:
712*404b540aSrobert /* Should only happen inside MEM. */
713*404b540aSrobert gcc_unreachable ();
714*404b540aSrobert
715*404b540aSrobert case CLOBBER:
716*404b540aSrobert scan_rtx (insn, &SET_DEST (x), cl, action,
717*404b540aSrobert GET_CODE (PATTERN (insn)) == COND_EXEC ? OP_INOUT : OP_OUT, 0);
718*404b540aSrobert return;
719*404b540aSrobert
720*404b540aSrobert case EXPR_LIST:
721*404b540aSrobert scan_rtx (insn, &XEXP (x, 0), cl, action, type, 0);
722*404b540aSrobert if (XEXP (x, 1))
723*404b540aSrobert scan_rtx (insn, &XEXP (x, 1), cl, action, type, 0);
724*404b540aSrobert return;
725*404b540aSrobert
726*404b540aSrobert default:
727*404b540aSrobert break;
728*404b540aSrobert }
729*404b540aSrobert
730*404b540aSrobert fmt = GET_RTX_FORMAT (code);
731*404b540aSrobert for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
732*404b540aSrobert {
733*404b540aSrobert if (fmt[i] == 'e')
734*404b540aSrobert scan_rtx (insn, &XEXP (x, i), cl, action, type, 0);
735*404b540aSrobert else if (fmt[i] == 'E')
736*404b540aSrobert for (j = XVECLEN (x, i) - 1; j >= 0; j--)
737*404b540aSrobert scan_rtx (insn, &XVECEXP (x, i, j), cl, action, type, 0);
738*404b540aSrobert }
739*404b540aSrobert }
740*404b540aSrobert
741*404b540aSrobert /* Build def/use chain. */
742*404b540aSrobert
743*404b540aSrobert static struct du_chain *
build_def_use(basic_block bb)744*404b540aSrobert build_def_use (basic_block bb)
745*404b540aSrobert {
746*404b540aSrobert rtx insn;
747*404b540aSrobert
748*404b540aSrobert open_chains = closed_chains = NULL;
749*404b540aSrobert
750*404b540aSrobert for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
751*404b540aSrobert {
752*404b540aSrobert if (INSN_P (insn))
753*404b540aSrobert {
754*404b540aSrobert int n_ops;
755*404b540aSrobert rtx note;
756*404b540aSrobert rtx old_operands[MAX_RECOG_OPERANDS];
757*404b540aSrobert rtx old_dups[MAX_DUP_OPERANDS];
758*404b540aSrobert int i, icode;
759*404b540aSrobert int alt;
760*404b540aSrobert int predicated;
761*404b540aSrobert
762*404b540aSrobert /* Process the insn, determining its effect on the def-use
763*404b540aSrobert chains. We perform the following steps with the register
764*404b540aSrobert references in the insn:
765*404b540aSrobert (1) Any read that overlaps an open chain, but doesn't exactly
766*404b540aSrobert match, causes that chain to be closed. We can't deal
767*404b540aSrobert with overlaps yet.
768*404b540aSrobert (2) Any read outside an operand causes any chain it overlaps
769*404b540aSrobert with to be closed, since we can't replace it.
770*404b540aSrobert (3) Any read inside an operand is added if there's already
771*404b540aSrobert an open chain for it.
772*404b540aSrobert (4) For any REG_DEAD note we find, close open chains that
773*404b540aSrobert overlap it.
774*404b540aSrobert (5) For any write we find, close open chains that overlap it.
775*404b540aSrobert (6) For any write we find in an operand, make a new chain.
776*404b540aSrobert (7) For any REG_UNUSED, close any chains we just opened. */
777*404b540aSrobert
778*404b540aSrobert icode = recog_memoized (insn);
779*404b540aSrobert extract_insn (insn);
780*404b540aSrobert if (! constrain_operands (1))
781*404b540aSrobert fatal_insn_not_found (insn);
782*404b540aSrobert preprocess_constraints ();
783*404b540aSrobert alt = which_alternative;
784*404b540aSrobert n_ops = recog_data.n_operands;
785*404b540aSrobert
786*404b540aSrobert /* Simplify the code below by rewriting things to reflect
787*404b540aSrobert matching constraints. Also promote OP_OUT to OP_INOUT
788*404b540aSrobert in predicated instructions. */
789*404b540aSrobert
790*404b540aSrobert predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
791*404b540aSrobert for (i = 0; i < n_ops; ++i)
792*404b540aSrobert {
793*404b540aSrobert int matches = recog_op_alt[i][alt].matches;
794*404b540aSrobert if (matches >= 0)
795*404b540aSrobert recog_op_alt[i][alt].cl = recog_op_alt[matches][alt].cl;
796*404b540aSrobert if (matches >= 0 || recog_op_alt[i][alt].matched >= 0
797*404b540aSrobert || (predicated && recog_data.operand_type[i] == OP_OUT))
798*404b540aSrobert recog_data.operand_type[i] = OP_INOUT;
799*404b540aSrobert }
800*404b540aSrobert
801*404b540aSrobert /* Step 1: Close chains for which we have overlapping reads. */
802*404b540aSrobert for (i = 0; i < n_ops; i++)
803*404b540aSrobert scan_rtx (insn, recog_data.operand_loc[i],
804*404b540aSrobert NO_REGS, terminate_overlapping_read,
805*404b540aSrobert recog_data.operand_type[i], 0);
806*404b540aSrobert
807*404b540aSrobert /* Step 2: Close chains for which we have reads outside operands.
808*404b540aSrobert We do this by munging all operands into CC0, and closing
809*404b540aSrobert everything remaining. */
810*404b540aSrobert
811*404b540aSrobert for (i = 0; i < n_ops; i++)
812*404b540aSrobert {
813*404b540aSrobert old_operands[i] = recog_data.operand[i];
814*404b540aSrobert /* Don't squash match_operator or match_parallel here, since
815*404b540aSrobert we don't know that all of the contained registers are
816*404b540aSrobert reachable by proper operands. */
817*404b540aSrobert if (recog_data.constraints[i][0] == '\0')
818*404b540aSrobert continue;
819*404b540aSrobert *recog_data.operand_loc[i] = cc0_rtx;
820*404b540aSrobert }
821*404b540aSrobert for (i = 0; i < recog_data.n_dups; i++)
822*404b540aSrobert {
823*404b540aSrobert int dup_num = recog_data.dup_num[i];
824*404b540aSrobert
825*404b540aSrobert old_dups[i] = *recog_data.dup_loc[i];
826*404b540aSrobert *recog_data.dup_loc[i] = cc0_rtx;
827*404b540aSrobert
828*404b540aSrobert /* For match_dup of match_operator or match_parallel, share
829*404b540aSrobert them, so that we don't miss changes in the dup. */
830*404b540aSrobert if (icode >= 0
831*404b540aSrobert && insn_data[icode].operand[dup_num].eliminable == 0)
832*404b540aSrobert old_dups[i] = recog_data.operand[dup_num];
833*404b540aSrobert }
834*404b540aSrobert
835*404b540aSrobert scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_all_read,
836*404b540aSrobert OP_IN, 0);
837*404b540aSrobert
838*404b540aSrobert for (i = 0; i < recog_data.n_dups; i++)
839*404b540aSrobert *recog_data.dup_loc[i] = old_dups[i];
840*404b540aSrobert for (i = 0; i < n_ops; i++)
841*404b540aSrobert *recog_data.operand_loc[i] = old_operands[i];
842*404b540aSrobert
843*404b540aSrobert /* Step 2B: Can't rename function call argument registers. */
844*404b540aSrobert if (CALL_P (insn) && CALL_INSN_FUNCTION_USAGE (insn))
845*404b540aSrobert scan_rtx (insn, &CALL_INSN_FUNCTION_USAGE (insn),
846*404b540aSrobert NO_REGS, terminate_all_read, OP_IN, 0);
847*404b540aSrobert
848*404b540aSrobert /* Step 2C: Can't rename asm operands that were originally
849*404b540aSrobert hard registers. */
850*404b540aSrobert if (asm_noperands (PATTERN (insn)) > 0)
851*404b540aSrobert for (i = 0; i < n_ops; i++)
852*404b540aSrobert {
853*404b540aSrobert rtx *loc = recog_data.operand_loc[i];
854*404b540aSrobert rtx op = *loc;
855*404b540aSrobert
856*404b540aSrobert if (REG_P (op)
857*404b540aSrobert && REGNO (op) == ORIGINAL_REGNO (op)
858*404b540aSrobert && (recog_data.operand_type[i] == OP_IN
859*404b540aSrobert || recog_data.operand_type[i] == OP_INOUT))
860*404b540aSrobert scan_rtx (insn, loc, NO_REGS, terminate_all_read, OP_IN, 0);
861*404b540aSrobert }
862*404b540aSrobert
863*404b540aSrobert /* Step 3: Append to chains for reads inside operands. */
864*404b540aSrobert for (i = 0; i < n_ops + recog_data.n_dups; i++)
865*404b540aSrobert {
866*404b540aSrobert int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
867*404b540aSrobert rtx *loc = (i < n_ops
868*404b540aSrobert ? recog_data.operand_loc[opn]
869*404b540aSrobert : recog_data.dup_loc[i - n_ops]);
870*404b540aSrobert enum reg_class cl = recog_op_alt[opn][alt].cl;
871*404b540aSrobert enum op_type type = recog_data.operand_type[opn];
872*404b540aSrobert
873*404b540aSrobert /* Don't scan match_operand here, since we've no reg class
874*404b540aSrobert information to pass down. Any operands that we could
875*404b540aSrobert substitute in will be represented elsewhere. */
876*404b540aSrobert if (recog_data.constraints[opn][0] == '\0')
877*404b540aSrobert continue;
878*404b540aSrobert
879*404b540aSrobert if (recog_op_alt[opn][alt].is_address)
880*404b540aSrobert scan_rtx_address (insn, loc, cl, mark_read, VOIDmode);
881*404b540aSrobert else
882*404b540aSrobert scan_rtx (insn, loc, cl, mark_read, type, 0);
883*404b540aSrobert }
884*404b540aSrobert
885*404b540aSrobert /* Step 3B: Record updates for regs in REG_INC notes, and
886*404b540aSrobert source regs in REG_FRAME_RELATED_EXPR notes. */
887*404b540aSrobert for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
888*404b540aSrobert if (REG_NOTE_KIND (note) == REG_INC
889*404b540aSrobert || REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
890*404b540aSrobert scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_read,
891*404b540aSrobert OP_INOUT, 0);
892*404b540aSrobert
893*404b540aSrobert /* Step 4: Close chains for registers that die here. */
894*404b540aSrobert for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
895*404b540aSrobert if (REG_NOTE_KIND (note) == REG_DEAD)
896*404b540aSrobert scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
897*404b540aSrobert OP_IN, 0);
898*404b540aSrobert
899*404b540aSrobert /* Step 4B: If this is a call, any chain live at this point
900*404b540aSrobert requires a caller-saved reg. */
901*404b540aSrobert if (CALL_P (insn))
902*404b540aSrobert {
903*404b540aSrobert struct du_chain *p;
904*404b540aSrobert for (p = open_chains; p; p = p->next_chain)
905*404b540aSrobert p->need_caller_save_reg = 1;
906*404b540aSrobert }
907*404b540aSrobert
908*404b540aSrobert /* Step 5: Close open chains that overlap writes. Similar to
909*404b540aSrobert step 2, we hide in-out operands, since we do not want to
910*404b540aSrobert close these chains. */
911*404b540aSrobert
912*404b540aSrobert for (i = 0; i < n_ops; i++)
913*404b540aSrobert {
914*404b540aSrobert old_operands[i] = recog_data.operand[i];
915*404b540aSrobert if (recog_data.operand_type[i] == OP_INOUT)
916*404b540aSrobert *recog_data.operand_loc[i] = cc0_rtx;
917*404b540aSrobert }
918*404b540aSrobert for (i = 0; i < recog_data.n_dups; i++)
919*404b540aSrobert {
920*404b540aSrobert int opn = recog_data.dup_num[i];
921*404b540aSrobert old_dups[i] = *recog_data.dup_loc[i];
922*404b540aSrobert if (recog_data.operand_type[opn] == OP_INOUT)
923*404b540aSrobert *recog_data.dup_loc[i] = cc0_rtx;
924*404b540aSrobert }
925*404b540aSrobert
926*404b540aSrobert scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_write, OP_IN, 0);
927*404b540aSrobert
928*404b540aSrobert for (i = 0; i < recog_data.n_dups; i++)
929*404b540aSrobert *recog_data.dup_loc[i] = old_dups[i];
930*404b540aSrobert for (i = 0; i < n_ops; i++)
931*404b540aSrobert *recog_data.operand_loc[i] = old_operands[i];
932*404b540aSrobert
933*404b540aSrobert /* Step 6: Begin new chains for writes inside operands. */
934*404b540aSrobert /* ??? Many targets have output constraints on the SET_DEST
935*404b540aSrobert of a call insn, which is stupid, since these are certainly
936*404b540aSrobert ABI defined hard registers. Don't change calls at all.
937*404b540aSrobert Similarly take special care for asm statement that originally
938*404b540aSrobert referenced hard registers. */
939*404b540aSrobert if (asm_noperands (PATTERN (insn)) > 0)
940*404b540aSrobert {
941*404b540aSrobert for (i = 0; i < n_ops; i++)
942*404b540aSrobert if (recog_data.operand_type[i] == OP_OUT)
943*404b540aSrobert {
944*404b540aSrobert rtx *loc = recog_data.operand_loc[i];
945*404b540aSrobert rtx op = *loc;
946*404b540aSrobert enum reg_class cl = recog_op_alt[i][alt].cl;
947*404b540aSrobert
948*404b540aSrobert if (REG_P (op)
949*404b540aSrobert && REGNO (op) == ORIGINAL_REGNO (op))
950*404b540aSrobert continue;
951*404b540aSrobert
952*404b540aSrobert scan_rtx (insn, loc, cl, mark_write, OP_OUT,
953*404b540aSrobert recog_op_alt[i][alt].earlyclobber);
954*404b540aSrobert }
955*404b540aSrobert }
956*404b540aSrobert else if (!CALL_P (insn))
957*404b540aSrobert for (i = 0; i < n_ops + recog_data.n_dups; i++)
958*404b540aSrobert {
959*404b540aSrobert int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
960*404b540aSrobert rtx *loc = (i < n_ops
961*404b540aSrobert ? recog_data.operand_loc[opn]
962*404b540aSrobert : recog_data.dup_loc[i - n_ops]);
963*404b540aSrobert enum reg_class cl = recog_op_alt[opn][alt].cl;
964*404b540aSrobert
965*404b540aSrobert if (recog_data.operand_type[opn] == OP_OUT)
966*404b540aSrobert scan_rtx (insn, loc, cl, mark_write, OP_OUT,
967*404b540aSrobert recog_op_alt[opn][alt].earlyclobber);
968*404b540aSrobert }
969*404b540aSrobert
970*404b540aSrobert /* Step 6B: Record destination regs in REG_FRAME_RELATED_EXPR
971*404b540aSrobert notes for update. */
972*404b540aSrobert for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
973*404b540aSrobert if (REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
974*404b540aSrobert scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_access,
975*404b540aSrobert OP_INOUT, 0);
976*404b540aSrobert
977*404b540aSrobert /* Step 7: Close chains for registers that were never
978*404b540aSrobert really used here. */
979*404b540aSrobert for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
980*404b540aSrobert if (REG_NOTE_KIND (note) == REG_UNUSED)
981*404b540aSrobert scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
982*404b540aSrobert OP_IN, 0);
983*404b540aSrobert }
984*404b540aSrobert if (insn == BB_END (bb))
985*404b540aSrobert break;
986*404b540aSrobert }
987*404b540aSrobert
988*404b540aSrobert /* Since we close every chain when we find a REG_DEAD note, anything that
989*404b540aSrobert is still open lives past the basic block, so it can't be renamed. */
990*404b540aSrobert return closed_chains;
991*404b540aSrobert }
992*404b540aSrobert
993*404b540aSrobert /* Dump all def/use chains in CHAINS to DUMP_FILE. They are
994*404b540aSrobert printed in reverse order as that's how we build them. */
995*404b540aSrobert
996*404b540aSrobert static void
dump_def_use_chain(struct du_chain * chains)997*404b540aSrobert dump_def_use_chain (struct du_chain *chains)
998*404b540aSrobert {
999*404b540aSrobert while (chains)
1000*404b540aSrobert {
1001*404b540aSrobert struct du_chain *this = chains;
1002*404b540aSrobert int r = REGNO (*this->loc);
1003*404b540aSrobert int nregs = hard_regno_nregs[r][GET_MODE (*this->loc)];
1004*404b540aSrobert fprintf (dump_file, "Register %s (%d):", reg_names[r], nregs);
1005*404b540aSrobert while (this)
1006*404b540aSrobert {
1007*404b540aSrobert fprintf (dump_file, " %d [%s]", INSN_UID (this->insn),
1008*404b540aSrobert reg_class_names[this->cl]);
1009*404b540aSrobert this = this->next_use;
1010*404b540aSrobert }
1011*404b540aSrobert fprintf (dump_file, "\n");
1012*404b540aSrobert chains = chains->next_chain;
1013*404b540aSrobert }
1014*404b540aSrobert }
1015*404b540aSrobert
1016*404b540aSrobert /* The following code does forward propagation of hard register copies.
1017*404b540aSrobert The object is to eliminate as many dependencies as possible, so that
1018*404b540aSrobert we have the most scheduling freedom. As a side effect, we also clean
1019*404b540aSrobert up some silly register allocation decisions made by reload. This
1020*404b540aSrobert code may be obsoleted by a new register allocator. */
1021*404b540aSrobert
1022*404b540aSrobert /* For each register, we have a list of registers that contain the same
1023*404b540aSrobert value. The OLDEST_REGNO field points to the head of the list, and
1024*404b540aSrobert the NEXT_REGNO field runs through the list. The MODE field indicates
1025*404b540aSrobert what mode the data is known to be in; this field is VOIDmode when the
1026*404b540aSrobert register is not known to contain valid data. */
1027*404b540aSrobert
1028*404b540aSrobert struct value_data_entry
1029*404b540aSrobert {
1030*404b540aSrobert enum machine_mode mode;
1031*404b540aSrobert unsigned int oldest_regno;
1032*404b540aSrobert unsigned int next_regno;
1033*404b540aSrobert };
1034*404b540aSrobert
1035*404b540aSrobert struct value_data
1036*404b540aSrobert {
1037*404b540aSrobert struct value_data_entry e[FIRST_PSEUDO_REGISTER];
1038*404b540aSrobert unsigned int max_value_regs;
1039*404b540aSrobert };
1040*404b540aSrobert
1041*404b540aSrobert static void kill_value_one_regno (unsigned, struct value_data *);
1042*404b540aSrobert static void kill_value_regno (unsigned, unsigned, struct value_data *);
1043*404b540aSrobert static void kill_value (rtx, struct value_data *);
1044*404b540aSrobert static void set_value_regno (unsigned, enum machine_mode, struct value_data *);
1045*404b540aSrobert static void init_value_data (struct value_data *);
1046*404b540aSrobert static void kill_clobbered_value (rtx, rtx, void *);
1047*404b540aSrobert static void kill_set_value (rtx, rtx, void *);
1048*404b540aSrobert static int kill_autoinc_value (rtx *, void *);
1049*404b540aSrobert static void copy_value (rtx, rtx, struct value_data *);
1050*404b540aSrobert static bool mode_change_ok (enum machine_mode, enum machine_mode,
1051*404b540aSrobert unsigned int);
1052*404b540aSrobert static rtx maybe_mode_change (enum machine_mode, enum machine_mode,
1053*404b540aSrobert enum machine_mode, unsigned int, unsigned int);
1054*404b540aSrobert static rtx find_oldest_value_reg (enum reg_class, rtx, struct value_data *);
1055*404b540aSrobert static bool replace_oldest_value_reg (rtx *, enum reg_class, rtx,
1056*404b540aSrobert struct value_data *);
1057*404b540aSrobert static bool replace_oldest_value_addr (rtx *, enum reg_class,
1058*404b540aSrobert enum machine_mode, rtx,
1059*404b540aSrobert struct value_data *);
1060*404b540aSrobert static bool replace_oldest_value_mem (rtx, rtx, struct value_data *);
1061*404b540aSrobert static bool copyprop_hardreg_forward_1 (basic_block, struct value_data *);
1062*404b540aSrobert extern void debug_value_data (struct value_data *);
1063*404b540aSrobert #ifdef ENABLE_CHECKING
1064*404b540aSrobert static void validate_value_data (struct value_data *);
1065*404b540aSrobert #endif
1066*404b540aSrobert
1067*404b540aSrobert /* Kill register REGNO. This involves removing it from any value
1068*404b540aSrobert lists, and resetting the value mode to VOIDmode. This is only a
1069*404b540aSrobert helper function; it does not handle any hard registers overlapping
1070*404b540aSrobert with REGNO. */
1071*404b540aSrobert
1072*404b540aSrobert static void
kill_value_one_regno(unsigned int regno,struct value_data * vd)1073*404b540aSrobert kill_value_one_regno (unsigned int regno, struct value_data *vd)
1074*404b540aSrobert {
1075*404b540aSrobert unsigned int i, next;
1076*404b540aSrobert
1077*404b540aSrobert if (vd->e[regno].oldest_regno != regno)
1078*404b540aSrobert {
1079*404b540aSrobert for (i = vd->e[regno].oldest_regno;
1080*404b540aSrobert vd->e[i].next_regno != regno;
1081*404b540aSrobert i = vd->e[i].next_regno)
1082*404b540aSrobert continue;
1083*404b540aSrobert vd->e[i].next_regno = vd->e[regno].next_regno;
1084*404b540aSrobert }
1085*404b540aSrobert else if ((next = vd->e[regno].next_regno) != INVALID_REGNUM)
1086*404b540aSrobert {
1087*404b540aSrobert for (i = next; i != INVALID_REGNUM; i = vd->e[i].next_regno)
1088*404b540aSrobert vd->e[i].oldest_regno = next;
1089*404b540aSrobert }
1090*404b540aSrobert
1091*404b540aSrobert vd->e[regno].mode = VOIDmode;
1092*404b540aSrobert vd->e[regno].oldest_regno = regno;
1093*404b540aSrobert vd->e[regno].next_regno = INVALID_REGNUM;
1094*404b540aSrobert
1095*404b540aSrobert #ifdef ENABLE_CHECKING
1096*404b540aSrobert validate_value_data (vd);
1097*404b540aSrobert #endif
1098*404b540aSrobert }
1099*404b540aSrobert
1100*404b540aSrobert /* Kill the value in register REGNO for NREGS, and any other registers
1101*404b540aSrobert whose values overlap. */
1102*404b540aSrobert
1103*404b540aSrobert static void
kill_value_regno(unsigned int regno,unsigned int nregs,struct value_data * vd)1104*404b540aSrobert kill_value_regno (unsigned int regno, unsigned int nregs,
1105*404b540aSrobert struct value_data *vd)
1106*404b540aSrobert {
1107*404b540aSrobert unsigned int j;
1108*404b540aSrobert
1109*404b540aSrobert /* Kill the value we're told to kill. */
1110*404b540aSrobert for (j = 0; j < nregs; ++j)
1111*404b540aSrobert kill_value_one_regno (regno + j, vd);
1112*404b540aSrobert
1113*404b540aSrobert /* Kill everything that overlapped what we're told to kill. */
1114*404b540aSrobert if (regno < vd->max_value_regs)
1115*404b540aSrobert j = 0;
1116*404b540aSrobert else
1117*404b540aSrobert j = regno - vd->max_value_regs;
1118*404b540aSrobert for (; j < regno; ++j)
1119*404b540aSrobert {
1120*404b540aSrobert unsigned int i, n;
1121*404b540aSrobert if (vd->e[j].mode == VOIDmode)
1122*404b540aSrobert continue;
1123*404b540aSrobert n = hard_regno_nregs[j][vd->e[j].mode];
1124*404b540aSrobert if (j + n > regno)
1125*404b540aSrobert for (i = 0; i < n; ++i)
1126*404b540aSrobert kill_value_one_regno (j + i, vd);
1127*404b540aSrobert }
1128*404b540aSrobert }
1129*404b540aSrobert
1130*404b540aSrobert /* Kill X. This is a convenience function wrapping kill_value_regno
1131*404b540aSrobert so that we mind the mode the register is in. */
1132*404b540aSrobert
1133*404b540aSrobert static void
kill_value(rtx x,struct value_data * vd)1134*404b540aSrobert kill_value (rtx x, struct value_data *vd)
1135*404b540aSrobert {
1136*404b540aSrobert rtx orig_rtx = x;
1137*404b540aSrobert
1138*404b540aSrobert if (GET_CODE (x) == SUBREG)
1139*404b540aSrobert {
1140*404b540aSrobert x = simplify_subreg (GET_MODE (x), SUBREG_REG (x),
1141*404b540aSrobert GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
1142*404b540aSrobert if (x == NULL_RTX)
1143*404b540aSrobert x = SUBREG_REG (orig_rtx);
1144*404b540aSrobert }
1145*404b540aSrobert if (REG_P (x))
1146*404b540aSrobert {
1147*404b540aSrobert unsigned int regno = REGNO (x);
1148*404b540aSrobert unsigned int n = hard_regno_nregs[regno][GET_MODE (x)];
1149*404b540aSrobert
1150*404b540aSrobert kill_value_regno (regno, n, vd);
1151*404b540aSrobert }
1152*404b540aSrobert }
1153*404b540aSrobert
1154*404b540aSrobert /* Remember that REGNO is valid in MODE. */
1155*404b540aSrobert
1156*404b540aSrobert static void
set_value_regno(unsigned int regno,enum machine_mode mode,struct value_data * vd)1157*404b540aSrobert set_value_regno (unsigned int regno, enum machine_mode mode,
1158*404b540aSrobert struct value_data *vd)
1159*404b540aSrobert {
1160*404b540aSrobert unsigned int nregs;
1161*404b540aSrobert
1162*404b540aSrobert vd->e[regno].mode = mode;
1163*404b540aSrobert
1164*404b540aSrobert nregs = hard_regno_nregs[regno][mode];
1165*404b540aSrobert if (nregs > vd->max_value_regs)
1166*404b540aSrobert vd->max_value_regs = nregs;
1167*404b540aSrobert }
1168*404b540aSrobert
1169*404b540aSrobert /* Initialize VD such that there are no known relationships between regs. */
1170*404b540aSrobert
1171*404b540aSrobert static void
init_value_data(struct value_data * vd)1172*404b540aSrobert init_value_data (struct value_data *vd)
1173*404b540aSrobert {
1174*404b540aSrobert int i;
1175*404b540aSrobert for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
1176*404b540aSrobert {
1177*404b540aSrobert vd->e[i].mode = VOIDmode;
1178*404b540aSrobert vd->e[i].oldest_regno = i;
1179*404b540aSrobert vd->e[i].next_regno = INVALID_REGNUM;
1180*404b540aSrobert }
1181*404b540aSrobert vd->max_value_regs = 0;
1182*404b540aSrobert }
1183*404b540aSrobert
1184*404b540aSrobert /* Called through note_stores. If X is clobbered, kill its value. */
1185*404b540aSrobert
1186*404b540aSrobert static void
kill_clobbered_value(rtx x,rtx set,void * data)1187*404b540aSrobert kill_clobbered_value (rtx x, rtx set, void *data)
1188*404b540aSrobert {
1189*404b540aSrobert struct value_data *vd = data;
1190*404b540aSrobert if (GET_CODE (set) == CLOBBER)
1191*404b540aSrobert kill_value (x, vd);
1192*404b540aSrobert }
1193*404b540aSrobert
1194*404b540aSrobert /* Called through note_stores. If X is set, not clobbered, kill its
1195*404b540aSrobert current value and install it as the root of its own value list. */
1196*404b540aSrobert
1197*404b540aSrobert static void
kill_set_value(rtx x,rtx set,void * data)1198*404b540aSrobert kill_set_value (rtx x, rtx set, void *data)
1199*404b540aSrobert {
1200*404b540aSrobert struct value_data *vd = data;
1201*404b540aSrobert if (GET_CODE (set) != CLOBBER)
1202*404b540aSrobert {
1203*404b540aSrobert kill_value (x, vd);
1204*404b540aSrobert if (REG_P (x))
1205*404b540aSrobert set_value_regno (REGNO (x), GET_MODE (x), vd);
1206*404b540aSrobert }
1207*404b540aSrobert }
1208*404b540aSrobert
1209*404b540aSrobert /* Called through for_each_rtx. Kill any register used as the base of an
1210*404b540aSrobert auto-increment expression, and install that register as the root of its
1211*404b540aSrobert own value list. */
1212*404b540aSrobert
1213*404b540aSrobert static int
kill_autoinc_value(rtx * px,void * data)1214*404b540aSrobert kill_autoinc_value (rtx *px, void *data)
1215*404b540aSrobert {
1216*404b540aSrobert rtx x = *px;
1217*404b540aSrobert struct value_data *vd = data;
1218*404b540aSrobert
1219*404b540aSrobert if (GET_RTX_CLASS (GET_CODE (x)) == RTX_AUTOINC)
1220*404b540aSrobert {
1221*404b540aSrobert x = XEXP (x, 0);
1222*404b540aSrobert kill_value (x, vd);
1223*404b540aSrobert set_value_regno (REGNO (x), Pmode, vd);
1224*404b540aSrobert return -1;
1225*404b540aSrobert }
1226*404b540aSrobert
1227*404b540aSrobert return 0;
1228*404b540aSrobert }
1229*404b540aSrobert
1230*404b540aSrobert /* Assert that SRC has been copied to DEST. Adjust the data structures
1231*404b540aSrobert to reflect that SRC contains an older copy of the shared value. */
1232*404b540aSrobert
1233*404b540aSrobert static void
copy_value(rtx dest,rtx src,struct value_data * vd)1234*404b540aSrobert copy_value (rtx dest, rtx src, struct value_data *vd)
1235*404b540aSrobert {
1236*404b540aSrobert unsigned int dr = REGNO (dest);
1237*404b540aSrobert unsigned int sr = REGNO (src);
1238*404b540aSrobert unsigned int dn, sn;
1239*404b540aSrobert unsigned int i;
1240*404b540aSrobert
1241*404b540aSrobert /* ??? At present, it's possible to see noop sets. It'd be nice if
1242*404b540aSrobert this were cleaned up beforehand... */
1243*404b540aSrobert if (sr == dr)
1244*404b540aSrobert return;
1245*404b540aSrobert
1246*404b540aSrobert /* Do not propagate copies to the stack pointer, as that can leave
1247*404b540aSrobert memory accesses with no scheduling dependency on the stack update. */
1248*404b540aSrobert if (dr == STACK_POINTER_REGNUM)
1249*404b540aSrobert return;
1250*404b540aSrobert
1251*404b540aSrobert /* Likewise with the frame pointer, if we're using one. */
1252*404b540aSrobert if (frame_pointer_needed && dr == HARD_FRAME_POINTER_REGNUM)
1253*404b540aSrobert return;
1254*404b540aSrobert
1255*404b540aSrobert /* Do not propagate copies to fixed or global registers, patterns
1256*404b540aSrobert can be relying to see particular fixed register or users can
1257*404b540aSrobert expect the chosen global register in asm. */
1258*404b540aSrobert if (fixed_regs[dr] || global_regs[dr])
1259*404b540aSrobert return;
1260*404b540aSrobert
1261*404b540aSrobert /* If SRC and DEST overlap, don't record anything. */
1262*404b540aSrobert dn = hard_regno_nregs[dr][GET_MODE (dest)];
1263*404b540aSrobert sn = hard_regno_nregs[sr][GET_MODE (dest)];
1264*404b540aSrobert if ((dr > sr && dr < sr + sn)
1265*404b540aSrobert || (sr > dr && sr < dr + dn))
1266*404b540aSrobert return;
1267*404b540aSrobert
1268*404b540aSrobert /* If SRC had no assigned mode (i.e. we didn't know it was live)
1269*404b540aSrobert assign it now and assume the value came from an input argument
1270*404b540aSrobert or somesuch. */
1271*404b540aSrobert if (vd->e[sr].mode == VOIDmode)
1272*404b540aSrobert set_value_regno (sr, vd->e[dr].mode, vd);
1273*404b540aSrobert
1274*404b540aSrobert /* If we are narrowing the input to a smaller number of hard regs,
1275*404b540aSrobert and it is in big endian, we are really extracting a high part.
1276*404b540aSrobert Since we generally associate a low part of a value with the value itself,
1277*404b540aSrobert we must not do the same for the high part.
1278*404b540aSrobert Note we can still get low parts for the same mode combination through
1279*404b540aSrobert a two-step copy involving differently sized hard regs.
1280*404b540aSrobert Assume hard regs fr* are 32 bits bits each, while r* are 64 bits each:
1281*404b540aSrobert (set (reg:DI r0) (reg:DI fr0))
1282*404b540aSrobert (set (reg:SI fr2) (reg:SI r0))
1283*404b540aSrobert loads the low part of (reg:DI fr0) - i.e. fr1 - into fr2, while:
1284*404b540aSrobert (set (reg:SI fr2) (reg:SI fr0))
1285*404b540aSrobert loads the high part of (reg:DI fr0) into fr2.
1286*404b540aSrobert
1287*404b540aSrobert We can't properly represent the latter case in our tables, so don't
1288*404b540aSrobert record anything then. */
1289*404b540aSrobert else if (sn < (unsigned int) hard_regno_nregs[sr][vd->e[sr].mode]
1290*404b540aSrobert && (GET_MODE_SIZE (vd->e[sr].mode) > UNITS_PER_WORD
1291*404b540aSrobert ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
1292*404b540aSrobert return;
1293*404b540aSrobert
1294*404b540aSrobert /* If SRC had been assigned a mode narrower than the copy, we can't
1295*404b540aSrobert link DEST into the chain, because not all of the pieces of the
1296*404b540aSrobert copy came from oldest_regno. */
1297*404b540aSrobert else if (sn > (unsigned int) hard_regno_nregs[sr][vd->e[sr].mode])
1298*404b540aSrobert return;
1299*404b540aSrobert
1300*404b540aSrobert /* Link DR at the end of the value chain used by SR. */
1301*404b540aSrobert
1302*404b540aSrobert vd->e[dr].oldest_regno = vd->e[sr].oldest_regno;
1303*404b540aSrobert
1304*404b540aSrobert for (i = sr; vd->e[i].next_regno != INVALID_REGNUM; i = vd->e[i].next_regno)
1305*404b540aSrobert continue;
1306*404b540aSrobert vd->e[i].next_regno = dr;
1307*404b540aSrobert
1308*404b540aSrobert #ifdef ENABLE_CHECKING
1309*404b540aSrobert validate_value_data (vd);
1310*404b540aSrobert #endif
1311*404b540aSrobert }
1312*404b540aSrobert
1313*404b540aSrobert /* Return true if a mode change from ORIG to NEW is allowed for REGNO. */
1314*404b540aSrobert
1315*404b540aSrobert static bool
mode_change_ok(enum machine_mode orig_mode,enum machine_mode new_mode,unsigned int regno ATTRIBUTE_UNUSED)1316*404b540aSrobert mode_change_ok (enum machine_mode orig_mode, enum machine_mode new_mode,
1317*404b540aSrobert unsigned int regno ATTRIBUTE_UNUSED)
1318*404b540aSrobert {
1319*404b540aSrobert if (GET_MODE_SIZE (orig_mode) < GET_MODE_SIZE (new_mode))
1320*404b540aSrobert return false;
1321*404b540aSrobert
1322*404b540aSrobert #ifdef CANNOT_CHANGE_MODE_CLASS
1323*404b540aSrobert return !REG_CANNOT_CHANGE_MODE_P (regno, orig_mode, new_mode);
1324*404b540aSrobert #endif
1325*404b540aSrobert
1326*404b540aSrobert return true;
1327*404b540aSrobert }
1328*404b540aSrobert
1329*404b540aSrobert /* Register REGNO was originally set in ORIG_MODE. It - or a copy of it -
1330*404b540aSrobert was copied in COPY_MODE to COPY_REGNO, and then COPY_REGNO was accessed
1331*404b540aSrobert in NEW_MODE.
1332*404b540aSrobert Return a NEW_MODE rtx for REGNO if that's OK, otherwise return NULL_RTX. */
1333*404b540aSrobert
1334*404b540aSrobert static rtx
maybe_mode_change(enum machine_mode orig_mode,enum machine_mode copy_mode,enum machine_mode new_mode,unsigned int regno,unsigned int copy_regno ATTRIBUTE_UNUSED)1335*404b540aSrobert maybe_mode_change (enum machine_mode orig_mode, enum machine_mode copy_mode,
1336*404b540aSrobert enum machine_mode new_mode, unsigned int regno,
1337*404b540aSrobert unsigned int copy_regno ATTRIBUTE_UNUSED)
1338*404b540aSrobert {
1339*404b540aSrobert if (orig_mode == new_mode)
1340*404b540aSrobert return gen_rtx_raw_REG (new_mode, regno);
1341*404b540aSrobert else if (mode_change_ok (orig_mode, new_mode, regno))
1342*404b540aSrobert {
1343*404b540aSrobert int copy_nregs = hard_regno_nregs[copy_regno][copy_mode];
1344*404b540aSrobert int use_nregs = hard_regno_nregs[copy_regno][new_mode];
1345*404b540aSrobert int copy_offset
1346*404b540aSrobert = GET_MODE_SIZE (copy_mode) / copy_nregs * (copy_nregs - use_nregs);
1347*404b540aSrobert int offset
1348*404b540aSrobert = GET_MODE_SIZE (orig_mode) - GET_MODE_SIZE (new_mode) - copy_offset;
1349*404b540aSrobert int byteoffset = offset % UNITS_PER_WORD;
1350*404b540aSrobert int wordoffset = offset - byteoffset;
1351*404b540aSrobert
1352*404b540aSrobert offset = ((WORDS_BIG_ENDIAN ? wordoffset : 0)
1353*404b540aSrobert + (BYTES_BIG_ENDIAN ? byteoffset : 0));
1354*404b540aSrobert return gen_rtx_raw_REG (new_mode,
1355*404b540aSrobert regno + subreg_regno_offset (regno, orig_mode,
1356*404b540aSrobert offset,
1357*404b540aSrobert new_mode));
1358*404b540aSrobert }
1359*404b540aSrobert return NULL_RTX;
1360*404b540aSrobert }
1361*404b540aSrobert
1362*404b540aSrobert /* Find the oldest copy of the value contained in REGNO that is in
1363*404b540aSrobert register class CL and has mode MODE. If found, return an rtx
1364*404b540aSrobert of that oldest register, otherwise return NULL. */
1365*404b540aSrobert
1366*404b540aSrobert static rtx
find_oldest_value_reg(enum reg_class cl,rtx reg,struct value_data * vd)1367*404b540aSrobert find_oldest_value_reg (enum reg_class cl, rtx reg, struct value_data *vd)
1368*404b540aSrobert {
1369*404b540aSrobert unsigned int regno = REGNO (reg);
1370*404b540aSrobert enum machine_mode mode = GET_MODE (reg);
1371*404b540aSrobert unsigned int i;
1372*404b540aSrobert
1373*404b540aSrobert /* If we are accessing REG in some mode other that what we set it in,
1374*404b540aSrobert make sure that the replacement is valid. In particular, consider
1375*404b540aSrobert (set (reg:DI r11) (...))
1376*404b540aSrobert (set (reg:SI r9) (reg:SI r11))
1377*404b540aSrobert (set (reg:SI r10) (...))
1378*404b540aSrobert (set (...) (reg:DI r9))
1379*404b540aSrobert Replacing r9 with r11 is invalid. */
1380*404b540aSrobert if (mode != vd->e[regno].mode)
1381*404b540aSrobert {
1382*404b540aSrobert if (hard_regno_nregs[regno][mode]
1383*404b540aSrobert > hard_regno_nregs[regno][vd->e[regno].mode])
1384*404b540aSrobert return NULL_RTX;
1385*404b540aSrobert }
1386*404b540aSrobert
1387*404b540aSrobert for (i = vd->e[regno].oldest_regno; i != regno; i = vd->e[i].next_regno)
1388*404b540aSrobert {
1389*404b540aSrobert enum machine_mode oldmode = vd->e[i].mode;
1390*404b540aSrobert rtx new;
1391*404b540aSrobert unsigned int last;
1392*404b540aSrobert
1393*404b540aSrobert for (last = i; last < i + hard_regno_nregs[i][mode]; last++)
1394*404b540aSrobert if (!TEST_HARD_REG_BIT (reg_class_contents[cl], last))
1395*404b540aSrobert return NULL_RTX;
1396*404b540aSrobert
1397*404b540aSrobert new = maybe_mode_change (oldmode, vd->e[regno].mode, mode, i, regno);
1398*404b540aSrobert if (new)
1399*404b540aSrobert {
1400*404b540aSrobert ORIGINAL_REGNO (new) = ORIGINAL_REGNO (reg);
1401*404b540aSrobert REG_ATTRS (new) = REG_ATTRS (reg);
1402*404b540aSrobert return new;
1403*404b540aSrobert }
1404*404b540aSrobert }
1405*404b540aSrobert
1406*404b540aSrobert return NULL_RTX;
1407*404b540aSrobert }
1408*404b540aSrobert
1409*404b540aSrobert /* If possible, replace the register at *LOC with the oldest register
1410*404b540aSrobert in register class CL. Return true if successfully replaced. */
1411*404b540aSrobert
1412*404b540aSrobert static bool
replace_oldest_value_reg(rtx * loc,enum reg_class cl,rtx insn,struct value_data * vd)1413*404b540aSrobert replace_oldest_value_reg (rtx *loc, enum reg_class cl, rtx insn,
1414*404b540aSrobert struct value_data *vd)
1415*404b540aSrobert {
1416*404b540aSrobert rtx new = find_oldest_value_reg (cl, *loc, vd);
1417*404b540aSrobert if (new)
1418*404b540aSrobert {
1419*404b540aSrobert if (dump_file)
1420*404b540aSrobert fprintf (dump_file, "insn %u: replaced reg %u with %u\n",
1421*404b540aSrobert INSN_UID (insn), REGNO (*loc), REGNO (new));
1422*404b540aSrobert
1423*404b540aSrobert validate_change (insn, loc, new, 1);
1424*404b540aSrobert return true;
1425*404b540aSrobert }
1426*404b540aSrobert return false;
1427*404b540aSrobert }
1428*404b540aSrobert
1429*404b540aSrobert /* Similar to replace_oldest_value_reg, but *LOC contains an address.
1430*404b540aSrobert Adapted from find_reloads_address_1. CL is INDEX_REG_CLASS or
1431*404b540aSrobert BASE_REG_CLASS depending on how the register is being considered. */
1432*404b540aSrobert
1433*404b540aSrobert static bool
replace_oldest_value_addr(rtx * loc,enum reg_class cl,enum machine_mode mode,rtx insn,struct value_data * vd)1434*404b540aSrobert replace_oldest_value_addr (rtx *loc, enum reg_class cl,
1435*404b540aSrobert enum machine_mode mode, rtx insn,
1436*404b540aSrobert struct value_data *vd)
1437*404b540aSrobert {
1438*404b540aSrobert rtx x = *loc;
1439*404b540aSrobert RTX_CODE code = GET_CODE (x);
1440*404b540aSrobert const char *fmt;
1441*404b540aSrobert int i, j;
1442*404b540aSrobert bool changed = false;
1443*404b540aSrobert
1444*404b540aSrobert switch (code)
1445*404b540aSrobert {
1446*404b540aSrobert case PLUS:
1447*404b540aSrobert {
1448*404b540aSrobert rtx orig_op0 = XEXP (x, 0);
1449*404b540aSrobert rtx orig_op1 = XEXP (x, 1);
1450*404b540aSrobert RTX_CODE code0 = GET_CODE (orig_op0);
1451*404b540aSrobert RTX_CODE code1 = GET_CODE (orig_op1);
1452*404b540aSrobert rtx op0 = orig_op0;
1453*404b540aSrobert rtx op1 = orig_op1;
1454*404b540aSrobert rtx *locI = NULL;
1455*404b540aSrobert rtx *locB = NULL;
1456*404b540aSrobert enum rtx_code index_code = SCRATCH;
1457*404b540aSrobert
1458*404b540aSrobert if (GET_CODE (op0) == SUBREG)
1459*404b540aSrobert {
1460*404b540aSrobert op0 = SUBREG_REG (op0);
1461*404b540aSrobert code0 = GET_CODE (op0);
1462*404b540aSrobert }
1463*404b540aSrobert
1464*404b540aSrobert if (GET_CODE (op1) == SUBREG)
1465*404b540aSrobert {
1466*404b540aSrobert op1 = SUBREG_REG (op1);
1467*404b540aSrobert code1 = GET_CODE (op1);
1468*404b540aSrobert }
1469*404b540aSrobert
1470*404b540aSrobert if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
1471*404b540aSrobert || code0 == ZERO_EXTEND || code1 == MEM)
1472*404b540aSrobert {
1473*404b540aSrobert locI = &XEXP (x, 0);
1474*404b540aSrobert locB = &XEXP (x, 1);
1475*404b540aSrobert index_code = GET_CODE (*locI);
1476*404b540aSrobert }
1477*404b540aSrobert else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
1478*404b540aSrobert || code1 == ZERO_EXTEND || code0 == MEM)
1479*404b540aSrobert {
1480*404b540aSrobert locI = &XEXP (x, 1);
1481*404b540aSrobert locB = &XEXP (x, 0);
1482*404b540aSrobert index_code = GET_CODE (*locI);
1483*404b540aSrobert }
1484*404b540aSrobert else if (code0 == CONST_INT || code0 == CONST
1485*404b540aSrobert || code0 == SYMBOL_REF || code0 == LABEL_REF)
1486*404b540aSrobert {
1487*404b540aSrobert locB = &XEXP (x, 1);
1488*404b540aSrobert index_code = GET_CODE (XEXP (x, 0));
1489*404b540aSrobert }
1490*404b540aSrobert else if (code1 == CONST_INT || code1 == CONST
1491*404b540aSrobert || code1 == SYMBOL_REF || code1 == LABEL_REF)
1492*404b540aSrobert {
1493*404b540aSrobert locB = &XEXP (x, 0);
1494*404b540aSrobert index_code = GET_CODE (XEXP (x, 1));
1495*404b540aSrobert }
1496*404b540aSrobert else if (code0 == REG && code1 == REG)
1497*404b540aSrobert {
1498*404b540aSrobert int index_op;
1499*404b540aSrobert unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
1500*404b540aSrobert
1501*404b540aSrobert if (REGNO_OK_FOR_INDEX_P (regno0)
1502*404b540aSrobert && regno_ok_for_base_p (regno1, mode, PLUS, REG))
1503*404b540aSrobert index_op = 0;
1504*404b540aSrobert else if (REGNO_OK_FOR_INDEX_P (regno1)
1505*404b540aSrobert && regno_ok_for_base_p (regno0, mode, PLUS, REG))
1506*404b540aSrobert index_op = 1;
1507*404b540aSrobert else if (regno_ok_for_base_p (regno1, mode, PLUS, REG))
1508*404b540aSrobert index_op = 0;
1509*404b540aSrobert else if (regno_ok_for_base_p (regno0, mode, PLUS, REG))
1510*404b540aSrobert index_op = 1;
1511*404b540aSrobert else if (REGNO_OK_FOR_INDEX_P (regno1))
1512*404b540aSrobert index_op = 1;
1513*404b540aSrobert else
1514*404b540aSrobert index_op = 0;
1515*404b540aSrobert
1516*404b540aSrobert locI = &XEXP (x, index_op);
1517*404b540aSrobert locB = &XEXP (x, !index_op);
1518*404b540aSrobert index_code = GET_CODE (*locI);
1519*404b540aSrobert }
1520*404b540aSrobert else if (code0 == REG)
1521*404b540aSrobert {
1522*404b540aSrobert locI = &XEXP (x, 0);
1523*404b540aSrobert locB = &XEXP (x, 1);
1524*404b540aSrobert index_code = GET_CODE (*locI);
1525*404b540aSrobert }
1526*404b540aSrobert else if (code1 == REG)
1527*404b540aSrobert {
1528*404b540aSrobert locI = &XEXP (x, 1);
1529*404b540aSrobert locB = &XEXP (x, 0);
1530*404b540aSrobert index_code = GET_CODE (*locI);
1531*404b540aSrobert }
1532*404b540aSrobert
1533*404b540aSrobert if (locI)
1534*404b540aSrobert changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, mode,
1535*404b540aSrobert insn, vd);
1536*404b540aSrobert if (locB)
1537*404b540aSrobert changed |= replace_oldest_value_addr (locB,
1538*404b540aSrobert base_reg_class (mode, PLUS,
1539*404b540aSrobert index_code),
1540*404b540aSrobert mode, insn, vd);
1541*404b540aSrobert return changed;
1542*404b540aSrobert }
1543*404b540aSrobert
1544*404b540aSrobert case POST_INC:
1545*404b540aSrobert case POST_DEC:
1546*404b540aSrobert case POST_MODIFY:
1547*404b540aSrobert case PRE_INC:
1548*404b540aSrobert case PRE_DEC:
1549*404b540aSrobert case PRE_MODIFY:
1550*404b540aSrobert return false;
1551*404b540aSrobert
1552*404b540aSrobert case MEM:
1553*404b540aSrobert return replace_oldest_value_mem (x, insn, vd);
1554*404b540aSrobert
1555*404b540aSrobert case REG:
1556*404b540aSrobert return replace_oldest_value_reg (loc, cl, insn, vd);
1557*404b540aSrobert
1558*404b540aSrobert default:
1559*404b540aSrobert break;
1560*404b540aSrobert }
1561*404b540aSrobert
1562*404b540aSrobert fmt = GET_RTX_FORMAT (code);
1563*404b540aSrobert for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1564*404b540aSrobert {
1565*404b540aSrobert if (fmt[i] == 'e')
1566*404b540aSrobert changed |= replace_oldest_value_addr (&XEXP (x, i), cl, mode,
1567*404b540aSrobert insn, vd);
1568*404b540aSrobert else if (fmt[i] == 'E')
1569*404b540aSrobert for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1570*404b540aSrobert changed |= replace_oldest_value_addr (&XVECEXP (x, i, j), cl,
1571*404b540aSrobert mode, insn, vd);
1572*404b540aSrobert }
1573*404b540aSrobert
1574*404b540aSrobert return changed;
1575*404b540aSrobert }
1576*404b540aSrobert
1577*404b540aSrobert /* Similar to replace_oldest_value_reg, but X contains a memory. */
1578*404b540aSrobert
1579*404b540aSrobert static bool
replace_oldest_value_mem(rtx x,rtx insn,struct value_data * vd)1580*404b540aSrobert replace_oldest_value_mem (rtx x, rtx insn, struct value_data *vd)
1581*404b540aSrobert {
1582*404b540aSrobert return replace_oldest_value_addr (&XEXP (x, 0),
1583*404b540aSrobert base_reg_class (GET_MODE (x), MEM,
1584*404b540aSrobert SCRATCH),
1585*404b540aSrobert GET_MODE (x), insn, vd);
1586*404b540aSrobert }
1587*404b540aSrobert
1588*404b540aSrobert /* Perform the forward copy propagation on basic block BB. */
1589*404b540aSrobert
1590*404b540aSrobert static bool
copyprop_hardreg_forward_1(basic_block bb,struct value_data * vd)1591*404b540aSrobert copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
1592*404b540aSrobert {
1593*404b540aSrobert bool changed = false;
1594*404b540aSrobert rtx insn;
1595*404b540aSrobert
1596*404b540aSrobert for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
1597*404b540aSrobert {
1598*404b540aSrobert int n_ops, i, alt, predicated;
1599*404b540aSrobert bool is_asm, any_replacements;
1600*404b540aSrobert rtx set;
1601*404b540aSrobert bool replaced[MAX_RECOG_OPERANDS];
1602*404b540aSrobert
1603*404b540aSrobert if (! INSN_P (insn))
1604*404b540aSrobert {
1605*404b540aSrobert if (insn == BB_END (bb))
1606*404b540aSrobert break;
1607*404b540aSrobert else
1608*404b540aSrobert continue;
1609*404b540aSrobert }
1610*404b540aSrobert
1611*404b540aSrobert set = single_set (insn);
1612*404b540aSrobert extract_insn (insn);
1613*404b540aSrobert if (! constrain_operands (1))
1614*404b540aSrobert fatal_insn_not_found (insn);
1615*404b540aSrobert preprocess_constraints ();
1616*404b540aSrobert alt = which_alternative;
1617*404b540aSrobert n_ops = recog_data.n_operands;
1618*404b540aSrobert is_asm = asm_noperands (PATTERN (insn)) >= 0;
1619*404b540aSrobert
1620*404b540aSrobert /* Simplify the code below by rewriting things to reflect
1621*404b540aSrobert matching constraints. Also promote OP_OUT to OP_INOUT
1622*404b540aSrobert in predicated instructions. */
1623*404b540aSrobert
1624*404b540aSrobert predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
1625*404b540aSrobert for (i = 0; i < n_ops; ++i)
1626*404b540aSrobert {
1627*404b540aSrobert int matches = recog_op_alt[i][alt].matches;
1628*404b540aSrobert if (matches >= 0)
1629*404b540aSrobert recog_op_alt[i][alt].cl = recog_op_alt[matches][alt].cl;
1630*404b540aSrobert if (matches >= 0 || recog_op_alt[i][alt].matched >= 0
1631*404b540aSrobert || (predicated && recog_data.operand_type[i] == OP_OUT))
1632*404b540aSrobert recog_data.operand_type[i] = OP_INOUT;
1633*404b540aSrobert }
1634*404b540aSrobert
1635*404b540aSrobert /* For each earlyclobber operand, zap the value data. */
1636*404b540aSrobert for (i = 0; i < n_ops; i++)
1637*404b540aSrobert if (recog_op_alt[i][alt].earlyclobber)
1638*404b540aSrobert kill_value (recog_data.operand[i], vd);
1639*404b540aSrobert
1640*404b540aSrobert /* Within asms, a clobber cannot overlap inputs or outputs.
1641*404b540aSrobert I wouldn't think this were true for regular insns, but
1642*404b540aSrobert scan_rtx treats them like that... */
1643*404b540aSrobert note_stores (PATTERN (insn), kill_clobbered_value, vd);
1644*404b540aSrobert
1645*404b540aSrobert /* Kill all auto-incremented values. */
1646*404b540aSrobert /* ??? REG_INC is useless, since stack pushes aren't done that way. */
1647*404b540aSrobert for_each_rtx (&PATTERN (insn), kill_autoinc_value, vd);
1648*404b540aSrobert
1649*404b540aSrobert /* Kill all early-clobbered operands. */
1650*404b540aSrobert for (i = 0; i < n_ops; i++)
1651*404b540aSrobert if (recog_op_alt[i][alt].earlyclobber)
1652*404b540aSrobert kill_value (recog_data.operand[i], vd);
1653*404b540aSrobert
1654*404b540aSrobert /* Special-case plain move instructions, since we may well
1655*404b540aSrobert be able to do the move from a different register class. */
1656*404b540aSrobert if (set && REG_P (SET_SRC (set)))
1657*404b540aSrobert {
1658*404b540aSrobert rtx src = SET_SRC (set);
1659*404b540aSrobert unsigned int regno = REGNO (src);
1660*404b540aSrobert enum machine_mode mode = GET_MODE (src);
1661*404b540aSrobert unsigned int i;
1662*404b540aSrobert rtx new;
1663*404b540aSrobert
1664*404b540aSrobert /* If we are accessing SRC in some mode other that what we
1665*404b540aSrobert set it in, make sure that the replacement is valid. */
1666*404b540aSrobert if (mode != vd->e[regno].mode)
1667*404b540aSrobert {
1668*404b540aSrobert if (hard_regno_nregs[regno][mode]
1669*404b540aSrobert > hard_regno_nregs[regno][vd->e[regno].mode])
1670*404b540aSrobert goto no_move_special_case;
1671*404b540aSrobert }
1672*404b540aSrobert
1673*404b540aSrobert /* If the destination is also a register, try to find a source
1674*404b540aSrobert register in the same class. */
1675*404b540aSrobert if (REG_P (SET_DEST (set)))
1676*404b540aSrobert {
1677*404b540aSrobert new = find_oldest_value_reg (REGNO_REG_CLASS (regno), src, vd);
1678*404b540aSrobert if (new && validate_change (insn, &SET_SRC (set), new, 0))
1679*404b540aSrobert {
1680*404b540aSrobert if (dump_file)
1681*404b540aSrobert fprintf (dump_file,
1682*404b540aSrobert "insn %u: replaced reg %u with %u\n",
1683*404b540aSrobert INSN_UID (insn), regno, REGNO (new));
1684*404b540aSrobert changed = true;
1685*404b540aSrobert goto did_replacement;
1686*404b540aSrobert }
1687*404b540aSrobert }
1688*404b540aSrobert
1689*404b540aSrobert /* Otherwise, try all valid registers and see if its valid. */
1690*404b540aSrobert for (i = vd->e[regno].oldest_regno; i != regno;
1691*404b540aSrobert i = vd->e[i].next_regno)
1692*404b540aSrobert {
1693*404b540aSrobert new = maybe_mode_change (vd->e[i].mode, vd->e[regno].mode,
1694*404b540aSrobert mode, i, regno);
1695*404b540aSrobert if (new != NULL_RTX)
1696*404b540aSrobert {
1697*404b540aSrobert if (validate_change (insn, &SET_SRC (set), new, 0))
1698*404b540aSrobert {
1699*404b540aSrobert ORIGINAL_REGNO (new) = ORIGINAL_REGNO (src);
1700*404b540aSrobert REG_ATTRS (new) = REG_ATTRS (src);
1701*404b540aSrobert if (dump_file)
1702*404b540aSrobert fprintf (dump_file,
1703*404b540aSrobert "insn %u: replaced reg %u with %u\n",
1704*404b540aSrobert INSN_UID (insn), regno, REGNO (new));
1705*404b540aSrobert changed = true;
1706*404b540aSrobert goto did_replacement;
1707*404b540aSrobert }
1708*404b540aSrobert }
1709*404b540aSrobert }
1710*404b540aSrobert }
1711*404b540aSrobert no_move_special_case:
1712*404b540aSrobert
1713*404b540aSrobert any_replacements = false;
1714*404b540aSrobert
1715*404b540aSrobert /* For each input operand, replace a hard register with the
1716*404b540aSrobert eldest live copy that's in an appropriate register class. */
1717*404b540aSrobert for (i = 0; i < n_ops; i++)
1718*404b540aSrobert {
1719*404b540aSrobert replaced[i] = false;
1720*404b540aSrobert
1721*404b540aSrobert /* Don't scan match_operand here, since we've no reg class
1722*404b540aSrobert information to pass down. Any operands that we could
1723*404b540aSrobert substitute in will be represented elsewhere. */
1724*404b540aSrobert if (recog_data.constraints[i][0] == '\0')
1725*404b540aSrobert continue;
1726*404b540aSrobert
1727*404b540aSrobert /* Don't replace in asms intentionally referencing hard regs. */
1728*404b540aSrobert if (is_asm && REG_P (recog_data.operand[i])
1729*404b540aSrobert && (REGNO (recog_data.operand[i])
1730*404b540aSrobert == ORIGINAL_REGNO (recog_data.operand[i])))
1731*404b540aSrobert continue;
1732*404b540aSrobert
1733*404b540aSrobert if (recog_data.operand_type[i] == OP_IN)
1734*404b540aSrobert {
1735*404b540aSrobert if (recog_op_alt[i][alt].is_address)
1736*404b540aSrobert replaced[i]
1737*404b540aSrobert = replace_oldest_value_addr (recog_data.operand_loc[i],
1738*404b540aSrobert recog_op_alt[i][alt].cl,
1739*404b540aSrobert VOIDmode, insn, vd);
1740*404b540aSrobert else if (REG_P (recog_data.operand[i]))
1741*404b540aSrobert replaced[i]
1742*404b540aSrobert = replace_oldest_value_reg (recog_data.operand_loc[i],
1743*404b540aSrobert recog_op_alt[i][alt].cl,
1744*404b540aSrobert insn, vd);
1745*404b540aSrobert else if (MEM_P (recog_data.operand[i]))
1746*404b540aSrobert replaced[i] = replace_oldest_value_mem (recog_data.operand[i],
1747*404b540aSrobert insn, vd);
1748*404b540aSrobert }
1749*404b540aSrobert else if (MEM_P (recog_data.operand[i]))
1750*404b540aSrobert replaced[i] = replace_oldest_value_mem (recog_data.operand[i],
1751*404b540aSrobert insn, vd);
1752*404b540aSrobert
1753*404b540aSrobert /* If we performed any replacement, update match_dups. */
1754*404b540aSrobert if (replaced[i])
1755*404b540aSrobert {
1756*404b540aSrobert int j;
1757*404b540aSrobert rtx new;
1758*404b540aSrobert
1759*404b540aSrobert new = *recog_data.operand_loc[i];
1760*404b540aSrobert recog_data.operand[i] = new;
1761*404b540aSrobert for (j = 0; j < recog_data.n_dups; j++)
1762*404b540aSrobert if (recog_data.dup_num[j] == i)
1763*404b540aSrobert validate_change (insn, recog_data.dup_loc[j], new, 1);
1764*404b540aSrobert
1765*404b540aSrobert any_replacements = true;
1766*404b540aSrobert }
1767*404b540aSrobert }
1768*404b540aSrobert
1769*404b540aSrobert if (any_replacements)
1770*404b540aSrobert {
1771*404b540aSrobert if (! apply_change_group ())
1772*404b540aSrobert {
1773*404b540aSrobert for (i = 0; i < n_ops; i++)
1774*404b540aSrobert if (replaced[i])
1775*404b540aSrobert {
1776*404b540aSrobert rtx old = *recog_data.operand_loc[i];
1777*404b540aSrobert recog_data.operand[i] = old;
1778*404b540aSrobert }
1779*404b540aSrobert
1780*404b540aSrobert if (dump_file)
1781*404b540aSrobert fprintf (dump_file,
1782*404b540aSrobert "insn %u: reg replacements not verified\n",
1783*404b540aSrobert INSN_UID (insn));
1784*404b540aSrobert }
1785*404b540aSrobert else
1786*404b540aSrobert changed = true;
1787*404b540aSrobert }
1788*404b540aSrobert
1789*404b540aSrobert did_replacement:
1790*404b540aSrobert /* Clobber call-clobbered registers. */
1791*404b540aSrobert if (CALL_P (insn))
1792*404b540aSrobert for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1793*404b540aSrobert if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
1794*404b540aSrobert kill_value_regno (i, 1, vd);
1795*404b540aSrobert
1796*404b540aSrobert /* Notice stores. */
1797*404b540aSrobert note_stores (PATTERN (insn), kill_set_value, vd);
1798*404b540aSrobert
1799*404b540aSrobert /* Notice copies. */
1800*404b540aSrobert if (set && REG_P (SET_DEST (set)) && REG_P (SET_SRC (set)))
1801*404b540aSrobert copy_value (SET_DEST (set), SET_SRC (set), vd);
1802*404b540aSrobert
1803*404b540aSrobert if (insn == BB_END (bb))
1804*404b540aSrobert break;
1805*404b540aSrobert }
1806*404b540aSrobert
1807*404b540aSrobert return changed;
1808*404b540aSrobert }
1809*404b540aSrobert
1810*404b540aSrobert /* Main entry point for the forward copy propagation optimization. */
1811*404b540aSrobert
1812*404b540aSrobert static void
copyprop_hardreg_forward(void)1813*404b540aSrobert copyprop_hardreg_forward (void)
1814*404b540aSrobert {
1815*404b540aSrobert struct value_data *all_vd;
1816*404b540aSrobert bool need_refresh;
1817*404b540aSrobert basic_block bb;
1818*404b540aSrobert sbitmap visited;
1819*404b540aSrobert
1820*404b540aSrobert need_refresh = false;
1821*404b540aSrobert
1822*404b540aSrobert all_vd = XNEWVEC (struct value_data, last_basic_block);
1823*404b540aSrobert
1824*404b540aSrobert visited = sbitmap_alloc (last_basic_block);
1825*404b540aSrobert sbitmap_zero (visited);
1826*404b540aSrobert
1827*404b540aSrobert FOR_EACH_BB (bb)
1828*404b540aSrobert {
1829*404b540aSrobert SET_BIT (visited, bb->index);
1830*404b540aSrobert
1831*404b540aSrobert /* If a block has a single predecessor, that we've already
1832*404b540aSrobert processed, begin with the value data that was live at
1833*404b540aSrobert the end of the predecessor block. */
1834*404b540aSrobert /* ??? Ought to use more intelligent queuing of blocks. */
1835*404b540aSrobert if (single_pred_p (bb)
1836*404b540aSrobert && TEST_BIT (visited, single_pred (bb)->index)
1837*404b540aSrobert && ! (single_pred_edge (bb)->flags & (EDGE_ABNORMAL_CALL | EDGE_EH)))
1838*404b540aSrobert all_vd[bb->index] = all_vd[single_pred (bb)->index];
1839*404b540aSrobert else
1840*404b540aSrobert init_value_data (all_vd + bb->index);
1841*404b540aSrobert
1842*404b540aSrobert if (copyprop_hardreg_forward_1 (bb, all_vd + bb->index))
1843*404b540aSrobert need_refresh = true;
1844*404b540aSrobert }
1845*404b540aSrobert
1846*404b540aSrobert sbitmap_free (visited);
1847*404b540aSrobert
1848*404b540aSrobert if (need_refresh)
1849*404b540aSrobert {
1850*404b540aSrobert if (dump_file)
1851*404b540aSrobert fputs ("\n\n", dump_file);
1852*404b540aSrobert
1853*404b540aSrobert /* ??? Irritatingly, delete_noop_moves does not take a set of blocks
1854*404b540aSrobert to scan, so we have to do a life update with no initial set of
1855*404b540aSrobert blocks Just In Case. */
1856*404b540aSrobert delete_noop_moves ();
1857*404b540aSrobert update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
1858*404b540aSrobert PROP_DEATH_NOTES
1859*404b540aSrobert | PROP_SCAN_DEAD_CODE
1860*404b540aSrobert | PROP_KILL_DEAD_CODE);
1861*404b540aSrobert }
1862*404b540aSrobert
1863*404b540aSrobert free (all_vd);
1864*404b540aSrobert }
1865*404b540aSrobert
1866*404b540aSrobert /* Dump the value chain data to stderr. */
1867*404b540aSrobert
1868*404b540aSrobert void
debug_value_data(struct value_data * vd)1869*404b540aSrobert debug_value_data (struct value_data *vd)
1870*404b540aSrobert {
1871*404b540aSrobert HARD_REG_SET set;
1872*404b540aSrobert unsigned int i, j;
1873*404b540aSrobert
1874*404b540aSrobert CLEAR_HARD_REG_SET (set);
1875*404b540aSrobert
1876*404b540aSrobert for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
1877*404b540aSrobert if (vd->e[i].oldest_regno == i)
1878*404b540aSrobert {
1879*404b540aSrobert if (vd->e[i].mode == VOIDmode)
1880*404b540aSrobert {
1881*404b540aSrobert if (vd->e[i].next_regno != INVALID_REGNUM)
1882*404b540aSrobert fprintf (stderr, "[%u] Bad next_regno for empty chain (%u)\n",
1883*404b540aSrobert i, vd->e[i].next_regno);
1884*404b540aSrobert continue;
1885*404b540aSrobert }
1886*404b540aSrobert
1887*404b540aSrobert SET_HARD_REG_BIT (set, i);
1888*404b540aSrobert fprintf (stderr, "[%u %s] ", i, GET_MODE_NAME (vd->e[i].mode));
1889*404b540aSrobert
1890*404b540aSrobert for (j = vd->e[i].next_regno;
1891*404b540aSrobert j != INVALID_REGNUM;
1892*404b540aSrobert j = vd->e[j].next_regno)
1893*404b540aSrobert {
1894*404b540aSrobert if (TEST_HARD_REG_BIT (set, j))
1895*404b540aSrobert {
1896*404b540aSrobert fprintf (stderr, "[%u] Loop in regno chain\n", j);
1897*404b540aSrobert return;
1898*404b540aSrobert }
1899*404b540aSrobert
1900*404b540aSrobert if (vd->e[j].oldest_regno != i)
1901*404b540aSrobert {
1902*404b540aSrobert fprintf (stderr, "[%u] Bad oldest_regno (%u)\n",
1903*404b540aSrobert j, vd->e[j].oldest_regno);
1904*404b540aSrobert return;
1905*404b540aSrobert }
1906*404b540aSrobert SET_HARD_REG_BIT (set, j);
1907*404b540aSrobert fprintf (stderr, "[%u %s] ", j, GET_MODE_NAME (vd->e[j].mode));
1908*404b540aSrobert }
1909*404b540aSrobert fputc ('\n', stderr);
1910*404b540aSrobert }
1911*404b540aSrobert
1912*404b540aSrobert for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
1913*404b540aSrobert if (! TEST_HARD_REG_BIT (set, i)
1914*404b540aSrobert && (vd->e[i].mode != VOIDmode
1915*404b540aSrobert || vd->e[i].oldest_regno != i
1916*404b540aSrobert || vd->e[i].next_regno != INVALID_REGNUM))
1917*404b540aSrobert fprintf (stderr, "[%u] Non-empty reg in chain (%s %u %i)\n",
1918*404b540aSrobert i, GET_MODE_NAME (vd->e[i].mode), vd->e[i].oldest_regno,
1919*404b540aSrobert vd->e[i].next_regno);
1920*404b540aSrobert }
1921*404b540aSrobert
1922*404b540aSrobert #ifdef ENABLE_CHECKING
1923*404b540aSrobert static void
validate_value_data(struct value_data * vd)1924*404b540aSrobert validate_value_data (struct value_data *vd)
1925*404b540aSrobert {
1926*404b540aSrobert HARD_REG_SET set;
1927*404b540aSrobert unsigned int i, j;
1928*404b540aSrobert
1929*404b540aSrobert CLEAR_HARD_REG_SET (set);
1930*404b540aSrobert
1931*404b540aSrobert for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
1932*404b540aSrobert if (vd->e[i].oldest_regno == i)
1933*404b540aSrobert {
1934*404b540aSrobert if (vd->e[i].mode == VOIDmode)
1935*404b540aSrobert {
1936*404b540aSrobert if (vd->e[i].next_regno != INVALID_REGNUM)
1937*404b540aSrobert internal_error ("validate_value_data: [%u] Bad next_regno for empty chain (%u)",
1938*404b540aSrobert i, vd->e[i].next_regno);
1939*404b540aSrobert continue;
1940*404b540aSrobert }
1941*404b540aSrobert
1942*404b540aSrobert SET_HARD_REG_BIT (set, i);
1943*404b540aSrobert
1944*404b540aSrobert for (j = vd->e[i].next_regno;
1945*404b540aSrobert j != INVALID_REGNUM;
1946*404b540aSrobert j = vd->e[j].next_regno)
1947*404b540aSrobert {
1948*404b540aSrobert if (TEST_HARD_REG_BIT (set, j))
1949*404b540aSrobert internal_error ("validate_value_data: Loop in regno chain (%u)",
1950*404b540aSrobert j);
1951*404b540aSrobert if (vd->e[j].oldest_regno != i)
1952*404b540aSrobert internal_error ("validate_value_data: [%u] Bad oldest_regno (%u)",
1953*404b540aSrobert j, vd->e[j].oldest_regno);
1954*404b540aSrobert
1955*404b540aSrobert SET_HARD_REG_BIT (set, j);
1956*404b540aSrobert }
1957*404b540aSrobert }
1958*404b540aSrobert
1959*404b540aSrobert for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
1960*404b540aSrobert if (! TEST_HARD_REG_BIT (set, i)
1961*404b540aSrobert && (vd->e[i].mode != VOIDmode
1962*404b540aSrobert || vd->e[i].oldest_regno != i
1963*404b540aSrobert || vd->e[i].next_regno != INVALID_REGNUM))
1964*404b540aSrobert internal_error ("validate_value_data: [%u] Non-empty reg in chain (%s %u %i)",
1965*404b540aSrobert i, GET_MODE_NAME (vd->e[i].mode), vd->e[i].oldest_regno,
1966*404b540aSrobert vd->e[i].next_regno);
1967*404b540aSrobert }
1968*404b540aSrobert #endif
1969*404b540aSrobert
1970*404b540aSrobert static bool
gate_handle_regrename(void)1971*404b540aSrobert gate_handle_regrename (void)
1972*404b540aSrobert {
1973*404b540aSrobert return (optimize > 0 && (flag_rename_registers || flag_cprop_registers));
1974*404b540aSrobert }
1975*404b540aSrobert
1976*404b540aSrobert
1977*404b540aSrobert /* Run the regrename and cprop passes. */
1978*404b540aSrobert static unsigned int
rest_of_handle_regrename(void)1979*404b540aSrobert rest_of_handle_regrename (void)
1980*404b540aSrobert {
1981*404b540aSrobert if (flag_rename_registers)
1982*404b540aSrobert regrename_optimize ();
1983*404b540aSrobert if (flag_cprop_registers)
1984*404b540aSrobert copyprop_hardreg_forward ();
1985*404b540aSrobert return 0;
1986*404b540aSrobert }
1987*404b540aSrobert
1988*404b540aSrobert struct tree_opt_pass pass_regrename =
1989*404b540aSrobert {
1990*404b540aSrobert "rnreg", /* name */
1991*404b540aSrobert gate_handle_regrename, /* gate */
1992*404b540aSrobert rest_of_handle_regrename, /* execute */
1993*404b540aSrobert NULL, /* sub */
1994*404b540aSrobert NULL, /* next */
1995*404b540aSrobert 0, /* static_pass_number */
1996*404b540aSrobert TV_RENAME_REGISTERS, /* tv_id */
1997*404b540aSrobert 0, /* properties_required */
1998*404b540aSrobert 0, /* properties_provided */
1999*404b540aSrobert 0, /* properties_destroyed */
2000*404b540aSrobert 0, /* todo_flags_start */
2001*404b540aSrobert TODO_dump_func, /* todo_flags_finish */
2002*404b540aSrobert 'n' /* letter */
2003*404b540aSrobert };
2004*404b540aSrobert
2005