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