xref: /dflybsd-src/contrib/gcc-4.7/gcc/regrename.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* Register renaming for the GNU compiler.
2*e4b17023SJohn Marino    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
3*e4b17023SJohn Marino    2010 Free Software Foundation, Inc.
4*e4b17023SJohn Marino 
5*e4b17023SJohn Marino    This file is part of GCC.
6*e4b17023SJohn Marino 
7*e4b17023SJohn Marino    GCC is free software; you can redistribute it and/or modify it
8*e4b17023SJohn Marino    under the terms of the GNU General Public License as published by
9*e4b17023SJohn Marino    the Free Software Foundation; either version 3, or (at your option)
10*e4b17023SJohn Marino    any later version.
11*e4b17023SJohn Marino 
12*e4b17023SJohn Marino    GCC is distributed in the hope that it will be useful, but WITHOUT
13*e4b17023SJohn Marino    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14*e4b17023SJohn Marino    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15*e4b17023SJohn Marino    License for more details.
16*e4b17023SJohn Marino 
17*e4b17023SJohn Marino    You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino    along with GCC; see the file COPYING3.  If not see
19*e4b17023SJohn Marino    <http://www.gnu.org/licenses/>.  */
20*e4b17023SJohn Marino 
21*e4b17023SJohn Marino #include "config.h"
22*e4b17023SJohn Marino #include "system.h"
23*e4b17023SJohn Marino #include "coretypes.h"
24*e4b17023SJohn Marino #include "tm.h"
25*e4b17023SJohn Marino #include "rtl-error.h"
26*e4b17023SJohn Marino #include "tm_p.h"
27*e4b17023SJohn Marino #include "insn-config.h"
28*e4b17023SJohn Marino #include "regs.h"
29*e4b17023SJohn Marino #include "addresses.h"
30*e4b17023SJohn Marino #include "hard-reg-set.h"
31*e4b17023SJohn Marino #include "basic-block.h"
32*e4b17023SJohn Marino #include "reload.h"
33*e4b17023SJohn Marino #include "output.h"
34*e4b17023SJohn Marino #include "function.h"
35*e4b17023SJohn Marino #include "recog.h"
36*e4b17023SJohn Marino #include "flags.h"
37*e4b17023SJohn Marino #include "obstack.h"
38*e4b17023SJohn Marino #include "timevar.h"
39*e4b17023SJohn Marino #include "tree-pass.h"
40*e4b17023SJohn Marino #include "df.h"
41*e4b17023SJohn Marino #include "target.h"
42*e4b17023SJohn Marino #include "emit-rtl.h"
43*e4b17023SJohn Marino #include "regrename.h"
44*e4b17023SJohn Marino 
45*e4b17023SJohn Marino /* This file implements the RTL register renaming pass of the compiler.  It is
46*e4b17023SJohn Marino    a semi-local pass whose goal is to maximize the usage of the register file
47*e4b17023SJohn Marino    of the processor by substituting registers for others in the solution given
48*e4b17023SJohn Marino    by the register allocator.  The algorithm is as follows:
49*e4b17023SJohn Marino 
50*e4b17023SJohn Marino      1. Local def/use chains are built: within each basic block, chains are
51*e4b17023SJohn Marino 	opened and closed; if a chain isn't closed at the end of the block,
52*e4b17023SJohn Marino 	it is dropped.  We pre-open chains if we have already examined a
53*e4b17023SJohn Marino 	predecessor block and found chains live at the end which match
54*e4b17023SJohn Marino 	live registers at the start of the new block.
55*e4b17023SJohn Marino 
56*e4b17023SJohn Marino      2. We try to combine the local chains across basic block boundaries by
57*e4b17023SJohn Marino         comparing chains that were open at the start or end of a block to
58*e4b17023SJohn Marino 	those in successor/predecessor blocks.
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino      3. For each chain, the set of possible renaming registers is computed.
61*e4b17023SJohn Marino 	This takes into account the renaming of previously processed chains.
62*e4b17023SJohn Marino 	Optionally, a preferred class is computed for the renaming register.
63*e4b17023SJohn Marino 
64*e4b17023SJohn Marino      4. The best renaming register is computed for the chain in the above set,
65*e4b17023SJohn Marino 	using a round-robin allocation.  If a preferred class exists, then the
66*e4b17023SJohn Marino 	round-robin allocation is done within the class first, if possible.
67*e4b17023SJohn Marino 	The round-robin allocation of renaming registers itself is global.
68*e4b17023SJohn Marino 
69*e4b17023SJohn Marino      5. If a renaming register has been found, it is substituted in the chain.
70*e4b17023SJohn Marino 
71*e4b17023SJohn Marino   Targets can parameterize the pass by specifying a preferred class for the
72*e4b17023SJohn Marino   renaming register for a given (super)class of registers to be renamed.  */
73*e4b17023SJohn Marino 
74*e4b17023SJohn Marino #if HOST_BITS_PER_WIDE_INT <= MAX_RECOG_OPERANDS
75*e4b17023SJohn Marino #error "Use a different bitmap implementation for untracked_operands."
76*e4b17023SJohn Marino #endif
77*e4b17023SJohn Marino 
78*e4b17023SJohn Marino enum scan_actions
79*e4b17023SJohn Marino {
80*e4b17023SJohn Marino   terminate_write,
81*e4b17023SJohn Marino   terminate_dead,
82*e4b17023SJohn Marino   mark_all_read,
83*e4b17023SJohn Marino   mark_read,
84*e4b17023SJohn Marino   mark_write,
85*e4b17023SJohn Marino   /* mark_access is for marking the destination regs in
86*e4b17023SJohn Marino      REG_FRAME_RELATED_EXPR notes (as if they were read) so that the
87*e4b17023SJohn Marino      note is updated properly.  */
88*e4b17023SJohn Marino   mark_access
89*e4b17023SJohn Marino };
90*e4b17023SJohn Marino 
91*e4b17023SJohn Marino static const char * const scan_actions_name[] =
92*e4b17023SJohn Marino {
93*e4b17023SJohn Marino   "terminate_write",
94*e4b17023SJohn Marino   "terminate_dead",
95*e4b17023SJohn Marino   "mark_all_read",
96*e4b17023SJohn Marino   "mark_read",
97*e4b17023SJohn Marino   "mark_write",
98*e4b17023SJohn Marino   "mark_access"
99*e4b17023SJohn Marino };
100*e4b17023SJohn Marino 
101*e4b17023SJohn Marino /* TICK and THIS_TICK are used to record the last time we saw each
102*e4b17023SJohn Marino    register.  */
103*e4b17023SJohn Marino static int tick[FIRST_PSEUDO_REGISTER];
104*e4b17023SJohn Marino static int this_tick = 0;
105*e4b17023SJohn Marino 
106*e4b17023SJohn Marino static struct obstack rename_obstack;
107*e4b17023SJohn Marino 
108*e4b17023SJohn Marino /* If nonnull, the code calling into the register renamer requested
109*e4b17023SJohn Marino    information about insn operands, and we store it here.  */
110*e4b17023SJohn Marino VEC(insn_rr_info, heap) *insn_rr;
111*e4b17023SJohn Marino 
112*e4b17023SJohn Marino static void scan_rtx (rtx, rtx *, enum reg_class, enum scan_actions,
113*e4b17023SJohn Marino 		      enum op_type);
114*e4b17023SJohn Marino static bool build_def_use (basic_block);
115*e4b17023SJohn Marino 
116*e4b17023SJohn Marino /* The id to be given to the next opened chain.  */
117*e4b17023SJohn Marino static unsigned current_id;
118*e4b17023SJohn Marino 
119*e4b17023SJohn Marino /* A mapping of unique id numbers to chains.  */
120*e4b17023SJohn Marino static VEC(du_head_p, heap) *id_to_chain;
121*e4b17023SJohn Marino 
122*e4b17023SJohn Marino /* List of currently open chains.  */
123*e4b17023SJohn Marino static struct du_head *open_chains;
124*e4b17023SJohn Marino 
125*e4b17023SJohn Marino /* Bitmap of open chains.  The bits set always match the list found in
126*e4b17023SJohn Marino    open_chains.  */
127*e4b17023SJohn Marino static bitmap_head open_chains_set;
128*e4b17023SJohn Marino 
129*e4b17023SJohn Marino /* Record the registers being tracked in open_chains.  */
130*e4b17023SJohn Marino static HARD_REG_SET live_in_chains;
131*e4b17023SJohn Marino 
132*e4b17023SJohn Marino /* Record the registers that are live but not tracked.  The intersection
133*e4b17023SJohn Marino    between this and live_in_chains is empty.  */
134*e4b17023SJohn Marino static HARD_REG_SET live_hard_regs;
135*e4b17023SJohn Marino 
136*e4b17023SJohn Marino /* Set while scanning RTL if INSN_RR is nonnull, i.e. if the current analysis
137*e4b17023SJohn Marino    is for a caller that requires operand data.  Used in
138*e4b17023SJohn Marino    record_operand_use.  */
139*e4b17023SJohn Marino static operand_rr_info *cur_operand;
140*e4b17023SJohn Marino 
141*e4b17023SJohn Marino /* Return the chain corresponding to id number ID.  Take into account that
142*e4b17023SJohn Marino    chains may have been merged.  */
143*e4b17023SJohn Marino du_head_p
regrename_chain_from_id(unsigned int id)144*e4b17023SJohn Marino regrename_chain_from_id (unsigned int id)
145*e4b17023SJohn Marino {
146*e4b17023SJohn Marino   du_head_p first_chain = VEC_index (du_head_p, id_to_chain, id);
147*e4b17023SJohn Marino   du_head_p chain = first_chain;
148*e4b17023SJohn Marino   while (chain->id != id)
149*e4b17023SJohn Marino     {
150*e4b17023SJohn Marino       id = chain->id;
151*e4b17023SJohn Marino       chain = VEC_index (du_head_p, id_to_chain, id);
152*e4b17023SJohn Marino     }
153*e4b17023SJohn Marino   first_chain->id = id;
154*e4b17023SJohn Marino   return chain;
155*e4b17023SJohn Marino }
156*e4b17023SJohn Marino 
157*e4b17023SJohn Marino /* Dump all def/use chains, starting at id FROM.  */
158*e4b17023SJohn Marino 
159*e4b17023SJohn Marino static void
dump_def_use_chain(int from)160*e4b17023SJohn Marino dump_def_use_chain (int from)
161*e4b17023SJohn Marino {
162*e4b17023SJohn Marino   du_head_p head;
163*e4b17023SJohn Marino   int i;
164*e4b17023SJohn Marino   FOR_EACH_VEC_ELT_FROM (du_head_p, id_to_chain, i, head, from)
165*e4b17023SJohn Marino     {
166*e4b17023SJohn Marino       struct du_chain *this_du = head->first;
167*e4b17023SJohn Marino 
168*e4b17023SJohn Marino       fprintf (dump_file, "Register %s (%d):",
169*e4b17023SJohn Marino 	       reg_names[head->regno], head->nregs);
170*e4b17023SJohn Marino       while (this_du)
171*e4b17023SJohn Marino 	{
172*e4b17023SJohn Marino 	  fprintf (dump_file, " %d [%s]", INSN_UID (this_du->insn),
173*e4b17023SJohn Marino 		   reg_class_names[this_du->cl]);
174*e4b17023SJohn Marino 	  this_du = this_du->next_use;
175*e4b17023SJohn Marino 	}
176*e4b17023SJohn Marino       fprintf (dump_file, "\n");
177*e4b17023SJohn Marino       head = head->next_chain;
178*e4b17023SJohn Marino     }
179*e4b17023SJohn Marino }
180*e4b17023SJohn Marino 
181*e4b17023SJohn Marino static void
free_chain_data(void)182*e4b17023SJohn Marino free_chain_data (void)
183*e4b17023SJohn Marino {
184*e4b17023SJohn Marino   int i;
185*e4b17023SJohn Marino   du_head_p ptr;
186*e4b17023SJohn Marino   for (i = 0; VEC_iterate(du_head_p, id_to_chain, i, ptr); i++)
187*e4b17023SJohn Marino     bitmap_clear (&ptr->conflicts);
188*e4b17023SJohn Marino 
189*e4b17023SJohn Marino   VEC_free (du_head_p, heap, id_to_chain);
190*e4b17023SJohn Marino }
191*e4b17023SJohn Marino 
192*e4b17023SJohn Marino /* Walk all chains starting with CHAINS and record that they conflict with
193*e4b17023SJohn Marino    another chain whose id is ID.  */
194*e4b17023SJohn Marino 
195*e4b17023SJohn Marino static void
mark_conflict(struct du_head * chains,unsigned id)196*e4b17023SJohn Marino mark_conflict (struct du_head *chains, unsigned id)
197*e4b17023SJohn Marino {
198*e4b17023SJohn Marino   while (chains)
199*e4b17023SJohn Marino     {
200*e4b17023SJohn Marino       bitmap_set_bit (&chains->conflicts, id);
201*e4b17023SJohn Marino       chains = chains->next_chain;
202*e4b17023SJohn Marino     }
203*e4b17023SJohn Marino }
204*e4b17023SJohn Marino 
205*e4b17023SJohn Marino /* Examine cur_operand, and if it is nonnull, record information about the
206*e4b17023SJohn Marino    use THIS_DU which is part of the chain HEAD.  */
207*e4b17023SJohn Marino 
208*e4b17023SJohn Marino static void
record_operand_use(struct du_head * head,struct du_chain * this_du)209*e4b17023SJohn Marino record_operand_use (struct du_head *head, struct du_chain *this_du)
210*e4b17023SJohn Marino {
211*e4b17023SJohn Marino   if (cur_operand == NULL)
212*e4b17023SJohn Marino     return;
213*e4b17023SJohn Marino   gcc_assert (cur_operand->n_chains < MAX_REGS_PER_ADDRESS);
214*e4b17023SJohn Marino   cur_operand->heads[cur_operand->n_chains] = head;
215*e4b17023SJohn Marino   cur_operand->chains[cur_operand->n_chains++] = this_du;
216*e4b17023SJohn Marino }
217*e4b17023SJohn Marino 
218*e4b17023SJohn Marino /* Create a new chain for THIS_NREGS registers starting at THIS_REGNO,
219*e4b17023SJohn Marino    and record its occurrence in *LOC, which is being written to in INSN.
220*e4b17023SJohn Marino    This access requires a register of class CL.  */
221*e4b17023SJohn Marino 
222*e4b17023SJohn Marino static du_head_p
create_new_chain(unsigned this_regno,unsigned this_nregs,rtx * loc,rtx insn,enum reg_class cl)223*e4b17023SJohn Marino create_new_chain (unsigned this_regno, unsigned this_nregs, rtx *loc,
224*e4b17023SJohn Marino 		  rtx insn, enum reg_class cl)
225*e4b17023SJohn Marino {
226*e4b17023SJohn Marino   struct du_head *head = XOBNEW (&rename_obstack, struct du_head);
227*e4b17023SJohn Marino   struct du_chain *this_du;
228*e4b17023SJohn Marino   int nregs;
229*e4b17023SJohn Marino 
230*e4b17023SJohn Marino   head->next_chain = open_chains;
231*e4b17023SJohn Marino   head->regno = this_regno;
232*e4b17023SJohn Marino   head->nregs = this_nregs;
233*e4b17023SJohn Marino   head->need_caller_save_reg = 0;
234*e4b17023SJohn Marino   head->cannot_rename = 0;
235*e4b17023SJohn Marino 
236*e4b17023SJohn Marino   VEC_safe_push (du_head_p, heap, id_to_chain, head);
237*e4b17023SJohn Marino   head->id = current_id++;
238*e4b17023SJohn Marino 
239*e4b17023SJohn Marino   bitmap_initialize (&head->conflicts, &bitmap_default_obstack);
240*e4b17023SJohn Marino   bitmap_copy (&head->conflicts, &open_chains_set);
241*e4b17023SJohn Marino   mark_conflict (open_chains, head->id);
242*e4b17023SJohn Marino 
243*e4b17023SJohn Marino   /* Since we're tracking this as a chain now, remove it from the
244*e4b17023SJohn Marino      list of conflicting live hard registers and track it in
245*e4b17023SJohn Marino      live_in_chains instead.  */
246*e4b17023SJohn Marino   nregs = head->nregs;
247*e4b17023SJohn Marino   while (nregs-- > 0)
248*e4b17023SJohn Marino     {
249*e4b17023SJohn Marino       SET_HARD_REG_BIT (live_in_chains, head->regno + nregs);
250*e4b17023SJohn Marino       CLEAR_HARD_REG_BIT (live_hard_regs, head->regno + nregs);
251*e4b17023SJohn Marino     }
252*e4b17023SJohn Marino 
253*e4b17023SJohn Marino   COPY_HARD_REG_SET (head->hard_conflicts, live_hard_regs);
254*e4b17023SJohn Marino   bitmap_set_bit (&open_chains_set, head->id);
255*e4b17023SJohn Marino 
256*e4b17023SJohn Marino   open_chains = head;
257*e4b17023SJohn Marino 
258*e4b17023SJohn Marino   if (dump_file)
259*e4b17023SJohn Marino     {
260*e4b17023SJohn Marino       fprintf (dump_file, "Creating chain %s (%d)",
261*e4b17023SJohn Marino 	       reg_names[head->regno], head->id);
262*e4b17023SJohn Marino       if (insn != NULL_RTX)
263*e4b17023SJohn Marino 	fprintf (dump_file, " at insn %d", INSN_UID (insn));
264*e4b17023SJohn Marino       fprintf (dump_file, "\n");
265*e4b17023SJohn Marino     }
266*e4b17023SJohn Marino 
267*e4b17023SJohn Marino   if (insn == NULL_RTX)
268*e4b17023SJohn Marino     {
269*e4b17023SJohn Marino       head->first = head->last = NULL;
270*e4b17023SJohn Marino       return head;
271*e4b17023SJohn Marino     }
272*e4b17023SJohn Marino 
273*e4b17023SJohn Marino   this_du = XOBNEW (&rename_obstack, struct du_chain);
274*e4b17023SJohn Marino   head->first = head->last = this_du;
275*e4b17023SJohn Marino 
276*e4b17023SJohn Marino   this_du->next_use = 0;
277*e4b17023SJohn Marino   this_du->loc = loc;
278*e4b17023SJohn Marino   this_du->insn = insn;
279*e4b17023SJohn Marino   this_du->cl = cl;
280*e4b17023SJohn Marino   record_operand_use (head, this_du);
281*e4b17023SJohn Marino   return head;
282*e4b17023SJohn Marino }
283*e4b17023SJohn Marino 
284*e4b17023SJohn Marino /* For a def-use chain HEAD, find which registers overlap its lifetime and
285*e4b17023SJohn Marino    set the corresponding bits in *PSET.  */
286*e4b17023SJohn Marino 
287*e4b17023SJohn Marino static void
merge_overlapping_regs(HARD_REG_SET * pset,struct du_head * head)288*e4b17023SJohn Marino merge_overlapping_regs (HARD_REG_SET *pset, struct du_head *head)
289*e4b17023SJohn Marino {
290*e4b17023SJohn Marino   bitmap_iterator bi;
291*e4b17023SJohn Marino   unsigned i;
292*e4b17023SJohn Marino   IOR_HARD_REG_SET (*pset, head->hard_conflicts);
293*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (&head->conflicts, 0, i, bi)
294*e4b17023SJohn Marino     {
295*e4b17023SJohn Marino       du_head_p other = regrename_chain_from_id (i);
296*e4b17023SJohn Marino       unsigned j = other->nregs;
297*e4b17023SJohn Marino       gcc_assert (other != head);
298*e4b17023SJohn Marino       while (j-- > 0)
299*e4b17023SJohn Marino 	SET_HARD_REG_BIT (*pset, other->regno + j);
300*e4b17023SJohn Marino     }
301*e4b17023SJohn Marino }
302*e4b17023SJohn Marino 
303*e4b17023SJohn Marino /* Check if NEW_REG can be the candidate register to rename for
304*e4b17023SJohn Marino    REG in THIS_HEAD chain.  THIS_UNAVAILABLE is a set of unavailable hard
305*e4b17023SJohn Marino    registers.  */
306*e4b17023SJohn Marino 
307*e4b17023SJohn Marino static bool
check_new_reg_p(int reg ATTRIBUTE_UNUSED,int new_reg,struct du_head * this_head,HARD_REG_SET this_unavailable)308*e4b17023SJohn Marino check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg,
309*e4b17023SJohn Marino 		 struct du_head *this_head, HARD_REG_SET this_unavailable)
310*e4b17023SJohn Marino {
311*e4b17023SJohn Marino   enum machine_mode mode = GET_MODE (*this_head->first->loc);
312*e4b17023SJohn Marino   int nregs = hard_regno_nregs[new_reg][mode];
313*e4b17023SJohn Marino   int i;
314*e4b17023SJohn Marino   struct du_chain *tmp;
315*e4b17023SJohn Marino 
316*e4b17023SJohn Marino   for (i = nregs - 1; i >= 0; --i)
317*e4b17023SJohn Marino     if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i)
318*e4b17023SJohn Marino 	|| fixed_regs[new_reg + i]
319*e4b17023SJohn Marino 	|| global_regs[new_reg + i]
320*e4b17023SJohn Marino 	/* Can't use regs which aren't saved by the prologue.  */
321*e4b17023SJohn Marino 	|| (! df_regs_ever_live_p (new_reg + i)
322*e4b17023SJohn Marino 	    && ! call_used_regs[new_reg + i])
323*e4b17023SJohn Marino #ifdef LEAF_REGISTERS
324*e4b17023SJohn Marino 	/* We can't use a non-leaf register if we're in a
325*e4b17023SJohn Marino 	   leaf function.  */
326*e4b17023SJohn Marino 	|| (current_function_is_leaf
327*e4b17023SJohn Marino 	    && !LEAF_REGISTERS[new_reg + i])
328*e4b17023SJohn Marino #endif
329*e4b17023SJohn Marino #ifdef HARD_REGNO_RENAME_OK
330*e4b17023SJohn Marino 	|| ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i)
331*e4b17023SJohn Marino #endif
332*e4b17023SJohn Marino 	)
333*e4b17023SJohn Marino       return false;
334*e4b17023SJohn Marino 
335*e4b17023SJohn Marino   /* See whether it accepts all modes that occur in
336*e4b17023SJohn Marino      definition and uses.  */
337*e4b17023SJohn Marino   for (tmp = this_head->first; tmp; tmp = tmp->next_use)
338*e4b17023SJohn Marino     if ((! HARD_REGNO_MODE_OK (new_reg, GET_MODE (*tmp->loc))
339*e4b17023SJohn Marino 	 && ! DEBUG_INSN_P (tmp->insn))
340*e4b17023SJohn Marino 	|| (this_head->need_caller_save_reg
341*e4b17023SJohn Marino 	    && ! (HARD_REGNO_CALL_PART_CLOBBERED
342*e4b17023SJohn Marino 		  (reg, GET_MODE (*tmp->loc)))
343*e4b17023SJohn Marino 	    && (HARD_REGNO_CALL_PART_CLOBBERED
344*e4b17023SJohn Marino 		(new_reg, GET_MODE (*tmp->loc)))))
345*e4b17023SJohn Marino       return false;
346*e4b17023SJohn Marino 
347*e4b17023SJohn Marino   return true;
348*e4b17023SJohn Marino }
349*e4b17023SJohn Marino 
350*e4b17023SJohn Marino /* For the chain THIS_HEAD, compute and return the best register to
351*e4b17023SJohn Marino    rename to.  SUPER_CLASS is the superunion of register classes in
352*e4b17023SJohn Marino    the chain.  UNAVAILABLE is a set of registers that cannot be used.
353*e4b17023SJohn Marino    OLD_REG is the register currently used for the chain.  */
354*e4b17023SJohn Marino 
355*e4b17023SJohn Marino int
find_best_rename_reg(du_head_p this_head,enum reg_class super_class,HARD_REG_SET * unavailable,int old_reg)356*e4b17023SJohn Marino find_best_rename_reg (du_head_p this_head, enum reg_class super_class,
357*e4b17023SJohn Marino 		      HARD_REG_SET *unavailable, int old_reg)
358*e4b17023SJohn Marino {
359*e4b17023SJohn Marino   bool has_preferred_class;
360*e4b17023SJohn Marino   enum reg_class preferred_class;
361*e4b17023SJohn Marino   int pass;
362*e4b17023SJohn Marino   int best_new_reg = old_reg;
363*e4b17023SJohn Marino 
364*e4b17023SJohn Marino   /* Further narrow the set of registers we can use for renaming.
365*e4b17023SJohn Marino      If the chain needs a call-saved register, mark the call-used
366*e4b17023SJohn Marino      registers as unavailable.  */
367*e4b17023SJohn Marino   if (this_head->need_caller_save_reg)
368*e4b17023SJohn Marino     IOR_HARD_REG_SET (*unavailable, call_used_reg_set);
369*e4b17023SJohn Marino 
370*e4b17023SJohn Marino   /* Mark registers that overlap this chain's lifetime as unavailable.  */
371*e4b17023SJohn Marino   merge_overlapping_regs (unavailable, this_head);
372*e4b17023SJohn Marino 
373*e4b17023SJohn Marino   /* Compute preferred rename class of super union of all the classes
374*e4b17023SJohn Marino      in the chain.  */
375*e4b17023SJohn Marino   preferred_class
376*e4b17023SJohn Marino     = (enum reg_class) targetm.preferred_rename_class (super_class);
377*e4b17023SJohn Marino 
378*e4b17023SJohn Marino   /* If PREFERRED_CLASS is not NO_REGS, we iterate in the first pass
379*e4b17023SJohn Marino      over registers that belong to PREFERRED_CLASS and try to find the
380*e4b17023SJohn Marino      best register within the class.  If that failed, we iterate in
381*e4b17023SJohn Marino      the second pass over registers that don't belong to the class.
382*e4b17023SJohn Marino      If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
383*e4b17023SJohn Marino      ascending order without any preference.  */
384*e4b17023SJohn Marino   has_preferred_class = (preferred_class != NO_REGS);
385*e4b17023SJohn Marino   for (pass = (has_preferred_class ? 0 : 1); pass < 2; pass++)
386*e4b17023SJohn Marino     {
387*e4b17023SJohn Marino       int new_reg;
388*e4b17023SJohn Marino       for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
389*e4b17023SJohn Marino 	{
390*e4b17023SJohn Marino 	  if (has_preferred_class
391*e4b17023SJohn Marino 	      && (pass == 0)
392*e4b17023SJohn Marino 	      != TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
393*e4b17023SJohn Marino 				    new_reg))
394*e4b17023SJohn Marino 	    continue;
395*e4b17023SJohn Marino 
396*e4b17023SJohn Marino 	  /* In the first pass, we force the renaming of registers that
397*e4b17023SJohn Marino 	     don't belong to PREFERRED_CLASS to registers that do, even
398*e4b17023SJohn Marino 	     though the latters were used not very long ago.  */
399*e4b17023SJohn Marino 	  if (check_new_reg_p (old_reg, new_reg, this_head,
400*e4b17023SJohn Marino 			       *unavailable)
401*e4b17023SJohn Marino 	      && ((pass == 0
402*e4b17023SJohn Marino 		   && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
403*e4b17023SJohn Marino 					  best_new_reg))
404*e4b17023SJohn Marino 		  || tick[best_new_reg] > tick[new_reg]))
405*e4b17023SJohn Marino 	    best_new_reg = new_reg;
406*e4b17023SJohn Marino 	}
407*e4b17023SJohn Marino       if (pass == 0 && best_new_reg != old_reg)
408*e4b17023SJohn Marino 	break;
409*e4b17023SJohn Marino     }
410*e4b17023SJohn Marino   return best_new_reg;
411*e4b17023SJohn Marino }
412*e4b17023SJohn Marino 
413*e4b17023SJohn Marino /* Perform register renaming on the current function.  */
414*e4b17023SJohn Marino static void
rename_chains(void)415*e4b17023SJohn Marino rename_chains (void)
416*e4b17023SJohn Marino {
417*e4b17023SJohn Marino   HARD_REG_SET unavailable;
418*e4b17023SJohn Marino   du_head_p this_head;
419*e4b17023SJohn Marino   int i;
420*e4b17023SJohn Marino 
421*e4b17023SJohn Marino   memset (tick, 0, sizeof tick);
422*e4b17023SJohn Marino 
423*e4b17023SJohn Marino   CLEAR_HARD_REG_SET (unavailable);
424*e4b17023SJohn Marino   /* Don't clobber traceback for noreturn functions.  */
425*e4b17023SJohn Marino   if (frame_pointer_needed)
426*e4b17023SJohn Marino     {
427*e4b17023SJohn Marino       add_to_hard_reg_set (&unavailable, Pmode, FRAME_POINTER_REGNUM);
428*e4b17023SJohn Marino #if !HARD_FRAME_POINTER_IS_FRAME_POINTER
429*e4b17023SJohn Marino       add_to_hard_reg_set (&unavailable, Pmode, HARD_FRAME_POINTER_REGNUM);
430*e4b17023SJohn Marino #endif
431*e4b17023SJohn Marino     }
432*e4b17023SJohn Marino 
433*e4b17023SJohn Marino   FOR_EACH_VEC_ELT (du_head_p, id_to_chain, i, this_head)
434*e4b17023SJohn Marino     {
435*e4b17023SJohn Marino       int best_new_reg;
436*e4b17023SJohn Marino       int n_uses;
437*e4b17023SJohn Marino       struct du_chain *tmp;
438*e4b17023SJohn Marino       HARD_REG_SET this_unavailable;
439*e4b17023SJohn Marino       int reg = this_head->regno;
440*e4b17023SJohn Marino       enum reg_class super_class = NO_REGS;
441*e4b17023SJohn Marino 
442*e4b17023SJohn Marino       if (this_head->cannot_rename)
443*e4b17023SJohn Marino 	continue;
444*e4b17023SJohn Marino 
445*e4b17023SJohn Marino       if (fixed_regs[reg] || global_regs[reg]
446*e4b17023SJohn Marino #if !HARD_FRAME_POINTER_IS_FRAME_POINTER
447*e4b17023SJohn Marino 	  || (frame_pointer_needed && reg == HARD_FRAME_POINTER_REGNUM)
448*e4b17023SJohn Marino #else
449*e4b17023SJohn Marino 	  || (frame_pointer_needed && reg == FRAME_POINTER_REGNUM)
450*e4b17023SJohn Marino #endif
451*e4b17023SJohn Marino 	  )
452*e4b17023SJohn Marino 	continue;
453*e4b17023SJohn Marino 
454*e4b17023SJohn Marino       COPY_HARD_REG_SET (this_unavailable, unavailable);
455*e4b17023SJohn Marino 
456*e4b17023SJohn Marino       /* Iterate over elements in the chain in order to:
457*e4b17023SJohn Marino 	 1. Count number of uses, and narrow the set of registers we can
458*e4b17023SJohn Marino 	    use for renaming.
459*e4b17023SJohn Marino 	 2. Compute the superunion of register classes in this chain.  */
460*e4b17023SJohn Marino       n_uses = 0;
461*e4b17023SJohn Marino       super_class = NO_REGS;
462*e4b17023SJohn Marino       for (tmp = this_head->first; tmp; tmp = tmp->next_use)
463*e4b17023SJohn Marino 	{
464*e4b17023SJohn Marino 	  if (DEBUG_INSN_P (tmp->insn))
465*e4b17023SJohn Marino 	    continue;
466*e4b17023SJohn Marino 	  n_uses++;
467*e4b17023SJohn Marino 	  IOR_COMPL_HARD_REG_SET (this_unavailable,
468*e4b17023SJohn Marino 				  reg_class_contents[tmp->cl]);
469*e4b17023SJohn Marino 	  super_class
470*e4b17023SJohn Marino 	    = reg_class_superunion[(int) super_class][(int) tmp->cl];
471*e4b17023SJohn Marino 	}
472*e4b17023SJohn Marino 
473*e4b17023SJohn Marino       if (n_uses < 2)
474*e4b17023SJohn Marino 	continue;
475*e4b17023SJohn Marino 
476*e4b17023SJohn Marino       best_new_reg = find_best_rename_reg (this_head, super_class,
477*e4b17023SJohn Marino 					   &this_unavailable, reg);
478*e4b17023SJohn Marino 
479*e4b17023SJohn Marino       if (dump_file)
480*e4b17023SJohn Marino 	{
481*e4b17023SJohn Marino 	  fprintf (dump_file, "Register %s in insn %d",
482*e4b17023SJohn Marino 		   reg_names[reg], INSN_UID (this_head->first->insn));
483*e4b17023SJohn Marino 	  if (this_head->need_caller_save_reg)
484*e4b17023SJohn Marino 	    fprintf (dump_file, " crosses a call");
485*e4b17023SJohn Marino 	}
486*e4b17023SJohn Marino 
487*e4b17023SJohn Marino       if (best_new_reg == reg)
488*e4b17023SJohn Marino 	{
489*e4b17023SJohn Marino 	  tick[reg] = ++this_tick;
490*e4b17023SJohn Marino 	  if (dump_file)
491*e4b17023SJohn Marino 	    fprintf (dump_file, "; no available better choice\n");
492*e4b17023SJohn Marino 	  continue;
493*e4b17023SJohn Marino 	}
494*e4b17023SJohn Marino 
495*e4b17023SJohn Marino       if (dump_file)
496*e4b17023SJohn Marino 	fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
497*e4b17023SJohn Marino 
498*e4b17023SJohn Marino       regrename_do_replace (this_head, best_new_reg);
499*e4b17023SJohn Marino       tick[best_new_reg] = ++this_tick;
500*e4b17023SJohn Marino       df_set_regs_ever_live (best_new_reg, true);
501*e4b17023SJohn Marino     }
502*e4b17023SJohn Marino }
503*e4b17023SJohn Marino 
504*e4b17023SJohn Marino /* A structure to record information for each hard register at the start of
505*e4b17023SJohn Marino    a basic block.  */
506*e4b17023SJohn Marino struct incoming_reg_info {
507*e4b17023SJohn Marino   /* Holds the number of registers used in the chain that gave us information
508*e4b17023SJohn Marino      about this register.  Zero means no information known yet, while a
509*e4b17023SJohn Marino      negative value is used for something that is part of, but not the first
510*e4b17023SJohn Marino      register in a multi-register value.  */
511*e4b17023SJohn Marino   int nregs;
512*e4b17023SJohn Marino   /* Set to true if we have accesses that conflict in the number of registers
513*e4b17023SJohn Marino      used.  */
514*e4b17023SJohn Marino   bool unusable;
515*e4b17023SJohn Marino };
516*e4b17023SJohn Marino 
517*e4b17023SJohn Marino /* A structure recording information about each basic block.  It is saved
518*e4b17023SJohn Marino    and restored around basic block boundaries.
519*e4b17023SJohn Marino    A pointer to such a structure is stored in each basic block's aux field
520*e4b17023SJohn Marino    during regrename_analyze, except for blocks we know can't be optimized
521*e4b17023SJohn Marino    (such as entry and exit blocks).  */
522*e4b17023SJohn Marino struct bb_rename_info
523*e4b17023SJohn Marino {
524*e4b17023SJohn Marino   /* The basic block corresponding to this structure.  */
525*e4b17023SJohn Marino   basic_block bb;
526*e4b17023SJohn Marino   /* Copies of the global information.  */
527*e4b17023SJohn Marino   bitmap_head open_chains_set;
528*e4b17023SJohn Marino   bitmap_head incoming_open_chains_set;
529*e4b17023SJohn Marino   struct incoming_reg_info incoming[FIRST_PSEUDO_REGISTER];
530*e4b17023SJohn Marino };
531*e4b17023SJohn Marino 
532*e4b17023SJohn Marino /* Initialize a rename_info structure P for basic block BB, which starts a new
533*e4b17023SJohn Marino    scan.  */
534*e4b17023SJohn Marino static void
init_rename_info(struct bb_rename_info * p,basic_block bb)535*e4b17023SJohn Marino init_rename_info (struct bb_rename_info *p, basic_block bb)
536*e4b17023SJohn Marino {
537*e4b17023SJohn Marino   int i;
538*e4b17023SJohn Marino   df_ref *def_rec;
539*e4b17023SJohn Marino   HARD_REG_SET start_chains_set;
540*e4b17023SJohn Marino 
541*e4b17023SJohn Marino   p->bb = bb;
542*e4b17023SJohn Marino   bitmap_initialize (&p->open_chains_set, &bitmap_default_obstack);
543*e4b17023SJohn Marino   bitmap_initialize (&p->incoming_open_chains_set, &bitmap_default_obstack);
544*e4b17023SJohn Marino 
545*e4b17023SJohn Marino   open_chains = NULL;
546*e4b17023SJohn Marino   bitmap_clear (&open_chains_set);
547*e4b17023SJohn Marino 
548*e4b17023SJohn Marino   CLEAR_HARD_REG_SET (live_in_chains);
549*e4b17023SJohn Marino   REG_SET_TO_HARD_REG_SET (live_hard_regs, df_get_live_in (bb));
550*e4b17023SJohn Marino   for (def_rec = df_get_artificial_defs (bb->index); *def_rec; def_rec++)
551*e4b17023SJohn Marino     {
552*e4b17023SJohn Marino       df_ref def = *def_rec;
553*e4b17023SJohn Marino       if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
554*e4b17023SJohn Marino 	SET_HARD_REG_BIT (live_hard_regs, DF_REF_REGNO (def));
555*e4b17023SJohn Marino     }
556*e4b17023SJohn Marino 
557*e4b17023SJohn Marino   /* Open chains based on information from (at least one) predecessor
558*e4b17023SJohn Marino      block.  This gives us a chance later on to combine chains across
559*e4b17023SJohn Marino      basic block boundaries.  Inconsistencies (in access sizes) will
560*e4b17023SJohn Marino      be caught normally and dealt with conservatively by disabling the
561*e4b17023SJohn Marino      chain for renaming, and there is no risk of losing optimization
562*e4b17023SJohn Marino      opportunities by opening chains either: if we did not open the
563*e4b17023SJohn Marino      chains, we'd have to track the live register as a hard reg, and
564*e4b17023SJohn Marino      we'd be unable to rename it in any case.  */
565*e4b17023SJohn Marino   CLEAR_HARD_REG_SET (start_chains_set);
566*e4b17023SJohn Marino   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
567*e4b17023SJohn Marino     {
568*e4b17023SJohn Marino       struct incoming_reg_info *iri = p->incoming + i;
569*e4b17023SJohn Marino       if (iri->nregs > 0 && !iri->unusable
570*e4b17023SJohn Marino 	  && range_in_hard_reg_set_p (live_hard_regs, i, iri->nregs))
571*e4b17023SJohn Marino 	{
572*e4b17023SJohn Marino 	  SET_HARD_REG_BIT (start_chains_set, i);
573*e4b17023SJohn Marino 	  remove_range_from_hard_reg_set (&live_hard_regs, i, iri->nregs);
574*e4b17023SJohn Marino 	}
575*e4b17023SJohn Marino     }
576*e4b17023SJohn Marino   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
577*e4b17023SJohn Marino     {
578*e4b17023SJohn Marino       struct incoming_reg_info *iri = p->incoming + i;
579*e4b17023SJohn Marino       if (TEST_HARD_REG_BIT (start_chains_set, i))
580*e4b17023SJohn Marino 	{
581*e4b17023SJohn Marino 	  du_head_p chain;
582*e4b17023SJohn Marino 	  if (dump_file)
583*e4b17023SJohn Marino 	    fprintf (dump_file, "opening incoming chain\n");
584*e4b17023SJohn Marino 	  chain = create_new_chain (i, iri->nregs, NULL, NULL_RTX, NO_REGS);
585*e4b17023SJohn Marino 	  bitmap_set_bit (&p->incoming_open_chains_set, chain->id);
586*e4b17023SJohn Marino 	}
587*e4b17023SJohn Marino     }
588*e4b17023SJohn Marino }
589*e4b17023SJohn Marino 
590*e4b17023SJohn Marino /* Record in RI that the block corresponding to it has an incoming
591*e4b17023SJohn Marino    live value, described by CHAIN.  */
592*e4b17023SJohn Marino static void
set_incoming_from_chain(struct bb_rename_info * ri,du_head_p chain)593*e4b17023SJohn Marino set_incoming_from_chain (struct bb_rename_info *ri, du_head_p chain)
594*e4b17023SJohn Marino {
595*e4b17023SJohn Marino   int i;
596*e4b17023SJohn Marino   int incoming_nregs = ri->incoming[chain->regno].nregs;
597*e4b17023SJohn Marino   int nregs;
598*e4b17023SJohn Marino 
599*e4b17023SJohn Marino   /* If we've recorded the same information before, everything is fine.  */
600*e4b17023SJohn Marino   if (incoming_nregs == chain->nregs)
601*e4b17023SJohn Marino     {
602*e4b17023SJohn Marino       if (dump_file)
603*e4b17023SJohn Marino 	fprintf (dump_file, "reg %d/%d already recorded\n",
604*e4b17023SJohn Marino 		 chain->regno, chain->nregs);
605*e4b17023SJohn Marino       return;
606*e4b17023SJohn Marino     }
607*e4b17023SJohn Marino 
608*e4b17023SJohn Marino   /* If we have no information for any of the involved registers, update
609*e4b17023SJohn Marino      the incoming array.  */
610*e4b17023SJohn Marino   nregs = chain->nregs;
611*e4b17023SJohn Marino   while (nregs-- > 0)
612*e4b17023SJohn Marino     if (ri->incoming[chain->regno + nregs].nregs != 0
613*e4b17023SJohn Marino 	|| ri->incoming[chain->regno + nregs].unusable)
614*e4b17023SJohn Marino       break;
615*e4b17023SJohn Marino   if (nregs < 0)
616*e4b17023SJohn Marino     {
617*e4b17023SJohn Marino       nregs = chain->nregs;
618*e4b17023SJohn Marino       ri->incoming[chain->regno].nregs = nregs;
619*e4b17023SJohn Marino       while (nregs-- > 1)
620*e4b17023SJohn Marino 	ri->incoming[chain->regno + nregs].nregs = -nregs;
621*e4b17023SJohn Marino       if (dump_file)
622*e4b17023SJohn Marino 	fprintf (dump_file, "recorded reg %d/%d\n",
623*e4b17023SJohn Marino 		 chain->regno, chain->nregs);
624*e4b17023SJohn Marino       return;
625*e4b17023SJohn Marino     }
626*e4b17023SJohn Marino 
627*e4b17023SJohn Marino   /* There must be some kind of conflict.  Prevent both the old and
628*e4b17023SJohn Marino      new ranges from being used.  */
629*e4b17023SJohn Marino   if (incoming_nregs < 0)
630*e4b17023SJohn Marino     ri->incoming[chain->regno + incoming_nregs].unusable = true;
631*e4b17023SJohn Marino   for (i = 0; i < chain->nregs; i++)
632*e4b17023SJohn Marino     ri->incoming[chain->regno + i].unusable = true;
633*e4b17023SJohn Marino }
634*e4b17023SJohn Marino 
635*e4b17023SJohn Marino /* Merge the two chains C1 and C2 so that all conflict information is
636*e4b17023SJohn Marino    recorded and C1, and the id of C2 is changed to that of C1.  */
637*e4b17023SJohn Marino static void
merge_chains(du_head_p c1,du_head_p c2)638*e4b17023SJohn Marino merge_chains (du_head_p c1, du_head_p c2)
639*e4b17023SJohn Marino {
640*e4b17023SJohn Marino   if (c1 == c2)
641*e4b17023SJohn Marino     return;
642*e4b17023SJohn Marino 
643*e4b17023SJohn Marino   if (c2->first != NULL)
644*e4b17023SJohn Marino     {
645*e4b17023SJohn Marino       if (c1->first == NULL)
646*e4b17023SJohn Marino 	c1->first = c2->first;
647*e4b17023SJohn Marino       else
648*e4b17023SJohn Marino 	c1->last->next_use = c2->first;
649*e4b17023SJohn Marino       c1->last = c2->last;
650*e4b17023SJohn Marino     }
651*e4b17023SJohn Marino 
652*e4b17023SJohn Marino   c2->first = c2->last = NULL;
653*e4b17023SJohn Marino   c2->id = c1->id;
654*e4b17023SJohn Marino 
655*e4b17023SJohn Marino   IOR_HARD_REG_SET (c1->hard_conflicts, c2->hard_conflicts);
656*e4b17023SJohn Marino   bitmap_ior_into (&c1->conflicts, &c2->conflicts);
657*e4b17023SJohn Marino 
658*e4b17023SJohn Marino   c1->need_caller_save_reg |= c2->need_caller_save_reg;
659*e4b17023SJohn Marino   c1->cannot_rename |= c2->cannot_rename;
660*e4b17023SJohn Marino }
661*e4b17023SJohn Marino 
662*e4b17023SJohn Marino /* Analyze the current function and build chains for renaming.  */
663*e4b17023SJohn Marino 
664*e4b17023SJohn Marino void
regrename_analyze(bitmap bb_mask)665*e4b17023SJohn Marino regrename_analyze (bitmap bb_mask)
666*e4b17023SJohn Marino {
667*e4b17023SJohn Marino   struct bb_rename_info *rename_info;
668*e4b17023SJohn Marino   int i;
669*e4b17023SJohn Marino   basic_block bb;
670*e4b17023SJohn Marino   int n_bbs;
671*e4b17023SJohn Marino   int *inverse_postorder;
672*e4b17023SJohn Marino 
673*e4b17023SJohn Marino   inverse_postorder = XNEWVEC (int, last_basic_block);
674*e4b17023SJohn Marino   n_bbs = pre_and_rev_post_order_compute (NULL, inverse_postorder, false);
675*e4b17023SJohn Marino 
676*e4b17023SJohn Marino   /* Gather some information about the blocks in this function.  */
677*e4b17023SJohn Marino   rename_info = XCNEWVEC (struct bb_rename_info, n_basic_blocks);
678*e4b17023SJohn Marino   i = 0;
679*e4b17023SJohn Marino   FOR_EACH_BB (bb)
680*e4b17023SJohn Marino     {
681*e4b17023SJohn Marino       struct bb_rename_info *ri = rename_info + i;
682*e4b17023SJohn Marino       ri->bb = bb;
683*e4b17023SJohn Marino       if (bb_mask != NULL && !bitmap_bit_p (bb_mask, bb->index))
684*e4b17023SJohn Marino 	bb->aux = NULL;
685*e4b17023SJohn Marino       else
686*e4b17023SJohn Marino 	bb->aux = ri;
687*e4b17023SJohn Marino       i++;
688*e4b17023SJohn Marino     }
689*e4b17023SJohn Marino 
690*e4b17023SJohn Marino   current_id = 0;
691*e4b17023SJohn Marino   id_to_chain = VEC_alloc (du_head_p, heap, 0);
692*e4b17023SJohn Marino   bitmap_initialize (&open_chains_set, &bitmap_default_obstack);
693*e4b17023SJohn Marino 
694*e4b17023SJohn Marino   /* The order in which we visit blocks ensures that whenever
695*e4b17023SJohn Marino      possible, we only process a block after at least one of its
696*e4b17023SJohn Marino      predecessors, which provides a "seeding" effect to make the logic
697*e4b17023SJohn Marino      in set_incoming_from_chain and init_rename_info useful.  */
698*e4b17023SJohn Marino 
699*e4b17023SJohn Marino   for (i = 0; i < n_bbs; i++)
700*e4b17023SJohn Marino     {
701*e4b17023SJohn Marino       basic_block bb1 = BASIC_BLOCK (inverse_postorder[i]);
702*e4b17023SJohn Marino       struct bb_rename_info *this_info;
703*e4b17023SJohn Marino       bool success;
704*e4b17023SJohn Marino       edge e;
705*e4b17023SJohn Marino       edge_iterator ei;
706*e4b17023SJohn Marino       int old_length = VEC_length (du_head_p, id_to_chain);
707*e4b17023SJohn Marino 
708*e4b17023SJohn Marino       this_info = (struct bb_rename_info *) bb1->aux;
709*e4b17023SJohn Marino       if (this_info == NULL)
710*e4b17023SJohn Marino 	continue;
711*e4b17023SJohn Marino 
712*e4b17023SJohn Marino       if (dump_file)
713*e4b17023SJohn Marino 	fprintf (dump_file, "\nprocessing block %d:\n", bb1->index);
714*e4b17023SJohn Marino 
715*e4b17023SJohn Marino       init_rename_info (this_info, bb1);
716*e4b17023SJohn Marino 
717*e4b17023SJohn Marino       success = build_def_use (bb1);
718*e4b17023SJohn Marino       if (!success)
719*e4b17023SJohn Marino 	{
720*e4b17023SJohn Marino 	  if (dump_file)
721*e4b17023SJohn Marino 	    fprintf (dump_file, "failed\n");
722*e4b17023SJohn Marino 	  bb1->aux = NULL;
723*e4b17023SJohn Marino 	  VEC_truncate (du_head_p, id_to_chain, old_length);
724*e4b17023SJohn Marino 	  current_id = old_length;
725*e4b17023SJohn Marino 	  bitmap_clear (&this_info->incoming_open_chains_set);
726*e4b17023SJohn Marino 	  open_chains = NULL;
727*e4b17023SJohn Marino 	  if (insn_rr != NULL)
728*e4b17023SJohn Marino 	    {
729*e4b17023SJohn Marino 	      rtx insn;
730*e4b17023SJohn Marino 	      FOR_BB_INSNS (bb1, insn)
731*e4b17023SJohn Marino 		{
732*e4b17023SJohn Marino 		  insn_rr_info *p = VEC_index (insn_rr_info, insn_rr,
733*e4b17023SJohn Marino 					       INSN_UID (insn));
734*e4b17023SJohn Marino 		  p->op_info = NULL;
735*e4b17023SJohn Marino 		}
736*e4b17023SJohn Marino 	    }
737*e4b17023SJohn Marino 	  continue;
738*e4b17023SJohn Marino 	}
739*e4b17023SJohn Marino 
740*e4b17023SJohn Marino       if (dump_file)
741*e4b17023SJohn Marino 	dump_def_use_chain (old_length);
742*e4b17023SJohn Marino       bitmap_copy (&this_info->open_chains_set, &open_chains_set);
743*e4b17023SJohn Marino 
744*e4b17023SJohn Marino       /* Add successor blocks to the worklist if necessary, and record
745*e4b17023SJohn Marino 	 data about our own open chains at the end of this block, which
746*e4b17023SJohn Marino 	 will be used to pre-open chains when processing the successors.  */
747*e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, bb1->succs)
748*e4b17023SJohn Marino 	{
749*e4b17023SJohn Marino 	  struct bb_rename_info *dest_ri;
750*e4b17023SJohn Marino 	  struct du_head *chain;
751*e4b17023SJohn Marino 
752*e4b17023SJohn Marino 	  if (dump_file)
753*e4b17023SJohn Marino 	    fprintf (dump_file, "successor block %d\n", e->dest->index);
754*e4b17023SJohn Marino 
755*e4b17023SJohn Marino 	  if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
756*e4b17023SJohn Marino 	    continue;
757*e4b17023SJohn Marino 	  dest_ri = (struct bb_rename_info *)e->dest->aux;
758*e4b17023SJohn Marino 	  if (dest_ri == NULL)
759*e4b17023SJohn Marino 	    continue;
760*e4b17023SJohn Marino 	  for (chain = open_chains; chain; chain = chain->next_chain)
761*e4b17023SJohn Marino 	    set_incoming_from_chain (dest_ri, chain);
762*e4b17023SJohn Marino 	}
763*e4b17023SJohn Marino     }
764*e4b17023SJohn Marino 
765*e4b17023SJohn Marino   free (inverse_postorder);
766*e4b17023SJohn Marino 
767*e4b17023SJohn Marino   /* Now, combine the chains data we have gathered across basic block
768*e4b17023SJohn Marino      boundaries.
769*e4b17023SJohn Marino 
770*e4b17023SJohn Marino      For every basic block, there may be chains open at the start, or at the
771*e4b17023SJohn Marino      end.  Rather than exclude them from renaming, we look for open chains
772*e4b17023SJohn Marino      with matching registers at the other side of the CFG edge.
773*e4b17023SJohn Marino 
774*e4b17023SJohn Marino      For a given chain using register R, open at the start of block B, we
775*e4b17023SJohn Marino      must find an open chain using R on the other side of every edge leading
776*e4b17023SJohn Marino      to B, if the register is live across this edge.  In the code below,
777*e4b17023SJohn Marino      N_PREDS_USED counts the number of edges where the register is live, and
778*e4b17023SJohn Marino      N_PREDS_JOINED counts those where we found an appropriate chain for
779*e4b17023SJohn Marino      joining.
780*e4b17023SJohn Marino 
781*e4b17023SJohn Marino      We perform the analysis for both incoming and outgoing edges, but we
782*e4b17023SJohn Marino      only need to merge once (in the second part, after verifying outgoing
783*e4b17023SJohn Marino      edges).  */
784*e4b17023SJohn Marino   FOR_EACH_BB (bb)
785*e4b17023SJohn Marino     {
786*e4b17023SJohn Marino       struct bb_rename_info *bb_ri = (struct bb_rename_info *) bb->aux;
787*e4b17023SJohn Marino       unsigned j;
788*e4b17023SJohn Marino       bitmap_iterator bi;
789*e4b17023SJohn Marino 
790*e4b17023SJohn Marino       if (bb_ri == NULL)
791*e4b17023SJohn Marino 	continue;
792*e4b17023SJohn Marino 
793*e4b17023SJohn Marino       if (dump_file)
794*e4b17023SJohn Marino 	fprintf (dump_file, "processing bb %d in edges\n", bb->index);
795*e4b17023SJohn Marino 
796*e4b17023SJohn Marino       EXECUTE_IF_SET_IN_BITMAP (&bb_ri->incoming_open_chains_set, 0, j, bi)
797*e4b17023SJohn Marino 	{
798*e4b17023SJohn Marino 	  edge e;
799*e4b17023SJohn Marino 	  edge_iterator ei;
800*e4b17023SJohn Marino 	  struct du_head *chain = regrename_chain_from_id (j);
801*e4b17023SJohn Marino 	  int n_preds_used = 0, n_preds_joined = 0;
802*e4b17023SJohn Marino 
803*e4b17023SJohn Marino 	  FOR_EACH_EDGE (e, ei, bb->preds)
804*e4b17023SJohn Marino 	    {
805*e4b17023SJohn Marino 	      struct bb_rename_info *src_ri;
806*e4b17023SJohn Marino 	      unsigned k;
807*e4b17023SJohn Marino 	      bitmap_iterator bi2;
808*e4b17023SJohn Marino 	      HARD_REG_SET live;
809*e4b17023SJohn Marino 	      bool success = false;
810*e4b17023SJohn Marino 
811*e4b17023SJohn Marino 	      REG_SET_TO_HARD_REG_SET (live, df_get_live_out (e->src));
812*e4b17023SJohn Marino 	      if (!range_overlaps_hard_reg_set_p (live, chain->regno,
813*e4b17023SJohn Marino 						  chain->nregs))
814*e4b17023SJohn Marino 		continue;
815*e4b17023SJohn Marino 	      n_preds_used++;
816*e4b17023SJohn Marino 
817*e4b17023SJohn Marino 	      if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
818*e4b17023SJohn Marino 		continue;
819*e4b17023SJohn Marino 
820*e4b17023SJohn Marino 	      src_ri = (struct bb_rename_info *)e->src->aux;
821*e4b17023SJohn Marino 	      if (src_ri == NULL)
822*e4b17023SJohn Marino 		continue;
823*e4b17023SJohn Marino 
824*e4b17023SJohn Marino 	      EXECUTE_IF_SET_IN_BITMAP (&src_ri->open_chains_set,
825*e4b17023SJohn Marino 					0, k, bi2)
826*e4b17023SJohn Marino 		{
827*e4b17023SJohn Marino 		  struct du_head *outgoing_chain = regrename_chain_from_id (k);
828*e4b17023SJohn Marino 
829*e4b17023SJohn Marino 		  if (outgoing_chain->regno == chain->regno
830*e4b17023SJohn Marino 		      && outgoing_chain->nregs == chain->nregs)
831*e4b17023SJohn Marino 		    {
832*e4b17023SJohn Marino 		      n_preds_joined++;
833*e4b17023SJohn Marino 		      success = true;
834*e4b17023SJohn Marino 		      break;
835*e4b17023SJohn Marino 		    }
836*e4b17023SJohn Marino 		}
837*e4b17023SJohn Marino 	      if (!success && dump_file)
838*e4b17023SJohn Marino 		fprintf (dump_file, "failure to match with pred block %d\n",
839*e4b17023SJohn Marino 			 e->src->index);
840*e4b17023SJohn Marino 	    }
841*e4b17023SJohn Marino 	  if (n_preds_joined < n_preds_used)
842*e4b17023SJohn Marino 	    {
843*e4b17023SJohn Marino 	      if (dump_file)
844*e4b17023SJohn Marino 		fprintf (dump_file, "cannot rename chain %d\n", j);
845*e4b17023SJohn Marino 	      chain->cannot_rename = 1;
846*e4b17023SJohn Marino 	    }
847*e4b17023SJohn Marino 	}
848*e4b17023SJohn Marino     }
849*e4b17023SJohn Marino   FOR_EACH_BB (bb)
850*e4b17023SJohn Marino     {
851*e4b17023SJohn Marino       struct bb_rename_info *bb_ri = (struct bb_rename_info *) bb->aux;
852*e4b17023SJohn Marino       unsigned j;
853*e4b17023SJohn Marino       bitmap_iterator bi;
854*e4b17023SJohn Marino 
855*e4b17023SJohn Marino       if (bb_ri == NULL)
856*e4b17023SJohn Marino 	continue;
857*e4b17023SJohn Marino 
858*e4b17023SJohn Marino       if (dump_file)
859*e4b17023SJohn Marino 	fprintf (dump_file, "processing bb %d out edges\n", bb->index);
860*e4b17023SJohn Marino 
861*e4b17023SJohn Marino       EXECUTE_IF_SET_IN_BITMAP (&bb_ri->open_chains_set, 0, j, bi)
862*e4b17023SJohn Marino 	{
863*e4b17023SJohn Marino 	  edge e;
864*e4b17023SJohn Marino 	  edge_iterator ei;
865*e4b17023SJohn Marino 	  struct du_head *chain = regrename_chain_from_id (j);
866*e4b17023SJohn Marino 	  int n_succs_used = 0, n_succs_joined = 0;
867*e4b17023SJohn Marino 
868*e4b17023SJohn Marino 	  FOR_EACH_EDGE (e, ei, bb->succs)
869*e4b17023SJohn Marino 	    {
870*e4b17023SJohn Marino 	      bool printed = false;
871*e4b17023SJohn Marino 	      struct bb_rename_info *dest_ri;
872*e4b17023SJohn Marino 	      unsigned k;
873*e4b17023SJohn Marino 	      bitmap_iterator bi2;
874*e4b17023SJohn Marino 	      HARD_REG_SET live;
875*e4b17023SJohn Marino 
876*e4b17023SJohn Marino 	      REG_SET_TO_HARD_REG_SET (live, df_get_live_in (e->dest));
877*e4b17023SJohn Marino 	      if (!range_overlaps_hard_reg_set_p (live, chain->regno,
878*e4b17023SJohn Marino 						  chain->nregs))
879*e4b17023SJohn Marino 		continue;
880*e4b17023SJohn Marino 
881*e4b17023SJohn Marino 	      n_succs_used++;
882*e4b17023SJohn Marino 
883*e4b17023SJohn Marino 	      dest_ri = (struct bb_rename_info *)e->dest->aux;
884*e4b17023SJohn Marino 	      if (dest_ri == NULL)
885*e4b17023SJohn Marino 		continue;
886*e4b17023SJohn Marino 
887*e4b17023SJohn Marino 	      EXECUTE_IF_SET_IN_BITMAP (&dest_ri->incoming_open_chains_set,
888*e4b17023SJohn Marino 					0, k, bi2)
889*e4b17023SJohn Marino 		{
890*e4b17023SJohn Marino 		  struct du_head *incoming_chain = regrename_chain_from_id (k);
891*e4b17023SJohn Marino 
892*e4b17023SJohn Marino 		  if (incoming_chain->regno == chain->regno
893*e4b17023SJohn Marino 		      && incoming_chain->nregs == chain->nregs)
894*e4b17023SJohn Marino 		    {
895*e4b17023SJohn Marino 		      if (dump_file)
896*e4b17023SJohn Marino 			{
897*e4b17023SJohn Marino 			  if (!printed)
898*e4b17023SJohn Marino 			    fprintf (dump_file,
899*e4b17023SJohn Marino 				     "merging blocks for edge %d -> %d\n",
900*e4b17023SJohn Marino 				     e->src->index, e->dest->index);
901*e4b17023SJohn Marino 			  printed = true;
902*e4b17023SJohn Marino 			  fprintf (dump_file,
903*e4b17023SJohn Marino 				   "  merging chains %d (->%d) and %d (->%d) [%s]\n",
904*e4b17023SJohn Marino 				   k, incoming_chain->id, j, chain->id,
905*e4b17023SJohn Marino 				   reg_names[incoming_chain->regno]);
906*e4b17023SJohn Marino 			}
907*e4b17023SJohn Marino 
908*e4b17023SJohn Marino 		      merge_chains (chain, incoming_chain);
909*e4b17023SJohn Marino 		      n_succs_joined++;
910*e4b17023SJohn Marino 		      break;
911*e4b17023SJohn Marino 		    }
912*e4b17023SJohn Marino 		}
913*e4b17023SJohn Marino 	    }
914*e4b17023SJohn Marino 	  if (n_succs_joined < n_succs_used)
915*e4b17023SJohn Marino 	    {
916*e4b17023SJohn Marino 	      if (dump_file)
917*e4b17023SJohn Marino 		fprintf (dump_file, "cannot rename chain %d\n",
918*e4b17023SJohn Marino 			 j);
919*e4b17023SJohn Marino 	      chain->cannot_rename = 1;
920*e4b17023SJohn Marino 	    }
921*e4b17023SJohn Marino 	}
922*e4b17023SJohn Marino     }
923*e4b17023SJohn Marino 
924*e4b17023SJohn Marino   free (rename_info);
925*e4b17023SJohn Marino 
926*e4b17023SJohn Marino   FOR_EACH_BB (bb)
927*e4b17023SJohn Marino     bb->aux = NULL;
928*e4b17023SJohn Marino }
929*e4b17023SJohn Marino 
930*e4b17023SJohn Marino void
regrename_do_replace(struct du_head * head,int reg)931*e4b17023SJohn Marino regrename_do_replace (struct du_head *head, int reg)
932*e4b17023SJohn Marino {
933*e4b17023SJohn Marino   struct du_chain *chain;
934*e4b17023SJohn Marino   unsigned int base_regno = head->regno;
935*e4b17023SJohn Marino   enum machine_mode mode;
936*e4b17023SJohn Marino 
937*e4b17023SJohn Marino   for (chain = head->first; chain; chain = chain->next_use)
938*e4b17023SJohn Marino     {
939*e4b17023SJohn Marino       unsigned int regno = ORIGINAL_REGNO (*chain->loc);
940*e4b17023SJohn Marino       struct reg_attrs *attr = REG_ATTRS (*chain->loc);
941*e4b17023SJohn Marino       int reg_ptr = REG_POINTER (*chain->loc);
942*e4b17023SJohn Marino 
943*e4b17023SJohn Marino       if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) != base_regno)
944*e4b17023SJohn Marino 	INSN_VAR_LOCATION_LOC (chain->insn) = gen_rtx_UNKNOWN_VAR_LOC ();
945*e4b17023SJohn Marino       else
946*e4b17023SJohn Marino 	{
947*e4b17023SJohn Marino 	  *chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg);
948*e4b17023SJohn Marino 	  if (regno >= FIRST_PSEUDO_REGISTER)
949*e4b17023SJohn Marino 	    ORIGINAL_REGNO (*chain->loc) = regno;
950*e4b17023SJohn Marino 	  REG_ATTRS (*chain->loc) = attr;
951*e4b17023SJohn Marino 	  REG_POINTER (*chain->loc) = reg_ptr;
952*e4b17023SJohn Marino 	}
953*e4b17023SJohn Marino 
954*e4b17023SJohn Marino       df_insn_rescan (chain->insn);
955*e4b17023SJohn Marino     }
956*e4b17023SJohn Marino 
957*e4b17023SJohn Marino   mode = GET_MODE (*head->first->loc);
958*e4b17023SJohn Marino   head->regno = reg;
959*e4b17023SJohn Marino   head->nregs = hard_regno_nregs[reg][mode];
960*e4b17023SJohn Marino }
961*e4b17023SJohn Marino 
962*e4b17023SJohn Marino 
963*e4b17023SJohn Marino /* True if we found a register with a size mismatch, which means that we
964*e4b17023SJohn Marino    can't track its lifetime accurately.  If so, we abort the current block
965*e4b17023SJohn Marino    without renaming.  */
966*e4b17023SJohn Marino static bool fail_current_block;
967*e4b17023SJohn Marino 
968*e4b17023SJohn Marino /* Return true if OP is a reg for which all bits are set in PSET, false
969*e4b17023SJohn Marino    if all bits are clear.
970*e4b17023SJohn Marino    In other cases, set fail_current_block and return false.  */
971*e4b17023SJohn Marino 
972*e4b17023SJohn Marino static bool
verify_reg_in_set(rtx op,HARD_REG_SET * pset)973*e4b17023SJohn Marino verify_reg_in_set (rtx op, HARD_REG_SET *pset)
974*e4b17023SJohn Marino {
975*e4b17023SJohn Marino   unsigned regno, nregs;
976*e4b17023SJohn Marino   bool all_live, all_dead;
977*e4b17023SJohn Marino   if (!REG_P (op))
978*e4b17023SJohn Marino     return false;
979*e4b17023SJohn Marino 
980*e4b17023SJohn Marino   regno = REGNO (op);
981*e4b17023SJohn Marino   nregs = hard_regno_nregs[regno][GET_MODE (op)];
982*e4b17023SJohn Marino   all_live = all_dead = true;
983*e4b17023SJohn Marino   while (nregs-- > 0)
984*e4b17023SJohn Marino     if (TEST_HARD_REG_BIT (*pset, regno + nregs))
985*e4b17023SJohn Marino       all_dead = false;
986*e4b17023SJohn Marino     else
987*e4b17023SJohn Marino       all_live = false;
988*e4b17023SJohn Marino   if (!all_dead && !all_live)
989*e4b17023SJohn Marino     {
990*e4b17023SJohn Marino       fail_current_block = true;
991*e4b17023SJohn Marino       return false;
992*e4b17023SJohn Marino     }
993*e4b17023SJohn Marino   return all_live;
994*e4b17023SJohn Marino }
995*e4b17023SJohn Marino 
996*e4b17023SJohn Marino /* Return true if OP is a reg that is being tracked already in some form.
997*e4b17023SJohn Marino    May set fail_current_block if it sees an unhandled case of overlap.  */
998*e4b17023SJohn Marino 
999*e4b17023SJohn Marino static bool
verify_reg_tracked(rtx op)1000*e4b17023SJohn Marino verify_reg_tracked (rtx op)
1001*e4b17023SJohn Marino {
1002*e4b17023SJohn Marino   return (verify_reg_in_set (op, &live_hard_regs)
1003*e4b17023SJohn Marino 	  || verify_reg_in_set (op, &live_in_chains));
1004*e4b17023SJohn Marino }
1005*e4b17023SJohn Marino 
1006*e4b17023SJohn Marino /* Called through note_stores.  DATA points to a rtx_code, either SET or
1007*e4b17023SJohn Marino    CLOBBER, which tells us which kind of rtx to look at.  If we have a
1008*e4b17023SJohn Marino    match, record the set register in live_hard_regs and in the hard_conflicts
1009*e4b17023SJohn Marino    bitmap of open chains.  */
1010*e4b17023SJohn Marino 
1011*e4b17023SJohn Marino static void
note_sets_clobbers(rtx x,const_rtx set,void * data)1012*e4b17023SJohn Marino note_sets_clobbers (rtx x, const_rtx set, void *data)
1013*e4b17023SJohn Marino {
1014*e4b17023SJohn Marino   enum rtx_code code = *(enum rtx_code *)data;
1015*e4b17023SJohn Marino   struct du_head *chain;
1016*e4b17023SJohn Marino 
1017*e4b17023SJohn Marino   if (GET_CODE (x) == SUBREG)
1018*e4b17023SJohn Marino     x = SUBREG_REG (x);
1019*e4b17023SJohn Marino   if (!REG_P (x) || GET_CODE (set) != code)
1020*e4b17023SJohn Marino     return;
1021*e4b17023SJohn Marino   /* There must not be pseudos at this point.  */
1022*e4b17023SJohn Marino   gcc_assert (HARD_REGISTER_P (x));
1023*e4b17023SJohn Marino   add_to_hard_reg_set (&live_hard_regs, GET_MODE (x), REGNO (x));
1024*e4b17023SJohn Marino   for (chain = open_chains; chain; chain = chain->next_chain)
1025*e4b17023SJohn Marino     add_to_hard_reg_set (&chain->hard_conflicts, GET_MODE (x), REGNO (x));
1026*e4b17023SJohn Marino }
1027*e4b17023SJohn Marino 
1028*e4b17023SJohn Marino static void
scan_rtx_reg(rtx insn,rtx * loc,enum reg_class cl,enum scan_actions action,enum op_type type)1029*e4b17023SJohn Marino scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl, enum scan_actions action,
1030*e4b17023SJohn Marino 	      enum op_type type)
1031*e4b17023SJohn Marino {
1032*e4b17023SJohn Marino   struct du_head **p;
1033*e4b17023SJohn Marino   rtx x = *loc;
1034*e4b17023SJohn Marino   enum machine_mode mode = GET_MODE (x);
1035*e4b17023SJohn Marino   unsigned this_regno = REGNO (x);
1036*e4b17023SJohn Marino   int this_nregs = hard_regno_nregs[this_regno][mode];
1037*e4b17023SJohn Marino 
1038*e4b17023SJohn Marino   if (action == mark_write)
1039*e4b17023SJohn Marino     {
1040*e4b17023SJohn Marino       if (type == OP_OUT)
1041*e4b17023SJohn Marino 	create_new_chain (this_regno, this_nregs, loc, insn, cl);
1042*e4b17023SJohn Marino       return;
1043*e4b17023SJohn Marino     }
1044*e4b17023SJohn Marino 
1045*e4b17023SJohn Marino   if ((type == OP_OUT) != (action == terminate_write || action == mark_access))
1046*e4b17023SJohn Marino     return;
1047*e4b17023SJohn Marino 
1048*e4b17023SJohn Marino   for (p = &open_chains; *p;)
1049*e4b17023SJohn Marino     {
1050*e4b17023SJohn Marino       struct du_head *head = *p;
1051*e4b17023SJohn Marino       struct du_head *next = head->next_chain;
1052*e4b17023SJohn Marino       int exact_match = (head->regno == this_regno
1053*e4b17023SJohn Marino 			 && head->nregs == this_nregs);
1054*e4b17023SJohn Marino       int superset = (this_regno <= head->regno
1055*e4b17023SJohn Marino 		      && this_regno + this_nregs >= head->regno + head->nregs);
1056*e4b17023SJohn Marino       int subset = (this_regno >= head->regno
1057*e4b17023SJohn Marino 		      && this_regno + this_nregs <= head->regno + head->nregs);
1058*e4b17023SJohn Marino 
1059*e4b17023SJohn Marino       if (!bitmap_bit_p (&open_chains_set, head->id)
1060*e4b17023SJohn Marino 	  || head->regno + head->nregs <= this_regno
1061*e4b17023SJohn Marino 	  || this_regno + this_nregs <= head->regno)
1062*e4b17023SJohn Marino 	{
1063*e4b17023SJohn Marino 	  p = &head->next_chain;
1064*e4b17023SJohn Marino 	  continue;
1065*e4b17023SJohn Marino 	}
1066*e4b17023SJohn Marino 
1067*e4b17023SJohn Marino       if (action == mark_read || action == mark_access)
1068*e4b17023SJohn Marino 	{
1069*e4b17023SJohn Marino 	  /* ??? Class NO_REGS can happen if the md file makes use of
1070*e4b17023SJohn Marino 	     EXTRA_CONSTRAINTS to match registers.  Which is arguably
1071*e4b17023SJohn Marino 	     wrong, but there we are.  */
1072*e4b17023SJohn Marino 
1073*e4b17023SJohn Marino 	  if (cl == NO_REGS || (!exact_match && !DEBUG_INSN_P (insn)))
1074*e4b17023SJohn Marino 	    {
1075*e4b17023SJohn Marino 	      if (dump_file)
1076*e4b17023SJohn Marino 		fprintf (dump_file,
1077*e4b17023SJohn Marino 			 "Cannot rename chain %s (%d) at insn %d (%s)\n",
1078*e4b17023SJohn Marino 			 reg_names[head->regno], head->id, INSN_UID (insn),
1079*e4b17023SJohn Marino 			 scan_actions_name[(int) action]);
1080*e4b17023SJohn Marino 	      head->cannot_rename = 1;
1081*e4b17023SJohn Marino 	      if (superset)
1082*e4b17023SJohn Marino 		{
1083*e4b17023SJohn Marino 		  unsigned nregs = this_nregs;
1084*e4b17023SJohn Marino 		  head->regno = this_regno;
1085*e4b17023SJohn Marino 		  head->nregs = this_nregs;
1086*e4b17023SJohn Marino 		  while (nregs-- > 0)
1087*e4b17023SJohn Marino 		    SET_HARD_REG_BIT (live_in_chains, head->regno + nregs);
1088*e4b17023SJohn Marino 		  if (dump_file)
1089*e4b17023SJohn Marino 		    fprintf (dump_file,
1090*e4b17023SJohn Marino 			     "Widening register in chain %s (%d) at insn %d\n",
1091*e4b17023SJohn Marino 			     reg_names[head->regno], head->id, INSN_UID (insn));
1092*e4b17023SJohn Marino 		}
1093*e4b17023SJohn Marino 	      else if (!subset)
1094*e4b17023SJohn Marino 		{
1095*e4b17023SJohn Marino 		  fail_current_block = true;
1096*e4b17023SJohn Marino 		  if (dump_file)
1097*e4b17023SJohn Marino 		    fprintf (dump_file,
1098*e4b17023SJohn Marino 			     "Failing basic block due to unhandled overlap\n");
1099*e4b17023SJohn Marino 		}
1100*e4b17023SJohn Marino 	    }
1101*e4b17023SJohn Marino 	  else
1102*e4b17023SJohn Marino 	    {
1103*e4b17023SJohn Marino 	      struct du_chain *this_du;
1104*e4b17023SJohn Marino 	      this_du = XOBNEW (&rename_obstack, struct du_chain);
1105*e4b17023SJohn Marino 	      this_du->next_use = 0;
1106*e4b17023SJohn Marino 	      this_du->loc = loc;
1107*e4b17023SJohn Marino 	      this_du->insn = insn;
1108*e4b17023SJohn Marino 	      this_du->cl = cl;
1109*e4b17023SJohn Marino 	      if (head->first == NULL)
1110*e4b17023SJohn Marino 		head->first = this_du;
1111*e4b17023SJohn Marino 	      else
1112*e4b17023SJohn Marino 		head->last->next_use = this_du;
1113*e4b17023SJohn Marino 	      record_operand_use (head, this_du);
1114*e4b17023SJohn Marino 	      head->last = this_du;
1115*e4b17023SJohn Marino 	    }
1116*e4b17023SJohn Marino 	  /* Avoid adding the same location in a DEBUG_INSN multiple times,
1117*e4b17023SJohn Marino 	     which could happen with non-exact overlap.  */
1118*e4b17023SJohn Marino 	  if (DEBUG_INSN_P (insn))
1119*e4b17023SJohn Marino 	    return;
1120*e4b17023SJohn Marino 	  /* Otherwise, find any other chains that do not match exactly;
1121*e4b17023SJohn Marino 	     ensure they all get marked unrenamable.  */
1122*e4b17023SJohn Marino 	  p = &head->next_chain;
1123*e4b17023SJohn Marino 	  continue;
1124*e4b17023SJohn Marino 	}
1125*e4b17023SJohn Marino 
1126*e4b17023SJohn Marino       /* Whether the terminated chain can be used for renaming
1127*e4b17023SJohn Marino 	 depends on the action and this being an exact match.
1128*e4b17023SJohn Marino 	 In either case, we remove this element from open_chains.  */
1129*e4b17023SJohn Marino 
1130*e4b17023SJohn Marino       if ((action == terminate_dead || action == terminate_write)
1131*e4b17023SJohn Marino 	  && (superset || subset))
1132*e4b17023SJohn Marino 	{
1133*e4b17023SJohn Marino 	  unsigned nregs;
1134*e4b17023SJohn Marino 
1135*e4b17023SJohn Marino 	  if (subset && !superset)
1136*e4b17023SJohn Marino 	    head->cannot_rename = 1;
1137*e4b17023SJohn Marino 	  bitmap_clear_bit (&open_chains_set, head->id);
1138*e4b17023SJohn Marino 
1139*e4b17023SJohn Marino 	  nregs = head->nregs;
1140*e4b17023SJohn Marino 	  while (nregs-- > 0)
1141*e4b17023SJohn Marino 	    {
1142*e4b17023SJohn Marino 	      CLEAR_HARD_REG_BIT (live_in_chains, head->regno + nregs);
1143*e4b17023SJohn Marino 	      if (subset && !superset
1144*e4b17023SJohn Marino 		  && (head->regno + nregs < this_regno
1145*e4b17023SJohn Marino 		      || head->regno + nregs >= this_regno + this_nregs))
1146*e4b17023SJohn Marino 		SET_HARD_REG_BIT (live_hard_regs, head->regno + nregs);
1147*e4b17023SJohn Marino 	    }
1148*e4b17023SJohn Marino 
1149*e4b17023SJohn Marino 	  *p = next;
1150*e4b17023SJohn Marino 	  if (dump_file)
1151*e4b17023SJohn Marino 	    fprintf (dump_file,
1152*e4b17023SJohn Marino 		     "Closing chain %s (%d) at insn %d (%s%s)\n",
1153*e4b17023SJohn Marino 		     reg_names[head->regno], head->id, INSN_UID (insn),
1154*e4b17023SJohn Marino 		     scan_actions_name[(int) action],
1155*e4b17023SJohn Marino 		     superset ? ", superset" : subset ? ", subset" : "");
1156*e4b17023SJohn Marino 	}
1157*e4b17023SJohn Marino       else if (action == terminate_dead || action == terminate_write)
1158*e4b17023SJohn Marino 	{
1159*e4b17023SJohn Marino 	  /* In this case, tracking liveness gets too hard.  Fail the
1160*e4b17023SJohn Marino 	     entire basic block.  */
1161*e4b17023SJohn Marino 	  if (dump_file)
1162*e4b17023SJohn Marino 	    fprintf (dump_file,
1163*e4b17023SJohn Marino 		     "Failing basic block due to unhandled overlap\n");
1164*e4b17023SJohn Marino 	  fail_current_block = true;
1165*e4b17023SJohn Marino 	  return;
1166*e4b17023SJohn Marino 	}
1167*e4b17023SJohn Marino       else
1168*e4b17023SJohn Marino 	{
1169*e4b17023SJohn Marino 	  head->cannot_rename = 1;
1170*e4b17023SJohn Marino 	  if (dump_file)
1171*e4b17023SJohn Marino 	    fprintf (dump_file,
1172*e4b17023SJohn Marino 		     "Cannot rename chain %s (%d) at insn %d (%s)\n",
1173*e4b17023SJohn Marino 		     reg_names[head->regno], head->id, INSN_UID (insn),
1174*e4b17023SJohn Marino 		     scan_actions_name[(int) action]);
1175*e4b17023SJohn Marino 	  p = &head->next_chain;
1176*e4b17023SJohn Marino 	}
1177*e4b17023SJohn Marino     }
1178*e4b17023SJohn Marino }
1179*e4b17023SJohn Marino 
1180*e4b17023SJohn Marino /* Adapted from find_reloads_address_1.  CL is INDEX_REG_CLASS or
1181*e4b17023SJohn Marino    BASE_REG_CLASS depending on how the register is being considered.  */
1182*e4b17023SJohn Marino 
1183*e4b17023SJohn Marino static void
scan_rtx_address(rtx insn,rtx * loc,enum reg_class cl,enum scan_actions action,enum machine_mode mode,addr_space_t as)1184*e4b17023SJohn Marino scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl,
1185*e4b17023SJohn Marino 		  enum scan_actions action, enum machine_mode mode,
1186*e4b17023SJohn Marino 		  addr_space_t as)
1187*e4b17023SJohn Marino {
1188*e4b17023SJohn Marino   rtx x = *loc;
1189*e4b17023SJohn Marino   RTX_CODE code = GET_CODE (x);
1190*e4b17023SJohn Marino   const char *fmt;
1191*e4b17023SJohn Marino   int i, j;
1192*e4b17023SJohn Marino 
1193*e4b17023SJohn Marino   if (action == mark_write || action == mark_access)
1194*e4b17023SJohn Marino     return;
1195*e4b17023SJohn Marino 
1196*e4b17023SJohn Marino   switch (code)
1197*e4b17023SJohn Marino     {
1198*e4b17023SJohn Marino     case PLUS:
1199*e4b17023SJohn Marino       {
1200*e4b17023SJohn Marino 	rtx orig_op0 = XEXP (x, 0);
1201*e4b17023SJohn Marino 	rtx orig_op1 = XEXP (x, 1);
1202*e4b17023SJohn Marino 	RTX_CODE code0 = GET_CODE (orig_op0);
1203*e4b17023SJohn Marino 	RTX_CODE code1 = GET_CODE (orig_op1);
1204*e4b17023SJohn Marino 	rtx op0 = orig_op0;
1205*e4b17023SJohn Marino 	rtx op1 = orig_op1;
1206*e4b17023SJohn Marino 	rtx *locI = NULL;
1207*e4b17023SJohn Marino 	rtx *locB = NULL;
1208*e4b17023SJohn Marino 	enum rtx_code index_code = SCRATCH;
1209*e4b17023SJohn Marino 
1210*e4b17023SJohn Marino 	if (GET_CODE (op0) == SUBREG)
1211*e4b17023SJohn Marino 	  {
1212*e4b17023SJohn Marino 	    op0 = SUBREG_REG (op0);
1213*e4b17023SJohn Marino 	    code0 = GET_CODE (op0);
1214*e4b17023SJohn Marino 	  }
1215*e4b17023SJohn Marino 
1216*e4b17023SJohn Marino 	if (GET_CODE (op1) == SUBREG)
1217*e4b17023SJohn Marino 	  {
1218*e4b17023SJohn Marino 	    op1 = SUBREG_REG (op1);
1219*e4b17023SJohn Marino 	    code1 = GET_CODE (op1);
1220*e4b17023SJohn Marino 	  }
1221*e4b17023SJohn Marino 
1222*e4b17023SJohn Marino 	if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
1223*e4b17023SJohn Marino 	    || code0 == ZERO_EXTEND || code1 == MEM)
1224*e4b17023SJohn Marino 	  {
1225*e4b17023SJohn Marino 	    locI = &XEXP (x, 0);
1226*e4b17023SJohn Marino 	    locB = &XEXP (x, 1);
1227*e4b17023SJohn Marino 	    index_code = GET_CODE (*locI);
1228*e4b17023SJohn Marino 	  }
1229*e4b17023SJohn Marino 	else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
1230*e4b17023SJohn Marino 		 || code1 == ZERO_EXTEND || code0 == MEM)
1231*e4b17023SJohn Marino 	  {
1232*e4b17023SJohn Marino 	    locI = &XEXP (x, 1);
1233*e4b17023SJohn Marino 	    locB = &XEXP (x, 0);
1234*e4b17023SJohn Marino 	    index_code = GET_CODE (*locI);
1235*e4b17023SJohn Marino 	  }
1236*e4b17023SJohn Marino 	else if (code0 == CONST_INT || code0 == CONST
1237*e4b17023SJohn Marino 		 || code0 == SYMBOL_REF || code0 == LABEL_REF)
1238*e4b17023SJohn Marino 	  {
1239*e4b17023SJohn Marino 	    locB = &XEXP (x, 1);
1240*e4b17023SJohn Marino 	    index_code = GET_CODE (XEXP (x, 0));
1241*e4b17023SJohn Marino 	  }
1242*e4b17023SJohn Marino 	else if (code1 == CONST_INT || code1 == CONST
1243*e4b17023SJohn Marino 		 || code1 == SYMBOL_REF || code1 == LABEL_REF)
1244*e4b17023SJohn Marino 	  {
1245*e4b17023SJohn Marino 	    locB = &XEXP (x, 0);
1246*e4b17023SJohn Marino 	    index_code = GET_CODE (XEXP (x, 1));
1247*e4b17023SJohn Marino 	  }
1248*e4b17023SJohn Marino 	else if (code0 == REG && code1 == REG)
1249*e4b17023SJohn Marino 	  {
1250*e4b17023SJohn Marino 	    int index_op;
1251*e4b17023SJohn Marino 	    unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
1252*e4b17023SJohn Marino 
1253*e4b17023SJohn Marino 	    if (REGNO_OK_FOR_INDEX_P (regno1)
1254*e4b17023SJohn Marino 		&& regno_ok_for_base_p (regno0, mode, as, PLUS, REG))
1255*e4b17023SJohn Marino 	      index_op = 1;
1256*e4b17023SJohn Marino 	    else if (REGNO_OK_FOR_INDEX_P (regno0)
1257*e4b17023SJohn Marino 		     && regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
1258*e4b17023SJohn Marino 	      index_op = 0;
1259*e4b17023SJohn Marino 	    else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG)
1260*e4b17023SJohn Marino 		     || REGNO_OK_FOR_INDEX_P (regno1))
1261*e4b17023SJohn Marino 	      index_op = 1;
1262*e4b17023SJohn Marino 	    else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
1263*e4b17023SJohn Marino 	      index_op = 0;
1264*e4b17023SJohn Marino 	    else
1265*e4b17023SJohn Marino 	      index_op = 1;
1266*e4b17023SJohn Marino 
1267*e4b17023SJohn Marino 	    locI = &XEXP (x, index_op);
1268*e4b17023SJohn Marino 	    locB = &XEXP (x, !index_op);
1269*e4b17023SJohn Marino 	    index_code = GET_CODE (*locI);
1270*e4b17023SJohn Marino 	  }
1271*e4b17023SJohn Marino 	else if (code0 == REG)
1272*e4b17023SJohn Marino 	  {
1273*e4b17023SJohn Marino 	    locI = &XEXP (x, 0);
1274*e4b17023SJohn Marino 	    locB = &XEXP (x, 1);
1275*e4b17023SJohn Marino 	    index_code = GET_CODE (*locI);
1276*e4b17023SJohn Marino 	  }
1277*e4b17023SJohn Marino 	else if (code1 == REG)
1278*e4b17023SJohn Marino 	  {
1279*e4b17023SJohn Marino 	    locI = &XEXP (x, 1);
1280*e4b17023SJohn Marino 	    locB = &XEXP (x, 0);
1281*e4b17023SJohn Marino 	    index_code = GET_CODE (*locI);
1282*e4b17023SJohn Marino 	  }
1283*e4b17023SJohn Marino 
1284*e4b17023SJohn Marino 	if (locI)
1285*e4b17023SJohn Marino 	  scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode, as);
1286*e4b17023SJohn Marino 	if (locB)
1287*e4b17023SJohn Marino 	  scan_rtx_address (insn, locB,
1288*e4b17023SJohn Marino 			    base_reg_class (mode, as, PLUS, index_code),
1289*e4b17023SJohn Marino 			    action, mode, as);
1290*e4b17023SJohn Marino 
1291*e4b17023SJohn Marino 	return;
1292*e4b17023SJohn Marino       }
1293*e4b17023SJohn Marino 
1294*e4b17023SJohn Marino     case POST_INC:
1295*e4b17023SJohn Marino     case POST_DEC:
1296*e4b17023SJohn Marino     case POST_MODIFY:
1297*e4b17023SJohn Marino     case PRE_INC:
1298*e4b17023SJohn Marino     case PRE_DEC:
1299*e4b17023SJohn Marino     case PRE_MODIFY:
1300*e4b17023SJohn Marino #ifndef AUTO_INC_DEC
1301*e4b17023SJohn Marino       /* If the target doesn't claim to handle autoinc, this must be
1302*e4b17023SJohn Marino 	 something special, like a stack push.  Kill this chain.  */
1303*e4b17023SJohn Marino       action = mark_all_read;
1304*e4b17023SJohn Marino #endif
1305*e4b17023SJohn Marino       break;
1306*e4b17023SJohn Marino 
1307*e4b17023SJohn Marino     case MEM:
1308*e4b17023SJohn Marino       scan_rtx_address (insn, &XEXP (x, 0),
1309*e4b17023SJohn Marino 			base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x),
1310*e4b17023SJohn Marino 					MEM, SCRATCH),
1311*e4b17023SJohn Marino 			action, GET_MODE (x), MEM_ADDR_SPACE (x));
1312*e4b17023SJohn Marino       return;
1313*e4b17023SJohn Marino 
1314*e4b17023SJohn Marino     case REG:
1315*e4b17023SJohn Marino       scan_rtx_reg (insn, loc, cl, action, OP_IN);
1316*e4b17023SJohn Marino       return;
1317*e4b17023SJohn Marino 
1318*e4b17023SJohn Marino     default:
1319*e4b17023SJohn Marino       break;
1320*e4b17023SJohn Marino     }
1321*e4b17023SJohn Marino 
1322*e4b17023SJohn Marino   fmt = GET_RTX_FORMAT (code);
1323*e4b17023SJohn Marino   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1324*e4b17023SJohn Marino     {
1325*e4b17023SJohn Marino       if (fmt[i] == 'e')
1326*e4b17023SJohn Marino 	scan_rtx_address (insn, &XEXP (x, i), cl, action, mode, as);
1327*e4b17023SJohn Marino       else if (fmt[i] == 'E')
1328*e4b17023SJohn Marino 	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1329*e4b17023SJohn Marino 	  scan_rtx_address (insn, &XVECEXP (x, i, j), cl, action, mode, as);
1330*e4b17023SJohn Marino     }
1331*e4b17023SJohn Marino }
1332*e4b17023SJohn Marino 
1333*e4b17023SJohn Marino static void
scan_rtx(rtx insn,rtx * loc,enum reg_class cl,enum scan_actions action,enum op_type type)1334*e4b17023SJohn Marino scan_rtx (rtx insn, rtx *loc, enum reg_class cl, enum scan_actions action,
1335*e4b17023SJohn Marino 	  enum op_type type)
1336*e4b17023SJohn Marino {
1337*e4b17023SJohn Marino   const char *fmt;
1338*e4b17023SJohn Marino   rtx x = *loc;
1339*e4b17023SJohn Marino   enum rtx_code code = GET_CODE (x);
1340*e4b17023SJohn Marino   int i, j;
1341*e4b17023SJohn Marino 
1342*e4b17023SJohn Marino   code = GET_CODE (x);
1343*e4b17023SJohn Marino   switch (code)
1344*e4b17023SJohn Marino     {
1345*e4b17023SJohn Marino     case CONST:
1346*e4b17023SJohn Marino     case CONST_INT:
1347*e4b17023SJohn Marino     case CONST_DOUBLE:
1348*e4b17023SJohn Marino     case CONST_FIXED:
1349*e4b17023SJohn Marino     case CONST_VECTOR:
1350*e4b17023SJohn Marino     case SYMBOL_REF:
1351*e4b17023SJohn Marino     case LABEL_REF:
1352*e4b17023SJohn Marino     case CC0:
1353*e4b17023SJohn Marino     case PC:
1354*e4b17023SJohn Marino       return;
1355*e4b17023SJohn Marino 
1356*e4b17023SJohn Marino     case REG:
1357*e4b17023SJohn Marino       scan_rtx_reg (insn, loc, cl, action, type);
1358*e4b17023SJohn Marino       return;
1359*e4b17023SJohn Marino 
1360*e4b17023SJohn Marino     case MEM:
1361*e4b17023SJohn Marino       scan_rtx_address (insn, &XEXP (x, 0),
1362*e4b17023SJohn Marino 			base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x),
1363*e4b17023SJohn Marino 					MEM, SCRATCH),
1364*e4b17023SJohn Marino 			action, GET_MODE (x), MEM_ADDR_SPACE (x));
1365*e4b17023SJohn Marino       return;
1366*e4b17023SJohn Marino 
1367*e4b17023SJohn Marino     case SET:
1368*e4b17023SJohn Marino       scan_rtx (insn, &SET_SRC (x), cl, action, OP_IN);
1369*e4b17023SJohn Marino       scan_rtx (insn, &SET_DEST (x), cl, action,
1370*e4b17023SJohn Marino 		(GET_CODE (PATTERN (insn)) == COND_EXEC
1371*e4b17023SJohn Marino 		 && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT);
1372*e4b17023SJohn Marino       return;
1373*e4b17023SJohn Marino 
1374*e4b17023SJohn Marino     case STRICT_LOW_PART:
1375*e4b17023SJohn Marino       scan_rtx (insn, &XEXP (x, 0), cl, action,
1376*e4b17023SJohn Marino 		verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT);
1377*e4b17023SJohn Marino       return;
1378*e4b17023SJohn Marino 
1379*e4b17023SJohn Marino     case ZERO_EXTRACT:
1380*e4b17023SJohn Marino     case SIGN_EXTRACT:
1381*e4b17023SJohn Marino       scan_rtx (insn, &XEXP (x, 0), cl, action,
1382*e4b17023SJohn Marino 		(type == OP_IN ? OP_IN :
1383*e4b17023SJohn Marino 		 verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT));
1384*e4b17023SJohn Marino       scan_rtx (insn, &XEXP (x, 1), cl, action, OP_IN);
1385*e4b17023SJohn Marino       scan_rtx (insn, &XEXP (x, 2), cl, action, OP_IN);
1386*e4b17023SJohn Marino       return;
1387*e4b17023SJohn Marino 
1388*e4b17023SJohn Marino     case POST_INC:
1389*e4b17023SJohn Marino     case PRE_INC:
1390*e4b17023SJohn Marino     case POST_DEC:
1391*e4b17023SJohn Marino     case PRE_DEC:
1392*e4b17023SJohn Marino     case POST_MODIFY:
1393*e4b17023SJohn Marino     case PRE_MODIFY:
1394*e4b17023SJohn Marino       /* Should only happen inside MEM.  */
1395*e4b17023SJohn Marino       gcc_unreachable ();
1396*e4b17023SJohn Marino 
1397*e4b17023SJohn Marino     case CLOBBER:
1398*e4b17023SJohn Marino       scan_rtx (insn, &SET_DEST (x), cl, action,
1399*e4b17023SJohn Marino 		(GET_CODE (PATTERN (insn)) == COND_EXEC
1400*e4b17023SJohn Marino 		 && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT);
1401*e4b17023SJohn Marino       return;
1402*e4b17023SJohn Marino 
1403*e4b17023SJohn Marino     case EXPR_LIST:
1404*e4b17023SJohn Marino       scan_rtx (insn, &XEXP (x, 0), cl, action, type);
1405*e4b17023SJohn Marino       if (XEXP (x, 1))
1406*e4b17023SJohn Marino 	scan_rtx (insn, &XEXP (x, 1), cl, action, type);
1407*e4b17023SJohn Marino       return;
1408*e4b17023SJohn Marino 
1409*e4b17023SJohn Marino     default:
1410*e4b17023SJohn Marino       break;
1411*e4b17023SJohn Marino     }
1412*e4b17023SJohn Marino 
1413*e4b17023SJohn Marino   fmt = GET_RTX_FORMAT (code);
1414*e4b17023SJohn Marino   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1415*e4b17023SJohn Marino     {
1416*e4b17023SJohn Marino       if (fmt[i] == 'e')
1417*e4b17023SJohn Marino 	scan_rtx (insn, &XEXP (x, i), cl, action, type);
1418*e4b17023SJohn Marino       else if (fmt[i] == 'E')
1419*e4b17023SJohn Marino 	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1420*e4b17023SJohn Marino 	  scan_rtx (insn, &XVECEXP (x, i, j), cl, action, type);
1421*e4b17023SJohn Marino     }
1422*e4b17023SJohn Marino }
1423*e4b17023SJohn Marino 
1424*e4b17023SJohn Marino /* Hide operands of the current insn (of which there are N_OPS) by
1425*e4b17023SJohn Marino    substituting cc0 for them.
1426*e4b17023SJohn Marino    Previous values are stored in the OLD_OPERANDS and OLD_DUPS.
1427*e4b17023SJohn Marino    For every bit set in DO_NOT_HIDE, we leave the operand alone.
1428*e4b17023SJohn Marino    If INOUT_AND_EC_ONLY is set, we only do this for OP_INOUT type operands
1429*e4b17023SJohn Marino    and earlyclobbers.  */
1430*e4b17023SJohn Marino 
1431*e4b17023SJohn Marino static void
hide_operands(int n_ops,rtx * old_operands,rtx * old_dups,unsigned HOST_WIDE_INT do_not_hide,bool inout_and_ec_only)1432*e4b17023SJohn Marino hide_operands (int n_ops, rtx *old_operands, rtx *old_dups,
1433*e4b17023SJohn Marino 	       unsigned HOST_WIDE_INT do_not_hide, bool inout_and_ec_only)
1434*e4b17023SJohn Marino {
1435*e4b17023SJohn Marino   int i;
1436*e4b17023SJohn Marino   int alt = which_alternative;
1437*e4b17023SJohn Marino   for (i = 0; i < n_ops; i++)
1438*e4b17023SJohn Marino     {
1439*e4b17023SJohn Marino       old_operands[i] = recog_data.operand[i];
1440*e4b17023SJohn Marino       /* Don't squash match_operator or match_parallel here, since
1441*e4b17023SJohn Marino 	 we don't know that all of the contained registers are
1442*e4b17023SJohn Marino 	 reachable by proper operands.  */
1443*e4b17023SJohn Marino       if (recog_data.constraints[i][0] == '\0')
1444*e4b17023SJohn Marino 	continue;
1445*e4b17023SJohn Marino       if (do_not_hide & (1 << i))
1446*e4b17023SJohn Marino 	continue;
1447*e4b17023SJohn Marino       if (!inout_and_ec_only || recog_data.operand_type[i] == OP_INOUT
1448*e4b17023SJohn Marino 	  || recog_op_alt[i][alt].earlyclobber)
1449*e4b17023SJohn Marino 	*recog_data.operand_loc[i] = cc0_rtx;
1450*e4b17023SJohn Marino     }
1451*e4b17023SJohn Marino   for (i = 0; i < recog_data.n_dups; i++)
1452*e4b17023SJohn Marino     {
1453*e4b17023SJohn Marino       int opn = recog_data.dup_num[i];
1454*e4b17023SJohn Marino       old_dups[i] = *recog_data.dup_loc[i];
1455*e4b17023SJohn Marino       if (do_not_hide & (1 << opn))
1456*e4b17023SJohn Marino 	continue;
1457*e4b17023SJohn Marino       if (!inout_and_ec_only || recog_data.operand_type[opn] == OP_INOUT
1458*e4b17023SJohn Marino 	  || recog_op_alt[opn][alt].earlyclobber)
1459*e4b17023SJohn Marino 	*recog_data.dup_loc[i] = cc0_rtx;
1460*e4b17023SJohn Marino     }
1461*e4b17023SJohn Marino }
1462*e4b17023SJohn Marino 
1463*e4b17023SJohn Marino /* Undo the substitution performed by hide_operands.  INSN is the insn we
1464*e4b17023SJohn Marino    are processing; the arguments are the same as in hide_operands.  */
1465*e4b17023SJohn Marino 
1466*e4b17023SJohn Marino static void
restore_operands(rtx insn,int n_ops,rtx * old_operands,rtx * old_dups)1467*e4b17023SJohn Marino restore_operands (rtx insn, int n_ops, rtx *old_operands, rtx *old_dups)
1468*e4b17023SJohn Marino {
1469*e4b17023SJohn Marino   int i;
1470*e4b17023SJohn Marino   for (i = 0; i < recog_data.n_dups; i++)
1471*e4b17023SJohn Marino     *recog_data.dup_loc[i] = old_dups[i];
1472*e4b17023SJohn Marino   for (i = 0; i < n_ops; i++)
1473*e4b17023SJohn Marino     *recog_data.operand_loc[i] = old_operands[i];
1474*e4b17023SJohn Marino   if (recog_data.n_dups)
1475*e4b17023SJohn Marino     df_insn_rescan (insn);
1476*e4b17023SJohn Marino }
1477*e4b17023SJohn Marino 
1478*e4b17023SJohn Marino /* For each output operand of INSN, call scan_rtx to create a new
1479*e4b17023SJohn Marino    open chain.  Do this only for normal or earlyclobber outputs,
1480*e4b17023SJohn Marino    depending on EARLYCLOBBER.  If INSN_INFO is nonnull, use it to
1481*e4b17023SJohn Marino    record information about the operands in the insn.  */
1482*e4b17023SJohn Marino 
1483*e4b17023SJohn Marino static void
record_out_operands(rtx insn,bool earlyclobber,insn_rr_info * insn_info)1484*e4b17023SJohn Marino record_out_operands (rtx insn, bool earlyclobber, insn_rr_info *insn_info)
1485*e4b17023SJohn Marino {
1486*e4b17023SJohn Marino   int n_ops = recog_data.n_operands;
1487*e4b17023SJohn Marino   int alt = which_alternative;
1488*e4b17023SJohn Marino 
1489*e4b17023SJohn Marino   int i;
1490*e4b17023SJohn Marino 
1491*e4b17023SJohn Marino   for (i = 0; i < n_ops + recog_data.n_dups; i++)
1492*e4b17023SJohn Marino     {
1493*e4b17023SJohn Marino       int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
1494*e4b17023SJohn Marino       rtx *loc = (i < n_ops
1495*e4b17023SJohn Marino 		  ? recog_data.operand_loc[opn]
1496*e4b17023SJohn Marino 		  : recog_data.dup_loc[i - n_ops]);
1497*e4b17023SJohn Marino       rtx op = *loc;
1498*e4b17023SJohn Marino       enum reg_class cl = recog_op_alt[opn][alt].cl;
1499*e4b17023SJohn Marino 
1500*e4b17023SJohn Marino       struct du_head *prev_open;
1501*e4b17023SJohn Marino 
1502*e4b17023SJohn Marino       if (recog_data.operand_type[opn] != OP_OUT
1503*e4b17023SJohn Marino 	  || recog_op_alt[opn][alt].earlyclobber != earlyclobber)
1504*e4b17023SJohn Marino 	continue;
1505*e4b17023SJohn Marino 
1506*e4b17023SJohn Marino       if (insn_info)
1507*e4b17023SJohn Marino 	cur_operand = insn_info->op_info + i;
1508*e4b17023SJohn Marino 
1509*e4b17023SJohn Marino       prev_open = open_chains;
1510*e4b17023SJohn Marino       scan_rtx (insn, loc, cl, mark_write, OP_OUT);
1511*e4b17023SJohn Marino 
1512*e4b17023SJohn Marino       /* ??? Many targets have output constraints on the SET_DEST
1513*e4b17023SJohn Marino 	 of a call insn, which is stupid, since these are certainly
1514*e4b17023SJohn Marino 	 ABI defined hard registers.  For these, and for asm operands
1515*e4b17023SJohn Marino 	 that originally referenced hard registers, we must record that
1516*e4b17023SJohn Marino 	 the chain cannot be renamed.  */
1517*e4b17023SJohn Marino       if (CALL_P (insn)
1518*e4b17023SJohn Marino 	  || (asm_noperands (PATTERN (insn)) > 0
1519*e4b17023SJohn Marino 	      && REG_P (op)
1520*e4b17023SJohn Marino 	      && REGNO (op) == ORIGINAL_REGNO (op)))
1521*e4b17023SJohn Marino 	{
1522*e4b17023SJohn Marino 	  if (prev_open != open_chains)
1523*e4b17023SJohn Marino 	    open_chains->cannot_rename = 1;
1524*e4b17023SJohn Marino 	}
1525*e4b17023SJohn Marino     }
1526*e4b17023SJohn Marino   cur_operand = NULL;
1527*e4b17023SJohn Marino }
1528*e4b17023SJohn Marino 
1529*e4b17023SJohn Marino /* Build def/use chain.  */
1530*e4b17023SJohn Marino 
1531*e4b17023SJohn Marino static bool
build_def_use(basic_block bb)1532*e4b17023SJohn Marino build_def_use (basic_block bb)
1533*e4b17023SJohn Marino {
1534*e4b17023SJohn Marino   rtx insn;
1535*e4b17023SJohn Marino   unsigned HOST_WIDE_INT untracked_operands;
1536*e4b17023SJohn Marino 
1537*e4b17023SJohn Marino   fail_current_block = false;
1538*e4b17023SJohn Marino 
1539*e4b17023SJohn Marino   for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
1540*e4b17023SJohn Marino     {
1541*e4b17023SJohn Marino       if (NONDEBUG_INSN_P (insn))
1542*e4b17023SJohn Marino 	{
1543*e4b17023SJohn Marino 	  int n_ops;
1544*e4b17023SJohn Marino 	  rtx note;
1545*e4b17023SJohn Marino 	  rtx old_operands[MAX_RECOG_OPERANDS];
1546*e4b17023SJohn Marino 	  rtx old_dups[MAX_DUP_OPERANDS];
1547*e4b17023SJohn Marino 	  int i;
1548*e4b17023SJohn Marino 	  int alt;
1549*e4b17023SJohn Marino 	  int predicated;
1550*e4b17023SJohn Marino 	  enum rtx_code set_code = SET;
1551*e4b17023SJohn Marino 	  enum rtx_code clobber_code = CLOBBER;
1552*e4b17023SJohn Marino 	  insn_rr_info *insn_info = NULL;
1553*e4b17023SJohn Marino 
1554*e4b17023SJohn Marino 	  /* Process the insn, determining its effect on the def-use
1555*e4b17023SJohn Marino 	     chains and live hard registers.  We perform the following
1556*e4b17023SJohn Marino 	     steps with the register references in the insn, simulating
1557*e4b17023SJohn Marino 	     its effect:
1558*e4b17023SJohn Marino 	     (1) Deal with earlyclobber operands and CLOBBERs of non-operands
1559*e4b17023SJohn Marino 	         by creating chains and marking hard regs live.
1560*e4b17023SJohn Marino 	     (2) Any read outside an operand causes any chain it overlaps
1561*e4b17023SJohn Marino 	         with to be marked unrenamable.
1562*e4b17023SJohn Marino 	     (3) Any read inside an operand is added if there's already
1563*e4b17023SJohn Marino 	         an open chain for it.
1564*e4b17023SJohn Marino 	     (4) For any REG_DEAD note we find, close open chains that
1565*e4b17023SJohn Marino 	         overlap it.
1566*e4b17023SJohn Marino 	     (5) For any non-earlyclobber write we find, close open chains
1567*e4b17023SJohn Marino 	         that overlap it.
1568*e4b17023SJohn Marino 	     (6) For any non-earlyclobber write we find in an operand, make
1569*e4b17023SJohn Marino 	         a new chain or mark the hard register as live.
1570*e4b17023SJohn Marino 	     (7) For any REG_UNUSED, close any chains we just opened.
1571*e4b17023SJohn Marino 
1572*e4b17023SJohn Marino 	     We cannot deal with situations where we track a reg in one mode
1573*e4b17023SJohn Marino 	     and see a reference in another mode; these will cause the chain
1574*e4b17023SJohn Marino 	     to be marked unrenamable or even cause us to abort the entire
1575*e4b17023SJohn Marino 	     basic block.  */
1576*e4b17023SJohn Marino 
1577*e4b17023SJohn Marino 	  extract_insn (insn);
1578*e4b17023SJohn Marino 	  if (! constrain_operands (1))
1579*e4b17023SJohn Marino 	    fatal_insn_not_found (insn);
1580*e4b17023SJohn Marino 	  preprocess_constraints ();
1581*e4b17023SJohn Marino 	  alt = which_alternative;
1582*e4b17023SJohn Marino 	  n_ops = recog_data.n_operands;
1583*e4b17023SJohn Marino 	  untracked_operands = 0;
1584*e4b17023SJohn Marino 
1585*e4b17023SJohn Marino 	  if (insn_rr != NULL)
1586*e4b17023SJohn Marino 	    {
1587*e4b17023SJohn Marino 	      insn_info = VEC_index (insn_rr_info, insn_rr, INSN_UID (insn));
1588*e4b17023SJohn Marino 	      insn_info->op_info = XOBNEWVEC (&rename_obstack, operand_rr_info,
1589*e4b17023SJohn Marino 					      recog_data.n_operands);
1590*e4b17023SJohn Marino 	      memset (insn_info->op_info, 0,
1591*e4b17023SJohn Marino 		      sizeof (operand_rr_info) * recog_data.n_operands);
1592*e4b17023SJohn Marino 	    }
1593*e4b17023SJohn Marino 
1594*e4b17023SJohn Marino 	  /* Simplify the code below by rewriting things to reflect
1595*e4b17023SJohn Marino 	     matching constraints.  Also promote OP_OUT to OP_INOUT in
1596*e4b17023SJohn Marino 	     predicated instructions, but only for register operands
1597*e4b17023SJohn Marino 	     that are already tracked, so that we can create a chain
1598*e4b17023SJohn Marino 	     when the first SET makes a register live.  */
1599*e4b17023SJohn Marino 
1600*e4b17023SJohn Marino 	  predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
1601*e4b17023SJohn Marino 	  for (i = 0; i < n_ops; ++i)
1602*e4b17023SJohn Marino 	    {
1603*e4b17023SJohn Marino 	      rtx op = recog_data.operand[i];
1604*e4b17023SJohn Marino 	      int matches = recog_op_alt[i][alt].matches;
1605*e4b17023SJohn Marino 	      if (matches >= 0)
1606*e4b17023SJohn Marino 		recog_op_alt[i][alt].cl = recog_op_alt[matches][alt].cl;
1607*e4b17023SJohn Marino 	      if (matches >= 0 || recog_op_alt[i][alt].matched >= 0
1608*e4b17023SJohn Marino 	          || (predicated && recog_data.operand_type[i] == OP_OUT))
1609*e4b17023SJohn Marino 		{
1610*e4b17023SJohn Marino 		  recog_data.operand_type[i] = OP_INOUT;
1611*e4b17023SJohn Marino 		  /* A special case to deal with instruction patterns that
1612*e4b17023SJohn Marino 		     have matching operands with different modes.  If we're
1613*e4b17023SJohn Marino 		     not already tracking such a reg, we won't start here,
1614*e4b17023SJohn Marino 		     and we must instead make sure to make the operand visible
1615*e4b17023SJohn Marino 		     to the machinery that tracks hard registers.  */
1616*e4b17023SJohn Marino 		  if (matches >= 0
1617*e4b17023SJohn Marino 		      && (GET_MODE_SIZE (recog_data.operand_mode[i])
1618*e4b17023SJohn Marino 			  != GET_MODE_SIZE (recog_data.operand_mode[matches]))
1619*e4b17023SJohn Marino 		      && !verify_reg_in_set (op, &live_in_chains))
1620*e4b17023SJohn Marino 		    {
1621*e4b17023SJohn Marino 		      untracked_operands |= 1 << i;
1622*e4b17023SJohn Marino 		      untracked_operands |= 1 << matches;
1623*e4b17023SJohn Marino 		    }
1624*e4b17023SJohn Marino 		}
1625*e4b17023SJohn Marino 	      /* If there's an in-out operand with a register that is not
1626*e4b17023SJohn Marino 		 being tracked at all yet, open a chain.  */
1627*e4b17023SJohn Marino 	      if (recog_data.operand_type[i] == OP_INOUT
1628*e4b17023SJohn Marino 		  && !(untracked_operands & (1 << i))
1629*e4b17023SJohn Marino 		  && REG_P (op)
1630*e4b17023SJohn Marino 		  && !verify_reg_tracked (op))
1631*e4b17023SJohn Marino 		{
1632*e4b17023SJohn Marino 		  enum machine_mode mode = GET_MODE (op);
1633*e4b17023SJohn Marino 		  unsigned this_regno = REGNO (op);
1634*e4b17023SJohn Marino 		  unsigned this_nregs = hard_regno_nregs[this_regno][mode];
1635*e4b17023SJohn Marino 		  create_new_chain (this_regno, this_nregs, NULL, NULL_RTX,
1636*e4b17023SJohn Marino 				    NO_REGS);
1637*e4b17023SJohn Marino 		}
1638*e4b17023SJohn Marino 	    }
1639*e4b17023SJohn Marino 
1640*e4b17023SJohn Marino 	  if (fail_current_block)
1641*e4b17023SJohn Marino 	    break;
1642*e4b17023SJohn Marino 
1643*e4b17023SJohn Marino 	  /* Step 1a: Mark hard registers that are clobbered in this insn,
1644*e4b17023SJohn Marino 	     outside an operand, as live.  */
1645*e4b17023SJohn Marino 	  hide_operands (n_ops, old_operands, old_dups, untracked_operands,
1646*e4b17023SJohn Marino 			 false);
1647*e4b17023SJohn Marino 	  note_stores (PATTERN (insn), note_sets_clobbers, &clobber_code);
1648*e4b17023SJohn Marino 	  restore_operands (insn, n_ops, old_operands, old_dups);
1649*e4b17023SJohn Marino 
1650*e4b17023SJohn Marino 	  /* Step 1b: Begin new chains for earlyclobbered writes inside
1651*e4b17023SJohn Marino 	     operands.  */
1652*e4b17023SJohn Marino 	  record_out_operands (insn, true, insn_info);
1653*e4b17023SJohn Marino 
1654*e4b17023SJohn Marino 	  /* Step 2: Mark chains for which we have reads outside operands
1655*e4b17023SJohn Marino 	     as unrenamable.
1656*e4b17023SJohn Marino 	     We do this by munging all operands into CC0, and closing
1657*e4b17023SJohn Marino 	     everything remaining.  */
1658*e4b17023SJohn Marino 
1659*e4b17023SJohn Marino 	  hide_operands (n_ops, old_operands, old_dups, untracked_operands,
1660*e4b17023SJohn Marino 			 false);
1661*e4b17023SJohn Marino 	  scan_rtx (insn, &PATTERN (insn), NO_REGS, mark_all_read, OP_IN);
1662*e4b17023SJohn Marino 	  restore_operands (insn, n_ops, old_operands, old_dups);
1663*e4b17023SJohn Marino 
1664*e4b17023SJohn Marino 	  /* Step 2B: Can't rename function call argument registers.  */
1665*e4b17023SJohn Marino 	  if (CALL_P (insn) && CALL_INSN_FUNCTION_USAGE (insn))
1666*e4b17023SJohn Marino 	    scan_rtx (insn, &CALL_INSN_FUNCTION_USAGE (insn),
1667*e4b17023SJohn Marino 		      NO_REGS, mark_all_read, OP_IN);
1668*e4b17023SJohn Marino 
1669*e4b17023SJohn Marino 	  /* Step 2C: Can't rename asm operands that were originally
1670*e4b17023SJohn Marino 	     hard registers.  */
1671*e4b17023SJohn Marino 	  if (asm_noperands (PATTERN (insn)) > 0)
1672*e4b17023SJohn Marino 	    for (i = 0; i < n_ops; i++)
1673*e4b17023SJohn Marino 	      {
1674*e4b17023SJohn Marino 		rtx *loc = recog_data.operand_loc[i];
1675*e4b17023SJohn Marino 		rtx op = *loc;
1676*e4b17023SJohn Marino 
1677*e4b17023SJohn Marino 		if (REG_P (op)
1678*e4b17023SJohn Marino 		    && REGNO (op) == ORIGINAL_REGNO (op)
1679*e4b17023SJohn Marino 		    && (recog_data.operand_type[i] == OP_IN
1680*e4b17023SJohn Marino 			|| recog_data.operand_type[i] == OP_INOUT))
1681*e4b17023SJohn Marino 		  scan_rtx (insn, loc, NO_REGS, mark_all_read, OP_IN);
1682*e4b17023SJohn Marino 	      }
1683*e4b17023SJohn Marino 
1684*e4b17023SJohn Marino 	  /* Step 3: Append to chains for reads inside operands.  */
1685*e4b17023SJohn Marino 	  for (i = 0; i < n_ops + recog_data.n_dups; i++)
1686*e4b17023SJohn Marino 	    {
1687*e4b17023SJohn Marino 	      int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
1688*e4b17023SJohn Marino 	      rtx *loc = (i < n_ops
1689*e4b17023SJohn Marino 			  ? recog_data.operand_loc[opn]
1690*e4b17023SJohn Marino 			  : recog_data.dup_loc[i - n_ops]);
1691*e4b17023SJohn Marino 	      enum reg_class cl = recog_op_alt[opn][alt].cl;
1692*e4b17023SJohn Marino 	      enum op_type type = recog_data.operand_type[opn];
1693*e4b17023SJohn Marino 
1694*e4b17023SJohn Marino 	      /* Don't scan match_operand here, since we've no reg class
1695*e4b17023SJohn Marino 		 information to pass down.  Any operands that we could
1696*e4b17023SJohn Marino 		 substitute in will be represented elsewhere.  */
1697*e4b17023SJohn Marino 	      if (recog_data.constraints[opn][0] == '\0'
1698*e4b17023SJohn Marino 		  || untracked_operands & (1 << opn))
1699*e4b17023SJohn Marino 		continue;
1700*e4b17023SJohn Marino 
1701*e4b17023SJohn Marino 	      if (insn_info)
1702*e4b17023SJohn Marino 		cur_operand = i == opn ? insn_info->op_info + i : NULL;
1703*e4b17023SJohn Marino 	      if (recog_op_alt[opn][alt].is_address)
1704*e4b17023SJohn Marino 		scan_rtx_address (insn, loc, cl, mark_read,
1705*e4b17023SJohn Marino 				  VOIDmode, ADDR_SPACE_GENERIC);
1706*e4b17023SJohn Marino 	      else
1707*e4b17023SJohn Marino 		scan_rtx (insn, loc, cl, mark_read, type);
1708*e4b17023SJohn Marino 	    }
1709*e4b17023SJohn Marino 	  cur_operand = NULL;
1710*e4b17023SJohn Marino 
1711*e4b17023SJohn Marino 	  /* Step 3B: Record updates for regs in REG_INC notes, and
1712*e4b17023SJohn Marino 	     source regs in REG_FRAME_RELATED_EXPR notes.  */
1713*e4b17023SJohn Marino 	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1714*e4b17023SJohn Marino 	    if (REG_NOTE_KIND (note) == REG_INC
1715*e4b17023SJohn Marino 		|| REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
1716*e4b17023SJohn Marino 	      scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_read,
1717*e4b17023SJohn Marino 			OP_INOUT);
1718*e4b17023SJohn Marino 
1719*e4b17023SJohn Marino 	  /* Step 4: Close chains for registers that die here.  */
1720*e4b17023SJohn Marino 	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1721*e4b17023SJohn Marino 	    if (REG_NOTE_KIND (note) == REG_DEAD)
1722*e4b17023SJohn Marino 	      {
1723*e4b17023SJohn Marino 		remove_from_hard_reg_set (&live_hard_regs,
1724*e4b17023SJohn Marino 					  GET_MODE (XEXP (note, 0)),
1725*e4b17023SJohn Marino 					  REGNO (XEXP (note, 0)));
1726*e4b17023SJohn Marino 		scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
1727*e4b17023SJohn Marino 			  OP_IN);
1728*e4b17023SJohn Marino 	      }
1729*e4b17023SJohn Marino 
1730*e4b17023SJohn Marino 	  /* Step 4B: If this is a call, any chain live at this point
1731*e4b17023SJohn Marino 	     requires a caller-saved reg.  */
1732*e4b17023SJohn Marino 	  if (CALL_P (insn))
1733*e4b17023SJohn Marino 	    {
1734*e4b17023SJohn Marino 	      struct du_head *p;
1735*e4b17023SJohn Marino 	      for (p = open_chains; p; p = p->next_chain)
1736*e4b17023SJohn Marino 		p->need_caller_save_reg = 1;
1737*e4b17023SJohn Marino 	    }
1738*e4b17023SJohn Marino 
1739*e4b17023SJohn Marino 	  /* Step 5: Close open chains that overlap writes.  Similar to
1740*e4b17023SJohn Marino 	     step 2, we hide in-out operands, since we do not want to
1741*e4b17023SJohn Marino 	     close these chains.  We also hide earlyclobber operands,
1742*e4b17023SJohn Marino 	     since we've opened chains for them in step 1, and earlier
1743*e4b17023SJohn Marino 	     chains they would overlap with must have been closed at
1744*e4b17023SJohn Marino 	     the previous insn at the latest, as such operands cannot
1745*e4b17023SJohn Marino 	     possibly overlap with any input operands.  */
1746*e4b17023SJohn Marino 
1747*e4b17023SJohn Marino 	  hide_operands (n_ops, old_operands, old_dups, untracked_operands,
1748*e4b17023SJohn Marino 			 true);
1749*e4b17023SJohn Marino 	  scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_write, OP_IN);
1750*e4b17023SJohn Marino 	  restore_operands (insn, n_ops, old_operands, old_dups);
1751*e4b17023SJohn Marino 
1752*e4b17023SJohn Marino 	  /* Step 6a: Mark hard registers that are set in this insn,
1753*e4b17023SJohn Marino 	     outside an operand, as live.  */
1754*e4b17023SJohn Marino 	  hide_operands (n_ops, old_operands, old_dups, untracked_operands,
1755*e4b17023SJohn Marino 			 false);
1756*e4b17023SJohn Marino 	  note_stores (PATTERN (insn), note_sets_clobbers, &set_code);
1757*e4b17023SJohn Marino 	  restore_operands (insn, n_ops, old_operands, old_dups);
1758*e4b17023SJohn Marino 
1759*e4b17023SJohn Marino 	  /* Step 6b: Begin new chains for writes inside operands.  */
1760*e4b17023SJohn Marino 	  record_out_operands (insn, false, insn_info);
1761*e4b17023SJohn Marino 
1762*e4b17023SJohn Marino 	  /* Step 6c: Record destination regs in REG_FRAME_RELATED_EXPR
1763*e4b17023SJohn Marino 	     notes for update.  */
1764*e4b17023SJohn Marino 	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1765*e4b17023SJohn Marino 	    if (REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
1766*e4b17023SJohn Marino 	      scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_access,
1767*e4b17023SJohn Marino 			OP_INOUT);
1768*e4b17023SJohn Marino 
1769*e4b17023SJohn Marino 	  /* Step 7: Close chains for registers that were never
1770*e4b17023SJohn Marino 	     really used here.  */
1771*e4b17023SJohn Marino 	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1772*e4b17023SJohn Marino 	    if (REG_NOTE_KIND (note) == REG_UNUSED)
1773*e4b17023SJohn Marino 	      {
1774*e4b17023SJohn Marino 		remove_from_hard_reg_set (&live_hard_regs,
1775*e4b17023SJohn Marino 					  GET_MODE (XEXP (note, 0)),
1776*e4b17023SJohn Marino 					  REGNO (XEXP (note, 0)));
1777*e4b17023SJohn Marino 		scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
1778*e4b17023SJohn Marino 			  OP_IN);
1779*e4b17023SJohn Marino 	      }
1780*e4b17023SJohn Marino 	}
1781*e4b17023SJohn Marino       else if (DEBUG_INSN_P (insn)
1782*e4b17023SJohn Marino 	       && !VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)))
1783*e4b17023SJohn Marino 	{
1784*e4b17023SJohn Marino 	  scan_rtx (insn, &INSN_VAR_LOCATION_LOC (insn),
1785*e4b17023SJohn Marino 		    ALL_REGS, mark_read, OP_IN);
1786*e4b17023SJohn Marino 	}
1787*e4b17023SJohn Marino       if (insn == BB_END (bb))
1788*e4b17023SJohn Marino 	break;
1789*e4b17023SJohn Marino     }
1790*e4b17023SJohn Marino 
1791*e4b17023SJohn Marino   if (fail_current_block)
1792*e4b17023SJohn Marino     return false;
1793*e4b17023SJohn Marino 
1794*e4b17023SJohn Marino   return true;
1795*e4b17023SJohn Marino }
1796*e4b17023SJohn Marino 
1797*e4b17023SJohn Marino /* Initialize the register renamer.  If INSN_INFO is true, ensure that
1798*e4b17023SJohn Marino    insn_rr is nonnull.  */
1799*e4b17023SJohn Marino void
regrename_init(bool insn_info)1800*e4b17023SJohn Marino regrename_init (bool insn_info)
1801*e4b17023SJohn Marino {
1802*e4b17023SJohn Marino   gcc_obstack_init (&rename_obstack);
1803*e4b17023SJohn Marino   insn_rr = NULL;
1804*e4b17023SJohn Marino   if (insn_info)
1805*e4b17023SJohn Marino     VEC_safe_grow_cleared (insn_rr_info, heap, insn_rr, get_max_uid ());
1806*e4b17023SJohn Marino }
1807*e4b17023SJohn Marino 
1808*e4b17023SJohn Marino /* Free all global data used by the register renamer.  */
1809*e4b17023SJohn Marino void
regrename_finish(void)1810*e4b17023SJohn Marino regrename_finish (void)
1811*e4b17023SJohn Marino {
1812*e4b17023SJohn Marino   VEC_free (insn_rr_info, heap, insn_rr);
1813*e4b17023SJohn Marino   free_chain_data ();
1814*e4b17023SJohn Marino   obstack_free (&rename_obstack, NULL);
1815*e4b17023SJohn Marino }
1816*e4b17023SJohn Marino 
1817*e4b17023SJohn Marino /* Perform register renaming on the current function.  */
1818*e4b17023SJohn Marino 
1819*e4b17023SJohn Marino static unsigned int
regrename_optimize(void)1820*e4b17023SJohn Marino regrename_optimize (void)
1821*e4b17023SJohn Marino {
1822*e4b17023SJohn Marino   df_set_flags (DF_LR_RUN_DCE);
1823*e4b17023SJohn Marino   df_note_add_problem ();
1824*e4b17023SJohn Marino   df_analyze ();
1825*e4b17023SJohn Marino   df_set_flags (DF_DEFER_INSN_RESCAN);
1826*e4b17023SJohn Marino 
1827*e4b17023SJohn Marino   regrename_init (false);
1828*e4b17023SJohn Marino 
1829*e4b17023SJohn Marino   regrename_analyze (NULL);
1830*e4b17023SJohn Marino 
1831*e4b17023SJohn Marino   rename_chains ();
1832*e4b17023SJohn Marino 
1833*e4b17023SJohn Marino   regrename_finish ();
1834*e4b17023SJohn Marino 
1835*e4b17023SJohn Marino   return 0;
1836*e4b17023SJohn Marino }
1837*e4b17023SJohn Marino 
1838*e4b17023SJohn Marino static bool
gate_handle_regrename(void)1839*e4b17023SJohn Marino gate_handle_regrename (void)
1840*e4b17023SJohn Marino {
1841*e4b17023SJohn Marino   return (optimize > 0 && (flag_rename_registers));
1842*e4b17023SJohn Marino }
1843*e4b17023SJohn Marino 
1844*e4b17023SJohn Marino struct rtl_opt_pass pass_regrename =
1845*e4b17023SJohn Marino {
1846*e4b17023SJohn Marino  {
1847*e4b17023SJohn Marino   RTL_PASS,
1848*e4b17023SJohn Marino   "rnreg",                              /* name */
1849*e4b17023SJohn Marino   gate_handle_regrename,                /* gate */
1850*e4b17023SJohn Marino   regrename_optimize,                   /* execute */
1851*e4b17023SJohn Marino   NULL,                                 /* sub */
1852*e4b17023SJohn Marino   NULL,                                 /* next */
1853*e4b17023SJohn Marino   0,                                    /* static_pass_number */
1854*e4b17023SJohn Marino   TV_RENAME_REGISTERS,                  /* tv_id */
1855*e4b17023SJohn Marino   0,                                    /* properties_required */
1856*e4b17023SJohn Marino   0,                                    /* properties_provided */
1857*e4b17023SJohn Marino   0,                                    /* properties_destroyed */
1858*e4b17023SJohn Marino   0,                                    /* todo_flags_start */
1859*e4b17023SJohn Marino   TODO_df_finish | TODO_verify_rtl_sharing |
1860*e4b17023SJohn Marino   0                                     /* todo_flags_finish */
1861*e4b17023SJohn Marino  }
1862*e4b17023SJohn Marino };
1863