xref: /dflybsd-src/contrib/gcc-8.0/gcc/regstat.c (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj /* Scanning of rtl for dataflow analysis.
2*38fd1498Szrj    Copyright (C) 2007-2018 Free Software Foundation, Inc.
3*38fd1498Szrj    Contributed by Kenneth Zadeck (zadeck@naturalbridge.com).
4*38fd1498Szrj 
5*38fd1498Szrj This file is part of GCC.
6*38fd1498Szrj 
7*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
8*38fd1498Szrj the terms of the GNU General Public License as published by the Free
9*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
10*38fd1498Szrj version.
11*38fd1498Szrj 
12*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15*38fd1498Szrj for more details.
16*38fd1498Szrj 
17*38fd1498Szrj You should have received a copy of the GNU General Public License
18*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
19*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
20*38fd1498Szrj 
21*38fd1498Szrj 
22*38fd1498Szrj #include "config.h"
23*38fd1498Szrj #include "system.h"
24*38fd1498Szrj #include "coretypes.h"
25*38fd1498Szrj #include "backend.h"
26*38fd1498Szrj #include "rtl.h"
27*38fd1498Szrj #include "predict.h"
28*38fd1498Szrj #include "df.h"
29*38fd1498Szrj #include "regs.h"
30*38fd1498Szrj 
31*38fd1498Szrj 
32*38fd1498Szrj struct regstat_n_sets_and_refs_t *regstat_n_sets_and_refs;
33*38fd1498Szrj 
34*38fd1498Szrj /*----------------------------------------------------------------------------
35*38fd1498Szrj    REG_N_SETS and REG_N_REFS.
36*38fd1498Szrj    ----------------------------------------------------------------------------*/
37*38fd1498Szrj 
38*38fd1498Szrj /* If a pass need to change these values in some magical way or the
39*38fd1498Szrj    pass needs to have accurate values for these and is not using
40*38fd1498Szrj    incremental df scanning, then it should use REG_N_SETS and
41*38fd1498Szrj    REG_N_USES.  If the pass is doing incremental scanning then it
42*38fd1498Szrj    should be getting the info from DF_REG_DEF_COUNT and
43*38fd1498Szrj    DF_REG_USE_COUNT.  */
44*38fd1498Szrj 
45*38fd1498Szrj void
regstat_init_n_sets_and_refs(void)46*38fd1498Szrj regstat_init_n_sets_and_refs (void)
47*38fd1498Szrj {
48*38fd1498Szrj   unsigned int i;
49*38fd1498Szrj   unsigned int max_regno = max_reg_num ();
50*38fd1498Szrj 
51*38fd1498Szrj   timevar_push (TV_REG_STATS);
52*38fd1498Szrj   df_grow_reg_info ();
53*38fd1498Szrj   gcc_assert (!regstat_n_sets_and_refs);
54*38fd1498Szrj 
55*38fd1498Szrj   regstat_n_sets_and_refs = XNEWVEC (struct regstat_n_sets_and_refs_t, max_regno);
56*38fd1498Szrj 
57*38fd1498Szrj   if (MAY_HAVE_DEBUG_BIND_INSNS)
58*38fd1498Szrj     for (i = 0; i < max_regno; i++)
59*38fd1498Szrj       {
60*38fd1498Szrj 	int use_count;
61*38fd1498Szrj 	df_ref use;
62*38fd1498Szrj 
63*38fd1498Szrj 	use_count = DF_REG_USE_COUNT (i);
64*38fd1498Szrj 	for (use = DF_REG_USE_CHAIN (i); use; use = DF_REF_NEXT_REG (use))
65*38fd1498Szrj 	  if (DF_REF_INSN_INFO (use) && DEBUG_INSN_P (DF_REF_INSN (use)))
66*38fd1498Szrj 	    use_count--;
67*38fd1498Szrj 
68*38fd1498Szrj 
69*38fd1498Szrj 	SET_REG_N_SETS (i, DF_REG_DEF_COUNT (i));
70*38fd1498Szrj 	SET_REG_N_REFS (i, use_count + REG_N_SETS (i));
71*38fd1498Szrj       }
72*38fd1498Szrj   else
73*38fd1498Szrj     for (i = 0; i < max_regno; i++)
74*38fd1498Szrj       {
75*38fd1498Szrj 	SET_REG_N_SETS (i, DF_REG_DEF_COUNT (i));
76*38fd1498Szrj 	SET_REG_N_REFS (i, DF_REG_USE_COUNT (i) + REG_N_SETS (i));
77*38fd1498Szrj       }
78*38fd1498Szrj   timevar_pop (TV_REG_STATS);
79*38fd1498Szrj 
80*38fd1498Szrj }
81*38fd1498Szrj 
82*38fd1498Szrj 
83*38fd1498Szrj /* Free the array that holds the REG_N_SETS and REG_N_REFS.  */
84*38fd1498Szrj 
85*38fd1498Szrj void
regstat_free_n_sets_and_refs(void)86*38fd1498Szrj regstat_free_n_sets_and_refs (void)
87*38fd1498Szrj {
88*38fd1498Szrj   gcc_assert (regstat_n_sets_and_refs);
89*38fd1498Szrj   free (regstat_n_sets_and_refs);
90*38fd1498Szrj   regstat_n_sets_and_refs = NULL;
91*38fd1498Szrj }
92*38fd1498Szrj 
93*38fd1498Szrj 
94*38fd1498Szrj /*----------------------------------------------------------------------------
95*38fd1498Szrj    REGISTER INFORMATION
96*38fd1498Szrj 
97*38fd1498Szrj    Process REG_N_DEATHS, REG_N_CALLS_CROSSED, and REG_BASIC_BLOCK.
98*38fd1498Szrj 
99*38fd1498Szrj    ----------------------------------------------------------------------------*/
100*38fd1498Szrj 
101*38fd1498Szrj static bitmap setjmp_crosses;
102*38fd1498Szrj struct reg_info_t *reg_info_p;
103*38fd1498Szrj 
104*38fd1498Szrj /* The number allocated elements of reg_info_p.  */
105*38fd1498Szrj size_t reg_info_p_size;
106*38fd1498Szrj 
107*38fd1498Szrj /* Compute register info: lifetime, bb, and number of defs and uses
108*38fd1498Szrj    for basic block BB.  LIVE is a scratch bitvector used here.  */
109*38fd1498Szrj 
110*38fd1498Szrj static void
regstat_bb_compute_ri(basic_block bb,bitmap live)111*38fd1498Szrj regstat_bb_compute_ri (basic_block bb, bitmap live)
112*38fd1498Szrj {
113*38fd1498Szrj   rtx_insn *insn;
114*38fd1498Szrj   df_ref def, use;
115*38fd1498Szrj   bitmap_iterator bi;
116*38fd1498Szrj   unsigned int regno;
117*38fd1498Szrj 
118*38fd1498Szrj   bitmap_copy (live, df_get_live_out (bb));
119*38fd1498Szrj 
120*38fd1498Szrj   /* Process the regs live at the end of the block.  Mark them as
121*38fd1498Szrj      not local to any one basic block.  */
122*38fd1498Szrj   EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
123*38fd1498Szrj     REG_BASIC_BLOCK (regno) = REG_BLOCK_GLOBAL;
124*38fd1498Szrj 
125*38fd1498Szrj   /* Process the artificial defs and uses at the bottom of the block
126*38fd1498Szrj      to begin processing.  */
127*38fd1498Szrj   FOR_EACH_ARTIFICIAL_DEF (def, bb->index)
128*38fd1498Szrj     if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
129*38fd1498Szrj       bitmap_clear_bit (live, DF_REF_REGNO (def));
130*38fd1498Szrj 
131*38fd1498Szrj   FOR_EACH_ARTIFICIAL_USE (use, bb->index)
132*38fd1498Szrj     if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
133*38fd1498Szrj       {
134*38fd1498Szrj 	regno = DF_REF_REGNO (use);
135*38fd1498Szrj 	bitmap_set_bit (live, regno);
136*38fd1498Szrj       }
137*38fd1498Szrj 
138*38fd1498Szrj   FOR_BB_INSNS_REVERSE (bb, insn)
139*38fd1498Szrj     {
140*38fd1498Szrj       struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
141*38fd1498Szrj       bitmap_iterator bi;
142*38fd1498Szrj       rtx link;
143*38fd1498Szrj 
144*38fd1498Szrj       if (!NONDEBUG_INSN_P (insn))
145*38fd1498Szrj 	continue;
146*38fd1498Szrj 
147*38fd1498Szrj       link = REG_NOTES (insn);
148*38fd1498Szrj       while (link)
149*38fd1498Szrj 	{
150*38fd1498Szrj 	  if (REG_NOTE_KIND (link) == REG_DEAD)
151*38fd1498Szrj 	    REG_N_DEATHS (REGNO (XEXP (link, 0)))++;
152*38fd1498Szrj 	  link = XEXP (link, 1);
153*38fd1498Szrj 	}
154*38fd1498Szrj 
155*38fd1498Szrj       /* Process the defs.  */
156*38fd1498Szrj       if (CALL_P (insn))
157*38fd1498Szrj 	{
158*38fd1498Szrj 	  bool set_jump = (find_reg_note (insn, REG_SETJMP, NULL) != NULL);
159*38fd1498Szrj 	  EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
160*38fd1498Szrj 	    {
161*38fd1498Szrj 	      REG_N_CALLS_CROSSED (regno)++;
162*38fd1498Szrj 
163*38fd1498Szrj 	      /* We have a problem with any pseudoreg that lives
164*38fd1498Szrj 		 across the setjmp.  ANSI says that if a user variable
165*38fd1498Szrj 		 does not change in value between the setjmp and the
166*38fd1498Szrj 		 longjmp, then the longjmp preserves it.  This
167*38fd1498Szrj 		 includes longjmp from a place where the pseudo
168*38fd1498Szrj 		 appears dead.  (In principle, the value still exists
169*38fd1498Szrj 		 if it is in scope.)  If the pseudo goes in a hard
170*38fd1498Szrj 		 reg, some other value may occupy that hard reg where
171*38fd1498Szrj 		 this pseudo is dead, thus clobbering the pseudo.
172*38fd1498Szrj 		 Conclusion: such a pseudo must not go in a hard
173*38fd1498Szrj 		 reg.  */
174*38fd1498Szrj 	      if (set_jump)
175*38fd1498Szrj 		bitmap_set_bit (setjmp_crosses, regno);
176*38fd1498Szrj 	    }
177*38fd1498Szrj 	}
178*38fd1498Szrj 
179*38fd1498Szrj       /* All of the defs except the return value are some sort of
180*38fd1498Szrj 	 clobber.  This code is for the return.  */
181*38fd1498Szrj       FOR_EACH_INSN_INFO_DEF (def, insn_info)
182*38fd1498Szrj 	{
183*38fd1498Szrj 	  if ((!CALL_P (insn))
184*38fd1498Szrj 	      || (!(DF_REF_FLAGS (def)
185*38fd1498Szrj 		    & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))))
186*38fd1498Szrj 	    {
187*38fd1498Szrj 	      unsigned int dregno = DF_REF_REGNO (def);
188*38fd1498Szrj 
189*38fd1498Szrj 	      /* Kill this register if it is not a subreg store or
190*38fd1498Szrj 		 conditional store.
191*38fd1498Szrj 		 ??? This means that any partial store is live from
192*38fd1498Szrj 		 the last use in a basic block to the start of this
193*38fd1498Szrj 		 basic block.  */
194*38fd1498Szrj 	      if (!(DF_REF_FLAGS (def)
195*38fd1498Szrj 		    & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
196*38fd1498Szrj 		bitmap_clear_bit (live, dregno);
197*38fd1498Szrj 
198*38fd1498Szrj 	      if (dregno >= FIRST_PSEUDO_REGISTER)
199*38fd1498Szrj 		{
200*38fd1498Szrj 		  REG_FREQ (dregno) += REG_FREQ_FROM_BB (bb);
201*38fd1498Szrj 		  REG_FREQ (dregno) =
202*38fd1498Szrj 		    MIN (REG_FREQ (dregno), REG_FREQ_MAX);
203*38fd1498Szrj 
204*38fd1498Szrj 		  if (REG_BASIC_BLOCK (dregno) == REG_BLOCK_UNKNOWN)
205*38fd1498Szrj 		    REG_BASIC_BLOCK (dregno) = bb->index;
206*38fd1498Szrj 		  else if (REG_BASIC_BLOCK (dregno) != bb->index)
207*38fd1498Szrj 		    REG_BASIC_BLOCK (dregno) = REG_BLOCK_GLOBAL;
208*38fd1498Szrj 		}
209*38fd1498Szrj 	    }
210*38fd1498Szrj 	}
211*38fd1498Szrj 
212*38fd1498Szrj       FOR_EACH_INSN_INFO_USE (use, insn_info)
213*38fd1498Szrj 	{
214*38fd1498Szrj 	  unsigned int uregno = DF_REF_REGNO (use);
215*38fd1498Szrj 
216*38fd1498Szrj 	  if (uregno >= FIRST_PSEUDO_REGISTER)
217*38fd1498Szrj 	    {
218*38fd1498Szrj 	      REG_FREQ (uregno) += REG_FREQ_FROM_BB (bb);
219*38fd1498Szrj 	      REG_FREQ (uregno) =
220*38fd1498Szrj 		MIN (REG_FREQ (uregno), REG_FREQ_MAX);
221*38fd1498Szrj 
222*38fd1498Szrj 	      if (REG_BASIC_BLOCK (uregno) == REG_BLOCK_UNKNOWN)
223*38fd1498Szrj 		REG_BASIC_BLOCK (uregno) = bb->index;
224*38fd1498Szrj 	      else if (REG_BASIC_BLOCK (uregno) != bb->index)
225*38fd1498Szrj 		REG_BASIC_BLOCK (uregno) = REG_BLOCK_GLOBAL;
226*38fd1498Szrj 	    }
227*38fd1498Szrj 	}
228*38fd1498Szrj     }
229*38fd1498Szrj }
230*38fd1498Szrj 
231*38fd1498Szrj 
232*38fd1498Szrj /* Compute register info: lifetime, bb, and number of defs and uses.  */
233*38fd1498Szrj void
regstat_compute_ri(void)234*38fd1498Szrj regstat_compute_ri (void)
235*38fd1498Szrj {
236*38fd1498Szrj   basic_block bb;
237*38fd1498Szrj   bitmap live = BITMAP_ALLOC (&df_bitmap_obstack);
238*38fd1498Szrj   unsigned int regno;
239*38fd1498Szrj   bitmap_iterator bi;
240*38fd1498Szrj 
241*38fd1498Szrj   /* Initialize everything.  */
242*38fd1498Szrj 
243*38fd1498Szrj   gcc_assert (!reg_info_p);
244*38fd1498Szrj 
245*38fd1498Szrj   timevar_push (TV_REG_STATS);
246*38fd1498Szrj   setjmp_crosses = BITMAP_ALLOC (&df_bitmap_obstack);
247*38fd1498Szrj   max_regno = max_reg_num ();
248*38fd1498Szrj   reg_info_p_size = max_regno;
249*38fd1498Szrj   reg_info_p = XCNEWVEC (struct reg_info_t, max_regno);
250*38fd1498Szrj 
251*38fd1498Szrj   FOR_EACH_BB_FN (bb, cfun)
252*38fd1498Szrj     {
253*38fd1498Szrj       regstat_bb_compute_ri (bb, live);
254*38fd1498Szrj     }
255*38fd1498Szrj 
256*38fd1498Szrj   BITMAP_FREE (live);
257*38fd1498Szrj 
258*38fd1498Szrj   /* See the setjmp comment in regstat_bb_compute_ri.  */
259*38fd1498Szrj   EXECUTE_IF_SET_IN_BITMAP (setjmp_crosses, FIRST_PSEUDO_REGISTER, regno, bi)
260*38fd1498Szrj     {
261*38fd1498Szrj       REG_BASIC_BLOCK (regno) = REG_BLOCK_UNKNOWN;
262*38fd1498Szrj     }
263*38fd1498Szrj 
264*38fd1498Szrj   timevar_pop (TV_REG_STATS);
265*38fd1498Szrj }
266*38fd1498Szrj 
267*38fd1498Szrj 
268*38fd1498Szrj /* Free all storage associated with the problem.  */
269*38fd1498Szrj 
270*38fd1498Szrj void
regstat_free_ri(void)271*38fd1498Szrj regstat_free_ri (void)
272*38fd1498Szrj {
273*38fd1498Szrj   gcc_assert (reg_info_p);
274*38fd1498Szrj   reg_info_p_size = 0;
275*38fd1498Szrj   free (reg_info_p);
276*38fd1498Szrj   reg_info_p = NULL;
277*38fd1498Szrj 
278*38fd1498Szrj   BITMAP_FREE (setjmp_crosses);
279*38fd1498Szrj }
280*38fd1498Szrj 
281*38fd1498Szrj 
282*38fd1498Szrj /* Return a bitmap containing the set of registers that cross a setjmp.
283*38fd1498Szrj    The client should not change or delete this bitmap.  */
284*38fd1498Szrj 
285*38fd1498Szrj bitmap
regstat_get_setjmp_crosses(void)286*38fd1498Szrj regstat_get_setjmp_crosses (void)
287*38fd1498Szrj {
288*38fd1498Szrj   return setjmp_crosses;
289*38fd1498Szrj }
290*38fd1498Szrj 
291*38fd1498Szrj /*----------------------------------------------------------------------------
292*38fd1498Szrj    Process REG_N_CALLS_CROSSED.
293*38fd1498Szrj 
294*38fd1498Szrj    This is used by sched_deps.  A good implementation of sched-deps
295*38fd1498Szrj    would really process the blocks directly rather than going through
296*38fd1498Szrj    lists of insns.  If it did this, it could use the exact regs that
297*38fd1498Szrj    cross an individual call rather than using this info that merges
298*38fd1498Szrj    the info for all calls.
299*38fd1498Szrj 
300*38fd1498Szrj    ----------------------------------------------------------------------------*/
301*38fd1498Szrj 
302*38fd1498Szrj 
303*38fd1498Szrj 
304*38fd1498Szrj /* Compute calls crossed for BB. Live is a scratch bitvector.  */
305*38fd1498Szrj 
306*38fd1498Szrj static void
regstat_bb_compute_calls_crossed(unsigned int bb_index,bitmap live)307*38fd1498Szrj regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live)
308*38fd1498Szrj {
309*38fd1498Szrj   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
310*38fd1498Szrj   rtx_insn *insn;
311*38fd1498Szrj   df_ref def, use;
312*38fd1498Szrj 
313*38fd1498Szrj   bitmap_copy (live, df_get_live_out (bb));
314*38fd1498Szrj 
315*38fd1498Szrj   /* Process the artificial defs and uses at the bottom of the block
316*38fd1498Szrj      to begin processing.  */
317*38fd1498Szrj   FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
318*38fd1498Szrj     if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
319*38fd1498Szrj       bitmap_clear_bit (live, DF_REF_REGNO (def));
320*38fd1498Szrj 
321*38fd1498Szrj   FOR_EACH_ARTIFICIAL_USE (use, bb_index)
322*38fd1498Szrj     if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
323*38fd1498Szrj       bitmap_set_bit (live, DF_REF_REGNO (use));
324*38fd1498Szrj 
325*38fd1498Szrj   FOR_BB_INSNS_REVERSE (bb, insn)
326*38fd1498Szrj     {
327*38fd1498Szrj       struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
328*38fd1498Szrj       unsigned int regno;
329*38fd1498Szrj 
330*38fd1498Szrj       if (!NONDEBUG_INSN_P (insn))
331*38fd1498Szrj 	continue;
332*38fd1498Szrj 
333*38fd1498Szrj       /* Process the defs.  */
334*38fd1498Szrj       if (CALL_P (insn))
335*38fd1498Szrj 	{
336*38fd1498Szrj 	  bitmap_iterator bi;
337*38fd1498Szrj 	  EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
338*38fd1498Szrj 	    {
339*38fd1498Szrj 	      REG_N_CALLS_CROSSED (regno)++;
340*38fd1498Szrj 	    }
341*38fd1498Szrj 	}
342*38fd1498Szrj 
343*38fd1498Szrj       /* All of the defs except the return value are some sort of
344*38fd1498Szrj 	 clobber.  This code is for the return.  */
345*38fd1498Szrj       FOR_EACH_INSN_INFO_DEF (def, insn_info)
346*38fd1498Szrj 	{
347*38fd1498Szrj 	  if ((!CALL_P (insn))
348*38fd1498Szrj 	      || (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))))
349*38fd1498Szrj 	    {
350*38fd1498Szrj 	      /* Kill this register if it is not a subreg store or conditional store.  */
351*38fd1498Szrj 	      if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
352*38fd1498Szrj 		bitmap_clear_bit (live, DF_REF_REGNO (def));
353*38fd1498Szrj 	    }
354*38fd1498Szrj 	}
355*38fd1498Szrj 
356*38fd1498Szrj       FOR_EACH_INSN_INFO_USE (use, insn_info)
357*38fd1498Szrj 	bitmap_set_bit (live, DF_REF_REGNO (use));
358*38fd1498Szrj     }
359*38fd1498Szrj }
360*38fd1498Szrj 
361*38fd1498Szrj 
362*38fd1498Szrj /* Compute register info: lifetime, bb, and number of defs and uses.  */
363*38fd1498Szrj void
regstat_compute_calls_crossed(void)364*38fd1498Szrj regstat_compute_calls_crossed (void)
365*38fd1498Szrj {
366*38fd1498Szrj   basic_block bb;
367*38fd1498Szrj   bitmap live = BITMAP_ALLOC (&df_bitmap_obstack);
368*38fd1498Szrj 
369*38fd1498Szrj   /* Initialize everything.  */
370*38fd1498Szrj   gcc_assert (!reg_info_p);
371*38fd1498Szrj 
372*38fd1498Szrj   timevar_push (TV_REG_STATS);
373*38fd1498Szrj   max_regno = max_reg_num ();
374*38fd1498Szrj   reg_info_p_size = max_regno;
375*38fd1498Szrj   reg_info_p = XCNEWVEC (struct reg_info_t, max_regno);
376*38fd1498Szrj 
377*38fd1498Szrj   FOR_EACH_BB_FN (bb, cfun)
378*38fd1498Szrj     {
379*38fd1498Szrj       regstat_bb_compute_calls_crossed (bb->index, live);
380*38fd1498Szrj     }
381*38fd1498Szrj 
382*38fd1498Szrj   BITMAP_FREE (live);
383*38fd1498Szrj   timevar_pop (TV_REG_STATS);
384*38fd1498Szrj }
385*38fd1498Szrj 
386*38fd1498Szrj 
387*38fd1498Szrj /* Free all storage associated with the problem.  */
388*38fd1498Szrj 
389*38fd1498Szrj void
regstat_free_calls_crossed(void)390*38fd1498Szrj regstat_free_calls_crossed (void)
391*38fd1498Szrj {
392*38fd1498Szrj   gcc_assert (reg_info_p);
393*38fd1498Szrj   reg_info_p_size = 0;
394*38fd1498Szrj   free (reg_info_p);
395*38fd1498Szrj   reg_info_p = NULL;
396*38fd1498Szrj }
397*38fd1498Szrj 
398*38fd1498Szrj /* Dump the register info to FILE.  */
399*38fd1498Szrj 
400*38fd1498Szrj void
dump_reg_info(FILE * file)401*38fd1498Szrj dump_reg_info (FILE *file)
402*38fd1498Szrj {
403*38fd1498Szrj   unsigned int i, max = max_reg_num ();
404*38fd1498Szrj   if (reload_completed)
405*38fd1498Szrj     return;
406*38fd1498Szrj 
407*38fd1498Szrj   if (reg_info_p_size < max)
408*38fd1498Szrj     max = reg_info_p_size;
409*38fd1498Szrj 
410*38fd1498Szrj   fprintf (file, "%d registers.\n", max);
411*38fd1498Szrj   for (i = FIRST_PSEUDO_REGISTER; i < max; i++)
412*38fd1498Szrj     {
413*38fd1498Szrj       enum reg_class rclass, altclass;
414*38fd1498Szrj 
415*38fd1498Szrj       if (regstat_n_sets_and_refs)
416*38fd1498Szrj 	fprintf (file, "\nRegister %d used %d times",
417*38fd1498Szrj 		 i, REG_N_REFS (i));
418*38fd1498Szrj       else if (df)
419*38fd1498Szrj 	fprintf (file, "\nRegister %d used %d times",
420*38fd1498Szrj 		 i, DF_REG_USE_COUNT (i) + DF_REG_DEF_COUNT (i));
421*38fd1498Szrj 
422*38fd1498Szrj       if (REG_BASIC_BLOCK (i) >= NUM_FIXED_BLOCKS)
423*38fd1498Szrj 	fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
424*38fd1498Szrj       if (regstat_n_sets_and_refs)
425*38fd1498Szrj 	fprintf (file, "; set %d time%s", REG_N_SETS (i),
426*38fd1498Szrj 		 (REG_N_SETS (i) == 1) ? "" : "s");
427*38fd1498Szrj       else if (df)
428*38fd1498Szrj 	fprintf (file, "; set %d time%s", DF_REG_DEF_COUNT (i),
429*38fd1498Szrj 		 (DF_REG_DEF_COUNT (i) == 1) ? "" : "s");
430*38fd1498Szrj       if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
431*38fd1498Szrj 	fputs ("; user var", file);
432*38fd1498Szrj       if (REG_N_DEATHS (i) != 1)
433*38fd1498Szrj 	fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
434*38fd1498Szrj       if (REG_N_CALLS_CROSSED (i) == 1)
435*38fd1498Szrj 	fputs ("; crosses 1 call", file);
436*38fd1498Szrj       else if (REG_N_CALLS_CROSSED (i))
437*38fd1498Szrj 	fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
438*38fd1498Szrj       if (regno_reg_rtx[i] != NULL
439*38fd1498Szrj 	  && maybe_ne (PSEUDO_REGNO_BYTES (i), UNITS_PER_WORD))
440*38fd1498Szrj 	{
441*38fd1498Szrj 	  fprintf (file, "; ");
442*38fd1498Szrj 	  print_dec (PSEUDO_REGNO_BYTES (i), file, SIGNED);
443*38fd1498Szrj 	  fprintf (file, " bytes");
444*38fd1498Szrj 	}
445*38fd1498Szrj 
446*38fd1498Szrj       rclass = reg_preferred_class (i);
447*38fd1498Szrj       altclass = reg_alternate_class (i);
448*38fd1498Szrj       if (rclass != GENERAL_REGS || altclass != ALL_REGS)
449*38fd1498Szrj 	{
450*38fd1498Szrj 	  if (altclass == ALL_REGS || rclass == ALL_REGS)
451*38fd1498Szrj 	    fprintf (file, "; pref %s", reg_class_names[(int) rclass]);
452*38fd1498Szrj 	  else if (altclass == NO_REGS)
453*38fd1498Szrj 	    fprintf (file, "; %s or none", reg_class_names[(int) rclass]);
454*38fd1498Szrj 	  else
455*38fd1498Szrj 	    fprintf (file, "; pref %s, else %s",
456*38fd1498Szrj 		     reg_class_names[(int) rclass],
457*38fd1498Szrj 		     reg_class_names[(int) altclass]);
458*38fd1498Szrj 	}
459*38fd1498Szrj 
460*38fd1498Szrj       if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
461*38fd1498Szrj 	fputs ("; pointer", file);
462*38fd1498Szrj       fputs (".\n", file);
463*38fd1498Szrj     }
464*38fd1498Szrj }
465*38fd1498Szrj 
466