Mercurial > hg > CbC > CbC_gcc
comparison gcc/regstat.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Scanning of rtl for dataflow analysis. | 1 /* Scanning of rtl for dataflow analysis. |
2 Copyright (C) 2007, 2008, 2009, 2010 | 2 Copyright (C) 2007-2017 Free Software Foundation, Inc. |
3 Free Software Foundation, Inc. | |
4 Contributed by Kenneth Zadeck (zadeck@naturalbridge.com). | 3 Contributed by Kenneth Zadeck (zadeck@naturalbridge.com). |
5 | 4 |
6 This file is part of GCC. | 5 This file is part of GCC. |
7 | 6 |
8 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
21 | 20 |
22 | 21 |
23 #include "config.h" | 22 #include "config.h" |
24 #include "system.h" | 23 #include "system.h" |
25 #include "coretypes.h" | 24 #include "coretypes.h" |
26 #include "tm.h" | 25 #include "backend.h" |
27 #include "rtl.h" | 26 #include "rtl.h" |
28 #include "tm_p.h" | 27 #include "predict.h" |
29 #include "flags.h" | 28 #include "df.h" |
30 #include "regs.h" | 29 #include "regs.h" |
31 #include "output.h" | |
32 #include "except.h" | |
33 #include "hard-reg-set.h" | |
34 #include "basic-block.h" | |
35 #include "timevar.h" | |
36 #include "df.h" | |
37 | 30 |
38 | 31 |
39 struct regstat_n_sets_and_refs_t *regstat_n_sets_and_refs; | 32 struct regstat_n_sets_and_refs_t *regstat_n_sets_and_refs; |
40 | 33 |
41 /*---------------------------------------------------------------------------- | 34 /*---------------------------------------------------------------------------- |
42 REG_N_SETS and REG_N_REFS. | 35 REG_N_SETS and REG_N_REFS. |
43 ----------------------------------------------------------------------------*/ | 36 ----------------------------------------------------------------------------*/ |
44 | 37 |
45 /* If a pass need to change these values in some magical way or or the | 38 /* If a pass need to change these values in some magical way or the |
46 pass needs to have accurate values for these and is not using | 39 pass needs to have accurate values for these and is not using |
47 incremental df scanning, then it should use REG_N_SETS and | 40 incremental df scanning, then it should use REG_N_SETS and |
48 REG_N_USES. If the pass is doing incremental scanning then it | 41 REG_N_USES. If the pass is doing incremental scanning then it |
49 should be getting the info from DF_REG_DEF_COUNT and | 42 should be getting the info from DF_REG_DEF_COUNT and |
50 DF_REG_USE_COUNT. */ | 43 DF_REG_USE_COUNT. */ |
99 | 92 |
100 | 93 |
101 /*---------------------------------------------------------------------------- | 94 /*---------------------------------------------------------------------------- |
102 REGISTER INFORMATION | 95 REGISTER INFORMATION |
103 | 96 |
104 Process REG_N_DEATHS, REG_LIVE_LENGTH, REG_N_CALLS_CROSSED, | 97 Process REG_N_DEATHS, REG_N_CALLS_CROSSED, and REG_BASIC_BLOCK. |
105 REG_N_THROWING_CALLS_CROSSED and REG_BASIC_BLOCK. | |
106 | 98 |
107 ----------------------------------------------------------------------------*/ | 99 ----------------------------------------------------------------------------*/ |
108 | 100 |
109 static bitmap setjmp_crosses; | 101 static bitmap setjmp_crosses; |
110 struct reg_info_t *reg_info_p; | 102 struct reg_info_t *reg_info_p; |
111 | 103 |
112 /* The number allocated elements of reg_info_p. */ | 104 /* The number allocated elements of reg_info_p. */ |
113 size_t reg_info_p_size; | 105 size_t reg_info_p_size; |
114 | 106 |
115 /* Compute register info: lifetime, bb, and number of defs and uses | 107 /* Compute register info: lifetime, bb, and number of defs and uses |
116 for basic block BB. The three bitvectors are scratch regs used | 108 for basic block BB. LIVE is a scratch bitvector used here. */ |
117 here. */ | |
118 | 109 |
119 static void | 110 static void |
120 regstat_bb_compute_ri (unsigned int bb_index, | 111 regstat_bb_compute_ri (basic_block bb, bitmap live) |
121 bitmap live, bitmap do_not_gen, bitmap artificial_uses, | 112 { |
122 bitmap local_live, bitmap local_processed) | 113 rtx_insn *insn; |
123 { | 114 df_ref def, use; |
124 basic_block bb = BASIC_BLOCK (bb_index); | |
125 rtx insn; | |
126 df_ref *def_rec; | |
127 df_ref *use_rec; | |
128 int luid = 0; | |
129 bitmap_iterator bi; | 115 bitmap_iterator bi; |
130 unsigned int regno; | 116 unsigned int regno; |
131 | 117 |
132 bitmap_copy (live, df_get_live_out (bb)); | 118 bitmap_copy (live, df_get_live_out (bb)); |
133 bitmap_clear (artificial_uses); | |
134 | 119 |
135 /* Process the regs live at the end of the block. Mark them as | 120 /* Process the regs live at the end of the block. Mark them as |
136 not local to any one basic block. */ | 121 not local to any one basic block. */ |
137 EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi) | 122 EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi) |
138 REG_BASIC_BLOCK (regno) = REG_BLOCK_GLOBAL; | 123 REG_BASIC_BLOCK (regno) = REG_BLOCK_GLOBAL; |
139 | 124 |
140 /* Process the artificial defs and uses at the bottom of the block | 125 /* Process the artificial defs and uses at the bottom of the block |
141 to begin processing. */ | 126 to begin processing. */ |
142 for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) | 127 FOR_EACH_ARTIFICIAL_DEF (def, bb->index) |
143 { | 128 if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) |
144 df_ref def = *def_rec; | 129 bitmap_clear_bit (live, DF_REF_REGNO (def)); |
145 if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) | 130 |
146 bitmap_clear_bit (live, DF_REF_REGNO (def)); | 131 FOR_EACH_ARTIFICIAL_USE (use, bb->index) |
147 } | 132 if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) |
148 | 133 { |
149 for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++) | 134 regno = DF_REF_REGNO (use); |
150 { | 135 bitmap_set_bit (live, regno); |
151 df_ref use = *use_rec; | 136 } |
152 if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) | |
153 { | |
154 regno = DF_REF_REGNO (use); | |
155 bitmap_set_bit (live, regno); | |
156 bitmap_set_bit (artificial_uses, regno); | |
157 } | |
158 } | |
159 | 137 |
160 FOR_BB_INSNS_REVERSE (bb, insn) | 138 FOR_BB_INSNS_REVERSE (bb, insn) |
161 { | 139 { |
162 unsigned int uid = INSN_UID (insn); | 140 struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); |
163 unsigned int regno; | |
164 bitmap_iterator bi; | 141 bitmap_iterator bi; |
165 struct df_mw_hardreg **mws_rec; | |
166 rtx link; | 142 rtx link; |
167 | 143 |
168 if (!NONDEBUG_INSN_P (insn)) | 144 if (!NONDEBUG_INSN_P (insn)) |
169 continue; | 145 continue; |
170 | 146 |
171 /* Increment the live_length for all of the registers that | |
172 are are referenced in this block and live at this | |
173 particular point. */ | |
174 EXECUTE_IF_SET_IN_BITMAP (local_live, 0, regno, bi) | |
175 { | |
176 REG_LIVE_LENGTH (regno)++; | |
177 } | |
178 luid++; | |
179 | |
180 bitmap_clear (do_not_gen); | |
181 | |
182 link = REG_NOTES (insn); | 147 link = REG_NOTES (insn); |
183 while (link) | 148 while (link) |
184 { | 149 { |
185 if (REG_NOTE_KIND (link) == REG_DEAD) | 150 if (REG_NOTE_KIND (link) == REG_DEAD) |
186 REG_N_DEATHS(REGNO (XEXP (link, 0)))++; | 151 REG_N_DEATHS (REGNO (XEXP (link, 0)))++; |
187 link = XEXP (link, 1); | 152 link = XEXP (link, 1); |
188 } | 153 } |
189 | 154 |
190 /* Process the defs. */ | 155 /* Process the defs. */ |
191 if (CALL_P (insn)) | 156 if (CALL_P (insn)) |
192 { | 157 { |
193 bool can_throw = can_throw_internal (insn); | |
194 bool set_jump = (find_reg_note (insn, REG_SETJMP, NULL) != NULL); | 158 bool set_jump = (find_reg_note (insn, REG_SETJMP, NULL) != NULL); |
195 EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi) | 159 EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi) |
196 { | 160 { |
197 REG_N_CALLS_CROSSED (regno)++; | 161 REG_N_CALLS_CROSSED (regno)++; |
198 REG_FREQ_CALLS_CROSSED (regno) += REG_FREQ_FROM_BB (bb); | |
199 if (can_throw) | |
200 REG_N_THROWING_CALLS_CROSSED (regno)++; | |
201 | 162 |
202 /* We have a problem with any pseudoreg that lives | 163 /* We have a problem with any pseudoreg that lives |
203 across the setjmp. ANSI says that if a user variable | 164 across the setjmp. ANSI says that if a user variable |
204 does not change in value between the setjmp and the | 165 does not change in value between the setjmp and the |
205 longjmp, then the longjmp preserves it. This | 166 longjmp, then the longjmp preserves it. This |
213 if (set_jump) | 174 if (set_jump) |
214 bitmap_set_bit (setjmp_crosses, regno); | 175 bitmap_set_bit (setjmp_crosses, regno); |
215 } | 176 } |
216 } | 177 } |
217 | 178 |
218 /* We only care about real sets for calls. Clobbers only | |
219 may clobbers cannot be depended on. */ | |
220 for (mws_rec = DF_INSN_UID_MWS (uid); *mws_rec; mws_rec++) | |
221 { | |
222 struct df_mw_hardreg *mws = *mws_rec; | |
223 if (DF_MWS_REG_DEF_P (mws)) | |
224 { | |
225 bool all_dead = true; | |
226 unsigned int r; | |
227 | |
228 for (r=mws->start_regno; r <= mws->end_regno; r++) | |
229 if ((bitmap_bit_p (live, r)) | |
230 || bitmap_bit_p (artificial_uses, r)) | |
231 { | |
232 all_dead = false; | |
233 break; | |
234 } | |
235 | |
236 if (all_dead) | |
237 { | |
238 unsigned int regno = mws->start_regno; | |
239 bitmap_set_bit (do_not_gen, regno); | |
240 /* Only do this if the value is totally dead. */ | |
241 REG_LIVE_LENGTH (regno)++; | |
242 } | |
243 } | |
244 } | |
245 | |
246 /* All of the defs except the return value are some sort of | 179 /* All of the defs except the return value are some sort of |
247 clobber. This code is for the return. */ | 180 clobber. This code is for the return. */ |
248 for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) | 181 FOR_EACH_INSN_INFO_DEF (def, insn_info) |
249 { | 182 { |
250 df_ref def = *def_rec; | |
251 if ((!CALL_P (insn)) | 183 if ((!CALL_P (insn)) |
252 || (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))) | 184 || (!(DF_REF_FLAGS (def) |
185 & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))) | |
253 { | 186 { |
254 unsigned int dregno = DF_REF_REGNO (def); | 187 unsigned int dregno = DF_REF_REGNO (def); |
255 | 188 |
256 if (bitmap_bit_p (live, dregno)) | 189 /* Kill this register if it is not a subreg store or |
257 { | 190 conditional store. |
258 /* If we have seen this regno, then it has already been | 191 ??? This means that any partial store is live from |
259 processed correctly with the per insn increment. If we | 192 the last use in a basic block to the start of this |
260 have not seen it we need to add the length from here to | 193 basic block. */ |
261 the end of the block to the live length. */ | 194 if (!(DF_REF_FLAGS (def) |
262 if (bitmap_bit_p (local_processed, dregno)) | 195 & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) |
263 { | 196 bitmap_clear_bit (live, dregno); |
264 if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) | |
265 bitmap_clear_bit (local_live, dregno); | |
266 } | |
267 else | |
268 { | |
269 bitmap_set_bit (local_processed, dregno); | |
270 REG_LIVE_LENGTH (dregno) += luid; | |
271 } | |
272 } | |
273 else if ((!(DF_REF_FLAGS (def) & DF_REF_MW_HARDREG)) | |
274 && (!bitmap_bit_p (artificial_uses, dregno))) | |
275 { | |
276 REG_LIVE_LENGTH (dregno)++; | |
277 } | |
278 | 197 |
279 if (dregno >= FIRST_PSEUDO_REGISTER) | 198 if (dregno >= FIRST_PSEUDO_REGISTER) |
280 { | 199 { |
281 REG_FREQ (dregno) += REG_FREQ_FROM_BB (bb); | 200 REG_FREQ (dregno) += REG_FREQ_FROM_BB (bb); |
201 REG_FREQ (dregno) = | |
202 MIN (REG_FREQ (dregno), REG_FREQ_MAX); | |
203 | |
282 if (REG_BASIC_BLOCK (dregno) == REG_BLOCK_UNKNOWN) | 204 if (REG_BASIC_BLOCK (dregno) == REG_BLOCK_UNKNOWN) |
283 REG_BASIC_BLOCK (dregno) = bb->index; | 205 REG_BASIC_BLOCK (dregno) = bb->index; |
284 else if (REG_BASIC_BLOCK (dregno) != bb->index) | 206 else if (REG_BASIC_BLOCK (dregno) != bb->index) |
285 REG_BASIC_BLOCK (dregno) = REG_BLOCK_GLOBAL; | 207 REG_BASIC_BLOCK (dregno) = REG_BLOCK_GLOBAL; |
286 } | 208 } |
287 | |
288 if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER + DF_REF_MAY_CLOBBER))) | |
289 bitmap_set_bit (do_not_gen, dregno); | |
290 | |
291 /* Kill this register if it is not a subreg store or conditional store. */ | |
292 if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) | |
293 bitmap_clear_bit (live, dregno); | |
294 } | 209 } |
295 } | 210 } |
296 | 211 |
297 for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) | 212 FOR_EACH_INSN_INFO_USE (use, insn_info) |
298 { | 213 { |
299 df_ref use = *use_rec; | |
300 unsigned int uregno = DF_REF_REGNO (use); | 214 unsigned int uregno = DF_REF_REGNO (use); |
301 | 215 |
302 if (uregno >= FIRST_PSEUDO_REGISTER) | 216 if (uregno >= FIRST_PSEUDO_REGISTER) |
303 { | 217 { |
304 REG_FREQ (uregno) += REG_FREQ_FROM_BB (bb); | 218 REG_FREQ (uregno) += REG_FREQ_FROM_BB (bb); |
219 REG_FREQ (uregno) = | |
220 MIN (REG_FREQ (uregno), REG_FREQ_MAX); | |
221 | |
305 if (REG_BASIC_BLOCK (uregno) == REG_BLOCK_UNKNOWN) | 222 if (REG_BASIC_BLOCK (uregno) == REG_BLOCK_UNKNOWN) |
306 REG_BASIC_BLOCK (uregno) = bb->index; | 223 REG_BASIC_BLOCK (uregno) = bb->index; |
307 else if (REG_BASIC_BLOCK (uregno) != bb->index) | 224 else if (REG_BASIC_BLOCK (uregno) != bb->index) |
308 REG_BASIC_BLOCK (uregno) = REG_BLOCK_GLOBAL; | 225 REG_BASIC_BLOCK (uregno) = REG_BLOCK_GLOBAL; |
309 } | 226 } |
310 | 227 } |
311 if (bitmap_set_bit (live, uregno)) | 228 } |
312 { | |
313 /* This register is now live. */ | |
314 | |
315 /* If we have seen this regno, then it has already been | |
316 processed correctly with the per insn increment. If | |
317 we have not seen it we set the bit so that begins to | |
318 get processed locally. Note that we don't even get | |
319 here if the variable was live at the end of the block | |
320 since just a ref inside the block does not effect the | |
321 calculations. */ | |
322 REG_LIVE_LENGTH (uregno) ++; | |
323 bitmap_set_bit (local_live, uregno); | |
324 bitmap_set_bit (local_processed, uregno); | |
325 } | |
326 } | |
327 } | |
328 | |
329 /* Add the length of the block to all of the registers that were not | |
330 referenced, but still live in this block. */ | |
331 bitmap_and_compl_into (live, local_processed); | |
332 EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi) | |
333 REG_LIVE_LENGTH (regno) += luid; | |
334 | |
335 bitmap_clear (local_processed); | |
336 bitmap_clear (local_live); | |
337 } | 229 } |
338 | 230 |
339 | 231 |
340 /* Compute register info: lifetime, bb, and number of defs and uses. */ | 232 /* Compute register info: lifetime, bb, and number of defs and uses. */ |
341 void | 233 void |
342 regstat_compute_ri (void) | 234 regstat_compute_ri (void) |
343 { | 235 { |
344 basic_block bb; | 236 basic_block bb; |
345 bitmap live = BITMAP_ALLOC (&df_bitmap_obstack); | 237 bitmap live = BITMAP_ALLOC (&df_bitmap_obstack); |
346 bitmap do_not_gen = BITMAP_ALLOC (&df_bitmap_obstack); | |
347 bitmap artificial_uses = BITMAP_ALLOC (&df_bitmap_obstack); | |
348 bitmap local_live = BITMAP_ALLOC (&df_bitmap_obstack); | |
349 bitmap local_processed = BITMAP_ALLOC (&df_bitmap_obstack); | |
350 unsigned int regno; | 238 unsigned int regno; |
351 bitmap_iterator bi; | 239 bitmap_iterator bi; |
352 | 240 |
353 /* Initialize everything. */ | 241 /* Initialize everything. */ |
354 | 242 |
358 setjmp_crosses = BITMAP_ALLOC (&df_bitmap_obstack); | 246 setjmp_crosses = BITMAP_ALLOC (&df_bitmap_obstack); |
359 max_regno = max_reg_num (); | 247 max_regno = max_reg_num (); |
360 reg_info_p_size = max_regno; | 248 reg_info_p_size = max_regno; |
361 reg_info_p = XCNEWVEC (struct reg_info_t, max_regno); | 249 reg_info_p = XCNEWVEC (struct reg_info_t, max_regno); |
362 | 250 |
363 FOR_EACH_BB (bb) | 251 FOR_EACH_BB_FN (bb, cfun) |
364 { | 252 { |
365 regstat_bb_compute_ri (bb->index, live, do_not_gen, artificial_uses, | 253 regstat_bb_compute_ri (bb, live); |
366 local_live, local_processed); | |
367 } | 254 } |
368 | 255 |
369 BITMAP_FREE (live); | 256 BITMAP_FREE (live); |
370 BITMAP_FREE (do_not_gen); | 257 |
371 BITMAP_FREE (artificial_uses); | 258 /* See the setjmp comment in regstat_bb_compute_ri. */ |
372 | |
373 /* See the setjmp comment in regstat_ri_bb_compute. */ | |
374 EXECUTE_IF_SET_IN_BITMAP (setjmp_crosses, FIRST_PSEUDO_REGISTER, regno, bi) | 259 EXECUTE_IF_SET_IN_BITMAP (setjmp_crosses, FIRST_PSEUDO_REGISTER, regno, bi) |
375 { | 260 { |
376 REG_BASIC_BLOCK (regno) = REG_BLOCK_UNKNOWN; | 261 REG_BASIC_BLOCK (regno) = REG_BLOCK_UNKNOWN; |
377 REG_LIVE_LENGTH (regno) = -1; | 262 } |
378 } | 263 |
379 | |
380 BITMAP_FREE (local_live); | |
381 BITMAP_FREE (local_processed); | |
382 timevar_pop (TV_REG_STATS); | 264 timevar_pop (TV_REG_STATS); |
383 } | 265 } |
384 | 266 |
385 | 267 |
386 /* Free all storage associated with the problem. */ | 268 /* Free all storage associated with the problem. */ |
422 /* Compute calls crossed for BB. Live is a scratch bitvector. */ | 304 /* Compute calls crossed for BB. Live is a scratch bitvector. */ |
423 | 305 |
424 static void | 306 static void |
425 regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live) | 307 regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live) |
426 { | 308 { |
427 basic_block bb = BASIC_BLOCK (bb_index); | 309 basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index); |
428 rtx insn; | 310 rtx_insn *insn; |
429 df_ref *def_rec; | 311 df_ref def, use; |
430 df_ref *use_rec; | |
431 | 312 |
432 bitmap_copy (live, df_get_live_out (bb)); | 313 bitmap_copy (live, df_get_live_out (bb)); |
433 | 314 |
434 /* Process the artificial defs and uses at the bottom of the block | 315 /* Process the artificial defs and uses at the bottom of the block |
435 to begin processing. */ | 316 to begin processing. */ |
436 for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) | 317 FOR_EACH_ARTIFICIAL_DEF (def, bb_index) |
437 { | 318 if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) |
438 df_ref def = *def_rec; | 319 bitmap_clear_bit (live, DF_REF_REGNO (def)); |
439 if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) | 320 |
440 bitmap_clear_bit (live, DF_REF_REGNO (def)); | 321 FOR_EACH_ARTIFICIAL_USE (use, bb_index) |
441 } | 322 if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) |
442 | 323 bitmap_set_bit (live, DF_REF_REGNO (use)); |
443 for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++) | |
444 { | |
445 df_ref use = *use_rec; | |
446 if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) | |
447 bitmap_set_bit (live, DF_REF_REGNO (use)); | |
448 } | |
449 | 324 |
450 FOR_BB_INSNS_REVERSE (bb, insn) | 325 FOR_BB_INSNS_REVERSE (bb, insn) |
451 { | 326 { |
452 unsigned int uid = INSN_UID (insn); | 327 struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); |
453 unsigned int regno; | 328 unsigned int regno; |
454 | 329 |
455 if (!INSN_P (insn)) | 330 if (!NONDEBUG_INSN_P (insn)) |
456 continue; | 331 continue; |
457 | 332 |
458 /* Process the defs. */ | 333 /* Process the defs. */ |
459 if (CALL_P (insn)) | 334 if (CALL_P (insn)) |
460 { | 335 { |
461 bitmap_iterator bi; | 336 bitmap_iterator bi; |
462 EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi) | 337 EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi) |
463 { | 338 { |
464 REG_N_CALLS_CROSSED (regno)++; | 339 REG_N_CALLS_CROSSED (regno)++; |
465 REG_FREQ_CALLS_CROSSED (regno) += REG_FREQ_FROM_BB (bb); | |
466 } | 340 } |
467 } | 341 } |
468 | 342 |
469 /* All of the defs except the return value are some sort of | 343 /* All of the defs except the return value are some sort of |
470 clobber. This code is for the return. */ | 344 clobber. This code is for the return. */ |
471 for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) | 345 FOR_EACH_INSN_INFO_DEF (def, insn_info) |
472 { | 346 { |
473 df_ref def = *def_rec; | |
474 if ((!CALL_P (insn)) | 347 if ((!CALL_P (insn)) |
475 || (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))) | 348 || (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))) |
476 { | 349 { |
477 /* Kill this register if it is not a subreg store or conditional store. */ | 350 /* Kill this register if it is not a subreg store or conditional store. */ |
478 if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) | 351 if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) |
479 bitmap_clear_bit (live, DF_REF_REGNO (def)); | 352 bitmap_clear_bit (live, DF_REF_REGNO (def)); |
480 } | 353 } |
481 } | 354 } |
482 | 355 |
483 for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) | 356 FOR_EACH_INSN_INFO_USE (use, insn_info) |
484 { | 357 bitmap_set_bit (live, DF_REF_REGNO (use)); |
485 df_ref use = *use_rec; | |
486 bitmap_set_bit (live, DF_REF_REGNO (use)); | |
487 } | |
488 } | 358 } |
489 } | 359 } |
490 | 360 |
491 | 361 |
492 /* Compute register info: lifetime, bb, and number of defs and uses. */ | 362 /* Compute register info: lifetime, bb, and number of defs and uses. */ |
502 timevar_push (TV_REG_STATS); | 372 timevar_push (TV_REG_STATS); |
503 max_regno = max_reg_num (); | 373 max_regno = max_reg_num (); |
504 reg_info_p_size = max_regno; | 374 reg_info_p_size = max_regno; |
505 reg_info_p = XCNEWVEC (struct reg_info_t, max_regno); | 375 reg_info_p = XCNEWVEC (struct reg_info_t, max_regno); |
506 | 376 |
507 FOR_EACH_BB (bb) | 377 FOR_EACH_BB_FN (bb, cfun) |
508 { | 378 { |
509 regstat_bb_compute_calls_crossed (bb->index, live); | 379 regstat_bb_compute_calls_crossed (bb->index, live); |
510 } | 380 } |
511 | 381 |
512 BITMAP_FREE (live); | 382 BITMAP_FREE (live); |
523 reg_info_p_size = 0; | 393 reg_info_p_size = 0; |
524 free (reg_info_p); | 394 free (reg_info_p); |
525 reg_info_p = NULL; | 395 reg_info_p = NULL; |
526 } | 396 } |
527 | 397 |
398 /* Dump the register info to FILE. */ | |
399 | |
400 void | |
401 dump_reg_info (FILE *file) | |
402 { | |
403 unsigned int i, max = max_reg_num (); | |
404 if (reload_completed) | |
405 return; | |
406 | |
407 if (reg_info_p_size < max) | |
408 max = reg_info_p_size; | |
409 | |
410 fprintf (file, "%d registers.\n", max); | |
411 for (i = FIRST_PSEUDO_REGISTER; i < max; i++) | |
412 { | |
413 enum reg_class rclass, altclass; | |
414 | |
415 if (regstat_n_sets_and_refs) | |
416 fprintf (file, "\nRegister %d used %d times", | |
417 i, REG_N_REFS (i)); | |
418 else if (df) | |
419 fprintf (file, "\nRegister %d used %d times", | |
420 i, DF_REG_USE_COUNT (i) + DF_REG_DEF_COUNT (i)); | |
421 | |
422 if (REG_BASIC_BLOCK (i) >= NUM_FIXED_BLOCKS) | |
423 fprintf (file, " in block %d", REG_BASIC_BLOCK (i)); | |
424 if (regstat_n_sets_and_refs) | |
425 fprintf (file, "; set %d time%s", REG_N_SETS (i), | |
426 (REG_N_SETS (i) == 1) ? "" : "s"); | |
427 else if (df) | |
428 fprintf (file, "; set %d time%s", DF_REG_DEF_COUNT (i), | |
429 (DF_REG_DEF_COUNT (i) == 1) ? "" : "s"); | |
430 if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i])) | |
431 fputs ("; user var", file); | |
432 if (REG_N_DEATHS (i) != 1) | |
433 fprintf (file, "; dies in %d places", REG_N_DEATHS (i)); | |
434 if (REG_N_CALLS_CROSSED (i) == 1) | |
435 fputs ("; crosses 1 call", file); | |
436 else if (REG_N_CALLS_CROSSED (i)) | |
437 fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i)); | |
438 if (regno_reg_rtx[i] != NULL | |
439 && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD) | |
440 fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i)); | |
441 | |
442 rclass = reg_preferred_class (i); | |
443 altclass = reg_alternate_class (i); | |
444 if (rclass != GENERAL_REGS || altclass != ALL_REGS) | |
445 { | |
446 if (altclass == ALL_REGS || rclass == ALL_REGS) | |
447 fprintf (file, "; pref %s", reg_class_names[(int) rclass]); | |
448 else if (altclass == NO_REGS) | |
449 fprintf (file, "; %s or none", reg_class_names[(int) rclass]); | |
450 else | |
451 fprintf (file, "; pref %s, else %s", | |
452 reg_class_names[(int) rclass], | |
453 reg_class_names[(int) altclass]); | |
454 } | |
455 | |
456 if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i])) | |
457 fputs ("; pointer", file); | |
458 fputs (".\n", file); | |
459 } | |
460 } | |
461 |