xref: /dragonfly/contrib/gcc-4.7/gcc/regstat.c (revision e4b17023)
1*e4b17023SJohn Marino /* Scanning of rtl for dataflow analysis.
2*e4b17023SJohn Marino    Copyright (C) 2007, 2008, 2009, 2010
3*e4b17023SJohn Marino    Free Software Foundation, Inc.
4*e4b17023SJohn Marino    Contributed by Kenneth Zadeck (zadeck@naturalbridge.com).
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino 
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11*e4b17023SJohn Marino version.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16*e4b17023SJohn Marino for more details.
17*e4b17023SJohn Marino 
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino 
23*e4b17023SJohn Marino #include "config.h"
24*e4b17023SJohn Marino #include "system.h"
25*e4b17023SJohn Marino #include "coretypes.h"
26*e4b17023SJohn Marino #include "tm.h"
27*e4b17023SJohn Marino #include "rtl.h"
28*e4b17023SJohn Marino #include "tm_p.h"
29*e4b17023SJohn Marino #include "flags.h"
30*e4b17023SJohn Marino #include "regs.h"
31*e4b17023SJohn Marino #include "output.h"
32*e4b17023SJohn Marino #include "except.h"
33*e4b17023SJohn Marino #include "hard-reg-set.h"
34*e4b17023SJohn Marino #include "basic-block.h"
35*e4b17023SJohn Marino #include "timevar.h"
36*e4b17023SJohn Marino #include "df.h"
37*e4b17023SJohn Marino 
38*e4b17023SJohn Marino 
39*e4b17023SJohn Marino struct regstat_n_sets_and_refs_t *regstat_n_sets_and_refs;
40*e4b17023SJohn Marino 
41*e4b17023SJohn Marino /*----------------------------------------------------------------------------
42*e4b17023SJohn Marino    REG_N_SETS and REG_N_REFS.
43*e4b17023SJohn Marino    ----------------------------------------------------------------------------*/
44*e4b17023SJohn Marino 
45*e4b17023SJohn Marino /* If a pass need to change these values in some magical way or the
46*e4b17023SJohn Marino    pass needs to have accurate values for these and is not using
47*e4b17023SJohn Marino    incremental df scanning, then it should use REG_N_SETS and
48*e4b17023SJohn Marino    REG_N_USES.  If the pass is doing incremental scanning then it
49*e4b17023SJohn Marino    should be getting the info from DF_REG_DEF_COUNT and
50*e4b17023SJohn Marino    DF_REG_USE_COUNT.  */
51*e4b17023SJohn Marino 
52*e4b17023SJohn Marino void
regstat_init_n_sets_and_refs(void)53*e4b17023SJohn Marino regstat_init_n_sets_and_refs (void)
54*e4b17023SJohn Marino {
55*e4b17023SJohn Marino   unsigned int i;
56*e4b17023SJohn Marino   unsigned int max_regno = max_reg_num ();
57*e4b17023SJohn Marino 
58*e4b17023SJohn Marino   timevar_push (TV_REG_STATS);
59*e4b17023SJohn Marino   df_grow_reg_info ();
60*e4b17023SJohn Marino   gcc_assert (!regstat_n_sets_and_refs);
61*e4b17023SJohn Marino 
62*e4b17023SJohn Marino   regstat_n_sets_and_refs = XNEWVEC (struct regstat_n_sets_and_refs_t, max_regno);
63*e4b17023SJohn Marino 
64*e4b17023SJohn Marino   if (MAY_HAVE_DEBUG_INSNS)
65*e4b17023SJohn Marino     for (i = 0; i < max_regno; i++)
66*e4b17023SJohn Marino       {
67*e4b17023SJohn Marino 	int use_count;
68*e4b17023SJohn Marino 	df_ref use;
69*e4b17023SJohn Marino 
70*e4b17023SJohn Marino 	use_count = DF_REG_USE_COUNT (i);
71*e4b17023SJohn Marino 	for (use = DF_REG_USE_CHAIN (i); use; use = DF_REF_NEXT_REG (use))
72*e4b17023SJohn Marino 	  if (DF_REF_INSN_INFO (use) && DEBUG_INSN_P (DF_REF_INSN (use)))
73*e4b17023SJohn Marino 	    use_count--;
74*e4b17023SJohn Marino 
75*e4b17023SJohn Marino 
76*e4b17023SJohn Marino 	SET_REG_N_SETS (i, DF_REG_DEF_COUNT (i));
77*e4b17023SJohn Marino 	SET_REG_N_REFS (i, use_count + REG_N_SETS (i));
78*e4b17023SJohn Marino       }
79*e4b17023SJohn Marino   else
80*e4b17023SJohn Marino     for (i = 0; i < max_regno; i++)
81*e4b17023SJohn Marino       {
82*e4b17023SJohn Marino 	SET_REG_N_SETS (i, DF_REG_DEF_COUNT (i));
83*e4b17023SJohn Marino 	SET_REG_N_REFS (i, DF_REG_USE_COUNT (i) + REG_N_SETS (i));
84*e4b17023SJohn Marino       }
85*e4b17023SJohn Marino   timevar_pop (TV_REG_STATS);
86*e4b17023SJohn Marino 
87*e4b17023SJohn Marino }
88*e4b17023SJohn Marino 
89*e4b17023SJohn Marino 
90*e4b17023SJohn Marino /* Free the array that holds the REG_N_SETS and REG_N_REFS.  */
91*e4b17023SJohn Marino 
92*e4b17023SJohn Marino void
regstat_free_n_sets_and_refs(void)93*e4b17023SJohn Marino regstat_free_n_sets_and_refs (void)
94*e4b17023SJohn Marino {
95*e4b17023SJohn Marino   gcc_assert (regstat_n_sets_and_refs);
96*e4b17023SJohn Marino   free (regstat_n_sets_and_refs);
97*e4b17023SJohn Marino   regstat_n_sets_and_refs = NULL;
98*e4b17023SJohn Marino }
99*e4b17023SJohn Marino 
100*e4b17023SJohn Marino 
101*e4b17023SJohn Marino /*----------------------------------------------------------------------------
102*e4b17023SJohn Marino    REGISTER INFORMATION
103*e4b17023SJohn Marino 
104*e4b17023SJohn Marino    Process REG_N_DEATHS, REG_LIVE_LENGTH, REG_N_CALLS_CROSSED,
105*e4b17023SJohn Marino    REG_N_THROWING_CALLS_CROSSED and REG_BASIC_BLOCK.
106*e4b17023SJohn Marino 
107*e4b17023SJohn Marino    ----------------------------------------------------------------------------*/
108*e4b17023SJohn Marino 
109*e4b17023SJohn Marino static bitmap setjmp_crosses;
110*e4b17023SJohn Marino struct reg_info_t *reg_info_p;
111*e4b17023SJohn Marino 
112*e4b17023SJohn Marino /* The number allocated elements of reg_info_p.  */
113*e4b17023SJohn Marino size_t reg_info_p_size;
114*e4b17023SJohn Marino 
115*e4b17023SJohn Marino /* Compute register info: lifetime, bb, and number of defs and uses
116*e4b17023SJohn Marino    for basic block BB.  The three bitvectors are scratch regs used
117*e4b17023SJohn Marino    here.  */
118*e4b17023SJohn Marino 
119*e4b17023SJohn Marino static void
regstat_bb_compute_ri(unsigned int bb_index,bitmap live,bitmap do_not_gen,bitmap artificial_uses,bitmap local_live,bitmap local_processed)120*e4b17023SJohn Marino regstat_bb_compute_ri (unsigned int bb_index,
121*e4b17023SJohn Marino 		       bitmap live, bitmap do_not_gen, bitmap artificial_uses,
122*e4b17023SJohn Marino 		       bitmap local_live, bitmap local_processed)
123*e4b17023SJohn Marino {
124*e4b17023SJohn Marino   basic_block bb = BASIC_BLOCK (bb_index);
125*e4b17023SJohn Marino   rtx insn;
126*e4b17023SJohn Marino   df_ref *def_rec;
127*e4b17023SJohn Marino   df_ref *use_rec;
128*e4b17023SJohn Marino   int luid = 0;
129*e4b17023SJohn Marino   bitmap_iterator bi;
130*e4b17023SJohn Marino   unsigned int regno;
131*e4b17023SJohn Marino 
132*e4b17023SJohn Marino   bitmap_copy (live, df_get_live_out (bb));
133*e4b17023SJohn Marino   bitmap_clear (artificial_uses);
134*e4b17023SJohn Marino 
135*e4b17023SJohn Marino   /* Process the regs live at the end of the block.  Mark them as
136*e4b17023SJohn Marino      not local to any one basic block.  */
137*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
138*e4b17023SJohn Marino     REG_BASIC_BLOCK (regno) = REG_BLOCK_GLOBAL;
139*e4b17023SJohn Marino 
140*e4b17023SJohn Marino   /* Process the artificial defs and uses at the bottom of the block
141*e4b17023SJohn Marino      to begin processing.  */
142*e4b17023SJohn Marino   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
143*e4b17023SJohn Marino     {
144*e4b17023SJohn Marino       df_ref def = *def_rec;
145*e4b17023SJohn Marino       if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
146*e4b17023SJohn Marino 	bitmap_clear_bit (live, DF_REF_REGNO (def));
147*e4b17023SJohn Marino     }
148*e4b17023SJohn Marino 
149*e4b17023SJohn Marino   for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
150*e4b17023SJohn Marino     {
151*e4b17023SJohn Marino       df_ref use = *use_rec;
152*e4b17023SJohn Marino       if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
153*e4b17023SJohn Marino 	{
154*e4b17023SJohn Marino 	  regno = DF_REF_REGNO (use);
155*e4b17023SJohn Marino 	  bitmap_set_bit (live, regno);
156*e4b17023SJohn Marino 	  bitmap_set_bit (artificial_uses, regno);
157*e4b17023SJohn Marino 	}
158*e4b17023SJohn Marino     }
159*e4b17023SJohn Marino 
160*e4b17023SJohn Marino   FOR_BB_INSNS_REVERSE (bb, insn)
161*e4b17023SJohn Marino     {
162*e4b17023SJohn Marino       unsigned int uid = INSN_UID (insn);
163*e4b17023SJohn Marino       unsigned int regno;
164*e4b17023SJohn Marino       bitmap_iterator bi;
165*e4b17023SJohn Marino       struct df_mw_hardreg **mws_rec;
166*e4b17023SJohn Marino       rtx link;
167*e4b17023SJohn Marino 
168*e4b17023SJohn Marino       if (!NONDEBUG_INSN_P (insn))
169*e4b17023SJohn Marino 	continue;
170*e4b17023SJohn Marino 
171*e4b17023SJohn Marino       /* Increment the live_length for all of the registers that
172*e4b17023SJohn Marino 	 are are referenced in this block and live at this
173*e4b17023SJohn Marino 	 particular point.  */
174*e4b17023SJohn Marino       EXECUTE_IF_SET_IN_BITMAP (local_live, 0, regno, bi)
175*e4b17023SJohn Marino 	{
176*e4b17023SJohn Marino 	  REG_LIVE_LENGTH (regno)++;
177*e4b17023SJohn Marino 	}
178*e4b17023SJohn Marino       luid++;
179*e4b17023SJohn Marino 
180*e4b17023SJohn Marino       bitmap_clear (do_not_gen);
181*e4b17023SJohn Marino 
182*e4b17023SJohn Marino       link = REG_NOTES (insn);
183*e4b17023SJohn Marino       while (link)
184*e4b17023SJohn Marino 	{
185*e4b17023SJohn Marino 	  if (REG_NOTE_KIND (link) == REG_DEAD)
186*e4b17023SJohn Marino 	    REG_N_DEATHS(REGNO (XEXP (link, 0)))++;
187*e4b17023SJohn Marino 	  link = XEXP (link, 1);
188*e4b17023SJohn Marino 	}
189*e4b17023SJohn Marino 
190*e4b17023SJohn Marino       /* Process the defs.  */
191*e4b17023SJohn Marino       if (CALL_P (insn))
192*e4b17023SJohn Marino 	{
193*e4b17023SJohn Marino 	  bool can_throw = can_throw_internal (insn);
194*e4b17023SJohn Marino 	  bool set_jump = (find_reg_note (insn, REG_SETJMP, NULL) != NULL);
195*e4b17023SJohn Marino 	  EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
196*e4b17023SJohn Marino 	    {
197*e4b17023SJohn Marino 	      REG_N_CALLS_CROSSED (regno)++;
198*e4b17023SJohn Marino 	      REG_FREQ_CALLS_CROSSED (regno) += REG_FREQ_FROM_BB (bb);
199*e4b17023SJohn Marino 	      if (can_throw)
200*e4b17023SJohn Marino 		REG_N_THROWING_CALLS_CROSSED (regno)++;
201*e4b17023SJohn Marino 
202*e4b17023SJohn Marino 	      /* We have a problem with any pseudoreg that lives
203*e4b17023SJohn Marino 		 across the setjmp.  ANSI says that if a user variable
204*e4b17023SJohn Marino 		 does not change in value between the setjmp and the
205*e4b17023SJohn Marino 		 longjmp, then the longjmp preserves it.  This
206*e4b17023SJohn Marino 		 includes longjmp from a place where the pseudo
207*e4b17023SJohn Marino 		 appears dead.  (In principle, the value still exists
208*e4b17023SJohn Marino 		 if it is in scope.)  If the pseudo goes in a hard
209*e4b17023SJohn Marino 		 reg, some other value may occupy that hard reg where
210*e4b17023SJohn Marino 		 this pseudo is dead, thus clobbering the pseudo.
211*e4b17023SJohn Marino 		 Conclusion: such a pseudo must not go in a hard
212*e4b17023SJohn Marino 		 reg.  */
213*e4b17023SJohn Marino 	      if (set_jump)
214*e4b17023SJohn Marino 		bitmap_set_bit (setjmp_crosses, regno);
215*e4b17023SJohn Marino 	    }
216*e4b17023SJohn Marino 	}
217*e4b17023SJohn Marino 
218*e4b17023SJohn Marino       /* We only care about real sets for calls.  Clobbers only
219*e4b17023SJohn Marino 	 may clobbers cannot be depended on.  */
220*e4b17023SJohn Marino       for (mws_rec = DF_INSN_UID_MWS (uid); *mws_rec; mws_rec++)
221*e4b17023SJohn Marino 	{
222*e4b17023SJohn Marino 	  struct df_mw_hardreg *mws = *mws_rec;
223*e4b17023SJohn Marino 	  if (DF_MWS_REG_DEF_P (mws))
224*e4b17023SJohn Marino 	    {
225*e4b17023SJohn Marino 	      bool all_dead = true;
226*e4b17023SJohn Marino 	      unsigned int r;
227*e4b17023SJohn Marino 
228*e4b17023SJohn Marino 	      for (r=mws->start_regno; r <= mws->end_regno; r++)
229*e4b17023SJohn Marino 		if ((bitmap_bit_p (live, r))
230*e4b17023SJohn Marino 		    || bitmap_bit_p (artificial_uses, r))
231*e4b17023SJohn Marino 		  {
232*e4b17023SJohn Marino 		    all_dead = false;
233*e4b17023SJohn Marino 		    break;
234*e4b17023SJohn Marino 		  }
235*e4b17023SJohn Marino 
236*e4b17023SJohn Marino 	      if (all_dead)
237*e4b17023SJohn Marino 		{
238*e4b17023SJohn Marino 		  unsigned int regno = mws->start_regno;
239*e4b17023SJohn Marino 		  bitmap_set_bit (do_not_gen, regno);
240*e4b17023SJohn Marino 		  /* Only do this if the value is totally dead.  */
241*e4b17023SJohn Marino 		  REG_LIVE_LENGTH (regno)++;
242*e4b17023SJohn Marino 		}
243*e4b17023SJohn Marino 	    }
244*e4b17023SJohn Marino 	}
245*e4b17023SJohn Marino 
246*e4b17023SJohn Marino       /* All of the defs except the return value are some sort of
247*e4b17023SJohn Marino 	 clobber.  This code is for the return.  */
248*e4b17023SJohn Marino       for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
249*e4b17023SJohn Marino 	{
250*e4b17023SJohn Marino 	  df_ref def = *def_rec;
251*e4b17023SJohn Marino 	  if ((!CALL_P (insn))
252*e4b17023SJohn Marino 	      || (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))))
253*e4b17023SJohn Marino 	    {
254*e4b17023SJohn Marino 	      unsigned int dregno = DF_REF_REGNO (def);
255*e4b17023SJohn Marino 
256*e4b17023SJohn Marino 	      if (bitmap_bit_p (live, dregno))
257*e4b17023SJohn Marino 		{
258*e4b17023SJohn Marino 		  /* If we have seen this regno, then it has already been
259*e4b17023SJohn Marino 		     processed correctly with the per insn increment.  If we
260*e4b17023SJohn Marino 		     have not seen it we need to add the length from here to
261*e4b17023SJohn Marino 		     the end of the block to the live length.  */
262*e4b17023SJohn Marino 		  if (bitmap_bit_p (local_processed, dregno))
263*e4b17023SJohn Marino 		    {
264*e4b17023SJohn Marino 		      if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
265*e4b17023SJohn Marino 			bitmap_clear_bit (local_live, dregno);
266*e4b17023SJohn Marino 		    }
267*e4b17023SJohn Marino 		  else
268*e4b17023SJohn Marino 		    {
269*e4b17023SJohn Marino 		      bitmap_set_bit (local_processed, dregno);
270*e4b17023SJohn Marino 		      REG_LIVE_LENGTH (dregno) += luid;
271*e4b17023SJohn Marino 		    }
272*e4b17023SJohn Marino 		}
273*e4b17023SJohn Marino 	      else if ((!(DF_REF_FLAGS (def) & DF_REF_MW_HARDREG))
274*e4b17023SJohn Marino 		       && (!bitmap_bit_p (artificial_uses, dregno)))
275*e4b17023SJohn Marino 		{
276*e4b17023SJohn Marino 		  REG_LIVE_LENGTH (dregno)++;
277*e4b17023SJohn Marino 		}
278*e4b17023SJohn Marino 
279*e4b17023SJohn Marino 	      if (dregno >= FIRST_PSEUDO_REGISTER)
280*e4b17023SJohn Marino 		{
281*e4b17023SJohn Marino 		  REG_FREQ (dregno) += REG_FREQ_FROM_BB (bb);
282*e4b17023SJohn Marino 		  if (REG_BASIC_BLOCK (dregno) == REG_BLOCK_UNKNOWN)
283*e4b17023SJohn Marino 		    REG_BASIC_BLOCK (dregno) = bb->index;
284*e4b17023SJohn Marino 		  else if (REG_BASIC_BLOCK (dregno) != bb->index)
285*e4b17023SJohn Marino 		    REG_BASIC_BLOCK (dregno) = REG_BLOCK_GLOBAL;
286*e4b17023SJohn Marino 		}
287*e4b17023SJohn Marino 
288*e4b17023SJohn Marino 	      if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER + DF_REF_MAY_CLOBBER)))
289*e4b17023SJohn Marino 		bitmap_set_bit (do_not_gen, dregno);
290*e4b17023SJohn Marino 
291*e4b17023SJohn Marino 	      /* Kill this register if it is not a subreg store or conditional store.  */
292*e4b17023SJohn Marino 	      if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
293*e4b17023SJohn Marino 		bitmap_clear_bit (live, dregno);
294*e4b17023SJohn Marino 	    }
295*e4b17023SJohn Marino 	}
296*e4b17023SJohn Marino 
297*e4b17023SJohn Marino       for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
298*e4b17023SJohn Marino 	{
299*e4b17023SJohn Marino 	  df_ref use = *use_rec;
300*e4b17023SJohn Marino 	  unsigned int uregno = DF_REF_REGNO (use);
301*e4b17023SJohn Marino 
302*e4b17023SJohn Marino 	  if (uregno >= FIRST_PSEUDO_REGISTER)
303*e4b17023SJohn Marino 	    {
304*e4b17023SJohn Marino 	      REG_FREQ (uregno) += REG_FREQ_FROM_BB (bb);
305*e4b17023SJohn Marino 	      if (REG_BASIC_BLOCK (uregno) == REG_BLOCK_UNKNOWN)
306*e4b17023SJohn Marino 		REG_BASIC_BLOCK (uregno) = bb->index;
307*e4b17023SJohn Marino 	      else if (REG_BASIC_BLOCK (uregno) != bb->index)
308*e4b17023SJohn Marino 		REG_BASIC_BLOCK (uregno) = REG_BLOCK_GLOBAL;
309*e4b17023SJohn Marino 	    }
310*e4b17023SJohn Marino 
311*e4b17023SJohn Marino 	  if (bitmap_set_bit (live, uregno))
312*e4b17023SJohn Marino 	    {
313*e4b17023SJohn Marino 	      /* This register is now live.  */
314*e4b17023SJohn Marino 
315*e4b17023SJohn Marino 	      /* If we have seen this regno, then it has already been
316*e4b17023SJohn Marino 		 processed correctly with the per insn increment.  If
317*e4b17023SJohn Marino 		 we have not seen it we set the bit so that begins to
318*e4b17023SJohn Marino 		 get processed locally.  Note that we don't even get
319*e4b17023SJohn Marino 		 here if the variable was live at the end of the block
320*e4b17023SJohn Marino 		 since just a ref inside the block does not effect the
321*e4b17023SJohn Marino 		 calculations.  */
322*e4b17023SJohn Marino 	      REG_LIVE_LENGTH (uregno) ++;
323*e4b17023SJohn Marino 	      bitmap_set_bit (local_live, uregno);
324*e4b17023SJohn Marino 	      bitmap_set_bit (local_processed, uregno);
325*e4b17023SJohn Marino 	    }
326*e4b17023SJohn Marino 	}
327*e4b17023SJohn Marino     }
328*e4b17023SJohn Marino 
329*e4b17023SJohn Marino   /* Add the length of the block to all of the registers that were not
330*e4b17023SJohn Marino      referenced, but still live in this block.  */
331*e4b17023SJohn Marino   bitmap_and_compl_into (live, local_processed);
332*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
333*e4b17023SJohn Marino     REG_LIVE_LENGTH (regno) += luid;
334*e4b17023SJohn Marino 
335*e4b17023SJohn Marino   bitmap_clear (local_processed);
336*e4b17023SJohn Marino   bitmap_clear (local_live);
337*e4b17023SJohn Marino }
338*e4b17023SJohn Marino 
339*e4b17023SJohn Marino 
340*e4b17023SJohn Marino /* Compute register info: lifetime, bb, and number of defs and uses.  */
341*e4b17023SJohn Marino void
regstat_compute_ri(void)342*e4b17023SJohn Marino regstat_compute_ri (void)
343*e4b17023SJohn Marino {
344*e4b17023SJohn Marino   basic_block bb;
345*e4b17023SJohn Marino   bitmap live = BITMAP_ALLOC (&df_bitmap_obstack);
346*e4b17023SJohn Marino   bitmap do_not_gen = BITMAP_ALLOC (&df_bitmap_obstack);
347*e4b17023SJohn Marino   bitmap artificial_uses = BITMAP_ALLOC (&df_bitmap_obstack);
348*e4b17023SJohn Marino   bitmap local_live = BITMAP_ALLOC (&df_bitmap_obstack);
349*e4b17023SJohn Marino   bitmap local_processed = BITMAP_ALLOC (&df_bitmap_obstack);
350*e4b17023SJohn Marino   unsigned int regno;
351*e4b17023SJohn Marino   bitmap_iterator bi;
352*e4b17023SJohn Marino 
353*e4b17023SJohn Marino   /* Initialize everything.  */
354*e4b17023SJohn Marino 
355*e4b17023SJohn Marino   gcc_assert (!reg_info_p);
356*e4b17023SJohn Marino 
357*e4b17023SJohn Marino   timevar_push (TV_REG_STATS);
358*e4b17023SJohn Marino   setjmp_crosses = BITMAP_ALLOC (&df_bitmap_obstack);
359*e4b17023SJohn Marino   max_regno = max_reg_num ();
360*e4b17023SJohn Marino   reg_info_p_size = max_regno;
361*e4b17023SJohn Marino   reg_info_p = XCNEWVEC (struct reg_info_t, max_regno);
362*e4b17023SJohn Marino 
363*e4b17023SJohn Marino   FOR_EACH_BB (bb)
364*e4b17023SJohn Marino     {
365*e4b17023SJohn Marino       regstat_bb_compute_ri (bb->index, live, do_not_gen, artificial_uses,
366*e4b17023SJohn Marino 			     local_live, local_processed);
367*e4b17023SJohn Marino     }
368*e4b17023SJohn Marino 
369*e4b17023SJohn Marino   BITMAP_FREE (live);
370*e4b17023SJohn Marino   BITMAP_FREE (do_not_gen);
371*e4b17023SJohn Marino   BITMAP_FREE (artificial_uses);
372*e4b17023SJohn Marino 
373*e4b17023SJohn Marino   /* See the setjmp comment in regstat_ri_bb_compute.  */
374*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (setjmp_crosses, FIRST_PSEUDO_REGISTER, regno, bi)
375*e4b17023SJohn Marino     {
376*e4b17023SJohn Marino       REG_BASIC_BLOCK (regno) = REG_BLOCK_UNKNOWN;
377*e4b17023SJohn Marino       REG_LIVE_LENGTH (regno) = -1;
378*e4b17023SJohn Marino     }
379*e4b17023SJohn Marino 
380*e4b17023SJohn Marino   BITMAP_FREE (local_live);
381*e4b17023SJohn Marino   BITMAP_FREE (local_processed);
382*e4b17023SJohn Marino   timevar_pop (TV_REG_STATS);
383*e4b17023SJohn Marino }
384*e4b17023SJohn Marino 
385*e4b17023SJohn Marino 
386*e4b17023SJohn Marino /* Free all storage associated with the problem.  */
387*e4b17023SJohn Marino 
388*e4b17023SJohn Marino void
regstat_free_ri(void)389*e4b17023SJohn Marino regstat_free_ri (void)
390*e4b17023SJohn Marino {
391*e4b17023SJohn Marino   gcc_assert (reg_info_p);
392*e4b17023SJohn Marino   reg_info_p_size = 0;
393*e4b17023SJohn Marino   free (reg_info_p);
394*e4b17023SJohn Marino   reg_info_p = NULL;
395*e4b17023SJohn Marino 
396*e4b17023SJohn Marino   BITMAP_FREE (setjmp_crosses);
397*e4b17023SJohn Marino }
398*e4b17023SJohn Marino 
399*e4b17023SJohn Marino 
400*e4b17023SJohn Marino /* Return a bitmap containing the set of registers that cross a setjmp.
401*e4b17023SJohn Marino    The client should not change or delete this bitmap.  */
402*e4b17023SJohn Marino 
403*e4b17023SJohn Marino bitmap
regstat_get_setjmp_crosses(void)404*e4b17023SJohn Marino regstat_get_setjmp_crosses (void)
405*e4b17023SJohn Marino {
406*e4b17023SJohn Marino   return setjmp_crosses;
407*e4b17023SJohn Marino }
408*e4b17023SJohn Marino 
409*e4b17023SJohn Marino /*----------------------------------------------------------------------------
410*e4b17023SJohn Marino    Process REG_N_CALLS_CROSSED.
411*e4b17023SJohn Marino 
412*e4b17023SJohn Marino    This is used by sched_deps.  A good implementation of sched-deps
413*e4b17023SJohn Marino    would really process the blocks directly rather than going through
414*e4b17023SJohn Marino    lists of insns.  If it did this, it could use the exact regs that
415*e4b17023SJohn Marino    cross an individual call rather than using this info that merges
416*e4b17023SJohn Marino    the info for all calls.
417*e4b17023SJohn Marino 
418*e4b17023SJohn Marino    ----------------------------------------------------------------------------*/
419*e4b17023SJohn Marino 
420*e4b17023SJohn Marino 
421*e4b17023SJohn Marino 
422*e4b17023SJohn Marino /* Compute calls crossed for BB. Live is a scratch bitvector.  */
423*e4b17023SJohn Marino 
424*e4b17023SJohn Marino static void
regstat_bb_compute_calls_crossed(unsigned int bb_index,bitmap live)425*e4b17023SJohn Marino regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live)
426*e4b17023SJohn Marino {
427*e4b17023SJohn Marino   basic_block bb = BASIC_BLOCK (bb_index);
428*e4b17023SJohn Marino   rtx insn;
429*e4b17023SJohn Marino   df_ref *def_rec;
430*e4b17023SJohn Marino   df_ref *use_rec;
431*e4b17023SJohn Marino 
432*e4b17023SJohn Marino   bitmap_copy (live, df_get_live_out (bb));
433*e4b17023SJohn Marino 
434*e4b17023SJohn Marino   /* Process the artificial defs and uses at the bottom of the block
435*e4b17023SJohn Marino      to begin processing.  */
436*e4b17023SJohn Marino   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
437*e4b17023SJohn Marino     {
438*e4b17023SJohn Marino       df_ref def = *def_rec;
439*e4b17023SJohn Marino       if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
440*e4b17023SJohn Marino 	bitmap_clear_bit (live, DF_REF_REGNO (def));
441*e4b17023SJohn Marino     }
442*e4b17023SJohn Marino 
443*e4b17023SJohn Marino   for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
444*e4b17023SJohn Marino     {
445*e4b17023SJohn Marino       df_ref use = *use_rec;
446*e4b17023SJohn Marino       if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
447*e4b17023SJohn Marino 	bitmap_set_bit (live, DF_REF_REGNO (use));
448*e4b17023SJohn Marino     }
449*e4b17023SJohn Marino 
450*e4b17023SJohn Marino   FOR_BB_INSNS_REVERSE (bb, insn)
451*e4b17023SJohn Marino     {
452*e4b17023SJohn Marino       unsigned int uid = INSN_UID (insn);
453*e4b17023SJohn Marino       unsigned int regno;
454*e4b17023SJohn Marino 
455*e4b17023SJohn Marino       if (!INSN_P (insn))
456*e4b17023SJohn Marino 	continue;
457*e4b17023SJohn Marino 
458*e4b17023SJohn Marino       /* Process the defs.  */
459*e4b17023SJohn Marino       if (CALL_P (insn))
460*e4b17023SJohn Marino 	{
461*e4b17023SJohn Marino 	  bitmap_iterator bi;
462*e4b17023SJohn Marino 	  EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
463*e4b17023SJohn Marino 	    {
464*e4b17023SJohn Marino 	      REG_N_CALLS_CROSSED (regno)++;
465*e4b17023SJohn Marino 	      REG_FREQ_CALLS_CROSSED (regno) += REG_FREQ_FROM_BB (bb);
466*e4b17023SJohn Marino 	    }
467*e4b17023SJohn Marino 	}
468*e4b17023SJohn Marino 
469*e4b17023SJohn Marino       /* All of the defs except the return value are some sort of
470*e4b17023SJohn Marino 	 clobber.  This code is for the return.  */
471*e4b17023SJohn Marino       for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
472*e4b17023SJohn Marino 	{
473*e4b17023SJohn Marino 	  df_ref def = *def_rec;
474*e4b17023SJohn Marino 	  if ((!CALL_P (insn))
475*e4b17023SJohn Marino 	      || (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))))
476*e4b17023SJohn Marino 	    {
477*e4b17023SJohn Marino 	      /* Kill this register if it is not a subreg store or conditional store.  */
478*e4b17023SJohn Marino 	      if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
479*e4b17023SJohn Marino 		bitmap_clear_bit (live, DF_REF_REGNO (def));
480*e4b17023SJohn Marino 	    }
481*e4b17023SJohn Marino 	}
482*e4b17023SJohn Marino 
483*e4b17023SJohn Marino       for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
484*e4b17023SJohn Marino 	{
485*e4b17023SJohn Marino 	  df_ref use = *use_rec;
486*e4b17023SJohn Marino 	  bitmap_set_bit (live, DF_REF_REGNO (use));
487*e4b17023SJohn Marino 	}
488*e4b17023SJohn Marino     }
489*e4b17023SJohn Marino }
490*e4b17023SJohn Marino 
491*e4b17023SJohn Marino 
492*e4b17023SJohn Marino /* Compute register info: lifetime, bb, and number of defs and uses.  */
493*e4b17023SJohn Marino void
regstat_compute_calls_crossed(void)494*e4b17023SJohn Marino regstat_compute_calls_crossed (void)
495*e4b17023SJohn Marino {
496*e4b17023SJohn Marino   basic_block bb;
497*e4b17023SJohn Marino   bitmap live = BITMAP_ALLOC (&df_bitmap_obstack);
498*e4b17023SJohn Marino 
499*e4b17023SJohn Marino   /* Initialize everything.  */
500*e4b17023SJohn Marino   gcc_assert (!reg_info_p);
501*e4b17023SJohn Marino 
502*e4b17023SJohn Marino   timevar_push (TV_REG_STATS);
503*e4b17023SJohn Marino   max_regno = max_reg_num ();
504*e4b17023SJohn Marino   reg_info_p_size = max_regno;
505*e4b17023SJohn Marino   reg_info_p = XCNEWVEC (struct reg_info_t, max_regno);
506*e4b17023SJohn Marino 
507*e4b17023SJohn Marino   FOR_EACH_BB (bb)
508*e4b17023SJohn Marino     {
509*e4b17023SJohn Marino       regstat_bb_compute_calls_crossed (bb->index, live);
510*e4b17023SJohn Marino     }
511*e4b17023SJohn Marino 
512*e4b17023SJohn Marino   BITMAP_FREE (live);
513*e4b17023SJohn Marino   timevar_pop (TV_REG_STATS);
514*e4b17023SJohn Marino }
515*e4b17023SJohn Marino 
516*e4b17023SJohn Marino 
517*e4b17023SJohn Marino /* Free all storage associated with the problem.  */
518*e4b17023SJohn Marino 
519*e4b17023SJohn Marino void
regstat_free_calls_crossed(void)520*e4b17023SJohn Marino regstat_free_calls_crossed (void)
521*e4b17023SJohn Marino {
522*e4b17023SJohn Marino   gcc_assert (reg_info_p);
523*e4b17023SJohn Marino   reg_info_p_size = 0;
524*e4b17023SJohn Marino   free (reg_info_p);
525*e4b17023SJohn Marino   reg_info_p = NULL;
526*e4b17023SJohn Marino }
527*e4b17023SJohn Marino 
528