Mercurial > hg > CbC > CbC_gcc
annotate gcc/cfg.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
rev | line source |
---|---|
0 | 1 /* Control flow graph manipulation code for GNU compiler. |
131 | 2 Copyright (C) 1987-2018 Free Software Foundation, Inc. |
0 | 3 |
4 This file is part of GCC. | |
5 | |
6 GCC is free software; you can redistribute it and/or modify it under | |
7 the terms of the GNU General Public License as published by the Free | |
8 Software Foundation; either version 3, or (at your option) any later | |
9 version. | |
10 | |
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GCC; see the file COPYING3. If not see | |
18 <http://www.gnu.org/licenses/>. */ | |
19 | |
20 /* This file contains low level functions to manipulate the CFG and | |
21 analyze it. All other modules should not transform the data structure | |
22 directly and use abstraction instead. The file is supposed to be | |
23 ordered bottom-up and should not contain any code dependent on a | |
24 particular intermediate language (RTL or trees). | |
25 | |
26 Available functionality: | |
27 - Initialization/deallocation | |
28 init_flow, clear_edges | |
29 - Low level basic block manipulation | |
30 alloc_block, expunge_block | |
31 - Edge manipulation | |
32 make_edge, make_single_succ_edge, cached_make_edge, remove_edge | |
33 - Low level edge redirection (without updating instruction chain) | |
34 redirect_edge_succ, redirect_edge_succ_nodup, redirect_edge_pred | |
35 - Dumping and debugging | |
36 dump_flow_info, debug_flow_info, dump_edge_info | |
37 - Allocation of AUX fields for basic blocks | |
38 alloc_aux_for_blocks, free_aux_for_blocks, alloc_aux_for_block | |
39 - clear_bb_flags | |
40 - Consistency checking | |
41 verify_flow_info | |
42 - Dumping and debugging | |
43 print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n | |
111 | 44 |
45 TODO: Document these "Available functionality" functions in the files | |
46 that implement them. | |
0 | 47 */ |
48 | |
49 #include "config.h" | |
50 #include "system.h" | |
51 #include "coretypes.h" | |
111 | 52 #include "backend.h" |
0 | 53 #include "hard-reg-set.h" |
111 | 54 #include "tree.h" |
55 #include "cfghooks.h" | |
0 | 56 #include "df.h" |
111 | 57 #include "cfganal.h" |
58 #include "cfgloop.h" /* FIXME: For struct loop. */ | |
59 #include "dumpfile.h" | |
0 | 60 |
61 | |
62 | |
63 /* Called once at initialization time. */ | |
64 | |
65 void | |
66 init_flow (struct function *the_fun) | |
67 { | |
68 if (!the_fun->cfg) | |
111 | 69 the_fun->cfg = ggc_cleared_alloc<control_flow_graph> (); |
70 n_edges_for_fn (the_fun) = 0; | |
131 | 71 the_fun->cfg->count_max = profile_count::uninitialized (); |
111 | 72 ENTRY_BLOCK_PTR_FOR_FN (the_fun) |
73 = alloc_block (); | |
74 ENTRY_BLOCK_PTR_FOR_FN (the_fun)->index = ENTRY_BLOCK; | |
75 EXIT_BLOCK_PTR_FOR_FN (the_fun) | |
76 = alloc_block (); | |
77 EXIT_BLOCK_PTR_FOR_FN (the_fun)->index = EXIT_BLOCK; | |
78 ENTRY_BLOCK_PTR_FOR_FN (the_fun)->next_bb | |
79 = EXIT_BLOCK_PTR_FOR_FN (the_fun); | |
80 EXIT_BLOCK_PTR_FOR_FN (the_fun)->prev_bb | |
81 = ENTRY_BLOCK_PTR_FOR_FN (the_fun); | |
131 | 82 the_fun->cfg->edge_flags_allocated = EDGE_ALL_FLAGS; |
83 the_fun->cfg->bb_flags_allocated = BB_ALL_FLAGS; | |
0 | 84 } |
85 | |
86 /* Helper function for remove_edge and clear_edges. Frees edge structure | |
111 | 87 without actually removing it from the pred/succ arrays. */ |
0 | 88 |
89 static void | |
111 | 90 free_edge (function *fn, edge e) |
0 | 91 { |
111 | 92 n_edges_for_fn (fn)--; |
0 | 93 ggc_free (e); |
94 } | |
95 | |
96 /* Free the memory associated with the edge structures. */ | |
97 | |
98 void | |
111 | 99 clear_edges (struct function *fn) |
0 | 100 { |
101 basic_block bb; | |
102 edge e; | |
103 edge_iterator ei; | |
104 | |
111 | 105 FOR_EACH_BB_FN (bb, fn) |
0 | 106 { |
107 FOR_EACH_EDGE (e, ei, bb->succs) | |
111 | 108 free_edge (fn, e); |
109 vec_safe_truncate (bb->succs, 0); | |
110 vec_safe_truncate (bb->preds, 0); | |
0 | 111 } |
112 | |
111 | 113 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (fn)->succs) |
114 free_edge (fn, e); | |
115 vec_safe_truncate (EXIT_BLOCK_PTR_FOR_FN (fn)->preds, 0); | |
116 vec_safe_truncate (ENTRY_BLOCK_PTR_FOR_FN (fn)->succs, 0); | |
0 | 117 |
111 | 118 gcc_assert (!n_edges_for_fn (fn)); |
0 | 119 } |
120 | |
121 /* Allocate memory for basic_block. */ | |
122 | |
123 basic_block | |
124 alloc_block (void) | |
125 { | |
126 basic_block bb; | |
111 | 127 bb = ggc_cleared_alloc<basic_block_def> (); |
128 bb->count = profile_count::uninitialized (); | |
0 | 129 return bb; |
130 } | |
131 | |
132 /* Link block B to chain after AFTER. */ | |
133 void | |
134 link_block (basic_block b, basic_block after) | |
135 { | |
136 b->next_bb = after->next_bb; | |
137 b->prev_bb = after; | |
138 after->next_bb = b; | |
139 b->next_bb->prev_bb = b; | |
140 } | |
141 | |
142 /* Unlink block B from chain. */ | |
143 void | |
144 unlink_block (basic_block b) | |
145 { | |
146 b->next_bb->prev_bb = b->prev_bb; | |
147 b->prev_bb->next_bb = b->next_bb; | |
148 b->prev_bb = NULL; | |
149 b->next_bb = NULL; | |
150 } | |
151 | |
152 /* Sequentially order blocks and compact the arrays. */ | |
153 void | |
154 compact_blocks (void) | |
155 { | |
156 int i; | |
157 | |
111 | 158 SET_BASIC_BLOCK_FOR_FN (cfun, ENTRY_BLOCK, ENTRY_BLOCK_PTR_FOR_FN (cfun)); |
159 SET_BASIC_BLOCK_FOR_FN (cfun, EXIT_BLOCK, EXIT_BLOCK_PTR_FOR_FN (cfun)); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
160 |
0 | 161 if (df) |
162 df_compact_blocks (); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
163 else |
0 | 164 { |
165 basic_block bb; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
166 |
0 | 167 i = NUM_FIXED_BLOCKS; |
111 | 168 FOR_EACH_BB_FN (bb, cfun) |
0 | 169 { |
111 | 170 SET_BASIC_BLOCK_FOR_FN (cfun, i, bb); |
0 | 171 bb->index = i; |
172 i++; | |
173 } | |
111 | 174 gcc_assert (i == n_basic_blocks_for_fn (cfun)); |
0 | 175 |
111 | 176 for (; i < last_basic_block_for_fn (cfun); i++) |
177 SET_BASIC_BLOCK_FOR_FN (cfun, i, NULL); | |
0 | 178 } |
111 | 179 last_basic_block_for_fn (cfun) = n_basic_blocks_for_fn (cfun); |
0 | 180 } |
181 | |
182 /* Remove block B from the basic block array. */ | |
183 | |
184 void | |
185 expunge_block (basic_block b) | |
186 { | |
187 unlink_block (b); | |
111 | 188 SET_BASIC_BLOCK_FOR_FN (cfun, b->index, NULL); |
189 n_basic_blocks_for_fn (cfun)--; | |
0 | 190 /* We should be able to ggc_free here, but we are not. |
191 The dead SSA_NAMES are left pointing to dead statements that are pointing | |
192 to dead basic blocks making garbage collector to die. | |
193 We should be able to release all dead SSA_NAMES and at the same time we should | |
194 clear out BB pointer of dead statements consistently. */ | |
195 } | |
196 | |
197 /* Connect E to E->src. */ | |
198 | |
199 static inline void | |
200 connect_src (edge e) | |
201 { | |
111 | 202 vec_safe_push (e->src->succs, e); |
0 | 203 df_mark_solutions_dirty (); |
204 } | |
205 | |
206 /* Connect E to E->dest. */ | |
207 | |
208 static inline void | |
209 connect_dest (edge e) | |
210 { | |
211 basic_block dest = e->dest; | |
111 | 212 vec_safe_push (dest->preds, e); |
0 | 213 e->dest_idx = EDGE_COUNT (dest->preds) - 1; |
214 df_mark_solutions_dirty (); | |
215 } | |
216 | |
217 /* Disconnect edge E from E->src. */ | |
218 | |
219 static inline void | |
220 disconnect_src (edge e) | |
221 { | |
222 basic_block src = e->src; | |
223 edge_iterator ei; | |
224 edge tmp; | |
225 | |
226 for (ei = ei_start (src->succs); (tmp = ei_safe_edge (ei)); ) | |
227 { | |
228 if (tmp == e) | |
229 { | |
111 | 230 src->succs->unordered_remove (ei.index); |
231 df_mark_solutions_dirty (); | |
0 | 232 return; |
233 } | |
234 else | |
235 ei_next (&ei); | |
236 } | |
237 | |
238 gcc_unreachable (); | |
239 } | |
240 | |
241 /* Disconnect edge E from E->dest. */ | |
242 | |
243 static inline void | |
244 disconnect_dest (edge e) | |
245 { | |
246 basic_block dest = e->dest; | |
247 unsigned int dest_idx = e->dest_idx; | |
248 | |
111 | 249 dest->preds->unordered_remove (dest_idx); |
0 | 250 |
251 /* If we removed an edge in the middle of the edge vector, we need | |
252 to update dest_idx of the edge that moved into the "hole". */ | |
253 if (dest_idx < EDGE_COUNT (dest->preds)) | |
254 EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx; | |
255 df_mark_solutions_dirty (); | |
256 } | |
257 | |
258 /* Create an edge connecting SRC and DEST with flags FLAGS. Return newly | |
259 created edge. Use this only if you are sure that this edge can't | |
260 possibly already exist. */ | |
261 | |
262 edge | |
263 unchecked_make_edge (basic_block src, basic_block dst, int flags) | |
264 { | |
265 edge e; | |
111 | 266 e = ggc_cleared_alloc<edge_def> (); |
267 n_edges_for_fn (cfun)++; | |
0 | 268 |
111 | 269 e->probability = profile_probability::uninitialized (); |
0 | 270 e->src = src; |
271 e->dest = dst; | |
272 e->flags = flags; | |
273 | |
274 connect_src (e); | |
275 connect_dest (e); | |
276 | |
277 execute_on_growing_pred (e); | |
278 return e; | |
279 } | |
280 | |
281 /* Create an edge connecting SRC and DST with FLAGS optionally using | |
282 edge cache CACHE. Return the new edge, NULL if already exist. */ | |
283 | |
284 edge | |
285 cached_make_edge (sbitmap edge_cache, basic_block src, basic_block dst, int flags) | |
286 { | |
287 if (edge_cache == NULL | |
111 | 288 || src == ENTRY_BLOCK_PTR_FOR_FN (cfun) |
289 || dst == EXIT_BLOCK_PTR_FOR_FN (cfun)) | |
0 | 290 return make_edge (src, dst, flags); |
291 | |
292 /* Does the requested edge already exist? */ | |
111 | 293 if (! bitmap_bit_p (edge_cache, dst->index)) |
0 | 294 { |
295 /* The edge does not exist. Create one and update the | |
296 cache. */ | |
111 | 297 bitmap_set_bit (edge_cache, dst->index); |
0 | 298 return unchecked_make_edge (src, dst, flags); |
299 } | |
300 | |
301 /* At this point, we know that the requested edge exists. Adjust | |
302 flags if necessary. */ | |
303 if (flags) | |
304 { | |
305 edge e = find_edge (src, dst); | |
306 e->flags |= flags; | |
307 } | |
308 | |
309 return NULL; | |
310 } | |
311 | |
312 /* Create an edge connecting SRC and DEST with flags FLAGS. Return newly | |
313 created edge or NULL if already exist. */ | |
314 | |
315 edge | |
316 make_edge (basic_block src, basic_block dest, int flags) | |
317 { | |
318 edge e = find_edge (src, dest); | |
319 | |
320 /* Make sure we don't add duplicate edges. */ | |
321 if (e) | |
322 { | |
323 e->flags |= flags; | |
324 return NULL; | |
325 } | |
326 | |
327 return unchecked_make_edge (src, dest, flags); | |
328 } | |
329 | |
330 /* Create an edge connecting SRC to DEST and set probability by knowing | |
331 that it is the single edge leaving SRC. */ | |
332 | |
333 edge | |
334 make_single_succ_edge (basic_block src, basic_block dest, int flags) | |
335 { | |
336 edge e = make_edge (src, dest, flags); | |
337 | |
111 | 338 e->probability = profile_probability::always (); |
0 | 339 return e; |
340 } | |
341 | |
342 /* This function will remove an edge from the flow graph. */ | |
343 | |
344 void | |
345 remove_edge_raw (edge e) | |
346 { | |
347 remove_predictions_associated_with_edge (e); | |
348 execute_on_shrinking_pred (e); | |
349 | |
350 disconnect_src (e); | |
351 disconnect_dest (e); | |
352 | |
111 | 353 free_edge (cfun, e); |
0 | 354 } |
355 | |
356 /* Redirect an edge's successor from one block to another. */ | |
357 | |
358 void | |
359 redirect_edge_succ (edge e, basic_block new_succ) | |
360 { | |
361 execute_on_shrinking_pred (e); | |
362 | |
363 disconnect_dest (e); | |
364 | |
365 e->dest = new_succ; | |
366 | |
367 /* Reconnect the edge to the new successor block. */ | |
368 connect_dest (e); | |
369 | |
370 execute_on_growing_pred (e); | |
371 } | |
372 | |
373 /* Redirect an edge's predecessor from one block to another. */ | |
374 | |
375 void | |
376 redirect_edge_pred (edge e, basic_block new_pred) | |
377 { | |
378 disconnect_src (e); | |
379 | |
380 e->src = new_pred; | |
381 | |
382 /* Reconnect the edge to the new predecessor block. */ | |
383 connect_src (e); | |
384 } | |
385 | |
111 | 386 /* Clear all basic block flags that do not have to be preserved. */ |
0 | 387 void |
388 clear_bb_flags (void) | |
389 { | |
390 basic_block bb; | |
131 | 391 int flags_to_preserve = BB_FLAGS_TO_PRESERVE; |
392 if (current_loops | |
393 && loops_state_satisfies_p (cfun, LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)) | |
394 flags_to_preserve |= BB_IRREDUCIBLE_LOOP; | |
0 | 395 |
111 | 396 FOR_ALL_BB_FN (bb, cfun) |
131 | 397 bb->flags &= flags_to_preserve; |
0 | 398 } |
399 | |
400 /* Check the consistency of profile information. We can't do that | |
401 in verify_flow_info, as the counts may get invalid for incompletely | |
402 solved graphs, later eliminating of conditionals or roundoff errors. | |
403 It is still practical to have them reported for debugging of simple | |
404 testcases. */ | |
111 | 405 static void |
406 check_bb_profile (basic_block bb, FILE * file, int indent) | |
0 | 407 { |
408 edge e; | |
409 edge_iterator ei; | |
111 | 410 struct function *fun = DECL_STRUCT_FUNCTION (current_function_decl); |
411 char *s_indent = (char *) alloca ((size_t) indent + 1); | |
412 memset ((void *) s_indent, ' ', (size_t) indent); | |
413 s_indent[indent] = '\0'; | |
0 | 414 |
111 | 415 if (profile_status_for_fn (fun) == PROFILE_ABSENT) |
0 | 416 return; |
417 | |
111 | 418 if (bb != EXIT_BLOCK_PTR_FOR_FN (fun)) |
0 | 419 { |
111 | 420 bool found = false; |
421 profile_probability sum = profile_probability::never (); | |
422 int isum = 0; | |
423 | |
0 | 424 FOR_EACH_EDGE (e, ei, bb->succs) |
111 | 425 { |
426 if (!(e->flags & (EDGE_EH | EDGE_FAKE))) | |
427 found = true; | |
428 sum += e->probability; | |
429 if (e->probability.initialized_p ()) | |
430 isum += e->probability.to_reg_br_prob_base (); | |
431 } | |
432 /* Only report mismatches for non-EH control flow. If there are only EH | |
433 edges it means that the BB ends by noreturn call. Here the control | |
434 flow may just terminate. */ | |
435 if (found) | |
436 { | |
437 if (sum.differs_from_p (profile_probability::always ())) | |
438 { | |
439 fprintf (file, | |
440 ";; %sInvalid sum of outgoing probabilities ", | |
441 s_indent); | |
442 sum.dump (file); | |
443 fprintf (file, "\n"); | |
444 } | |
445 /* Probabilities caps to 100% and thus the previous test will never | |
446 fire if the sum of probabilities is too large. */ | |
447 else if (isum > REG_BR_PROB_BASE + 100) | |
448 { | |
449 fprintf (file, | |
450 ";; %sInvalid sum of outgoing probabilities %.1f%%\n", | |
451 s_indent, isum * 100.0 / REG_BR_PROB_BASE); | |
452 } | |
453 } | |
0 | 454 } |
111 | 455 if (bb != ENTRY_BLOCK_PTR_FOR_FN (fun)) |
0 | 456 { |
131 | 457 profile_count sum = profile_count::zero (); |
0 | 458 FOR_EACH_EDGE (e, ei, bb->preds) |
131 | 459 sum += e->count (); |
460 if (sum.differs_from_p (bb->count)) | |
461 { | |
462 fprintf (file, ";; %sInvalid sum of incoming counts ", | |
463 s_indent); | |
464 sum.dump (file); | |
465 fprintf (file, ", should be "); | |
466 bb->count.dump (file); | |
467 fprintf (file, "\n"); | |
468 } | |
111 | 469 } |
470 if (BB_PARTITION (bb) == BB_COLD_PARTITION) | |
471 { | |
472 /* Warn about inconsistencies in the partitioning that are | |
473 currently caused by profile insanities created via optimization. */ | |
474 if (!probably_never_executed_bb_p (fun, bb)) | |
475 fprintf (file, ";; %sBlock in cold partition with hot count\n", | |
476 s_indent); | |
0 | 477 FOR_EACH_EDGE (e, ei, bb->preds) |
111 | 478 { |
479 if (!probably_never_executed_edge_p (fun, e)) | |
480 fprintf (file, | |
481 ";; %sBlock in cold partition with incoming hot edge\n", | |
482 s_indent); | |
483 } | |
0 | 484 } |
485 } | |
486 | |
487 void | |
111 | 488 dump_edge_info (FILE *file, edge e, dump_flags_t flags, int do_succ) |
0 | 489 { |
490 basic_block side = (do_succ ? e->dest : e->src); | |
111 | 491 bool do_details = false; |
492 | |
493 if ((flags & TDF_DETAILS) != 0 | |
494 && (flags & TDF_SLIM) == 0) | |
495 do_details = true; | |
496 | |
497 if (side->index == ENTRY_BLOCK) | |
0 | 498 fputs (" ENTRY", file); |
111 | 499 else if (side->index == EXIT_BLOCK) |
0 | 500 fputs (" EXIT", file); |
501 else | |
502 fprintf (file, " %d", side->index); | |
503 | |
111 | 504 if (e->probability.initialized_p () && do_details) |
505 { | |
506 fprintf (file, " ["); | |
507 e->probability.dump (file); | |
508 fprintf (file, "] "); | |
509 } | |
0 | 510 |
111 | 511 if (e->count ().initialized_p () && do_details) |
0 | 512 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
513 fputs (" count:", file); |
111 | 514 e->count ().dump (file); |
0 | 515 } |
516 | |
111 | 517 if (e->flags && do_details) |
0 | 518 { |
111 | 519 static const char * const bitnames[] = |
520 { | |
521 #define DEF_EDGE_FLAG(NAME,IDX) #NAME , | |
522 #include "cfg-flags.def" | |
523 NULL | |
524 #undef DEF_EDGE_FLAG | |
525 }; | |
526 bool comma = false; | |
0 | 527 int i, flags = e->flags; |
528 | |
111 | 529 gcc_assert (e->flags <= EDGE_ALL_FLAGS); |
0 | 530 fputs (" (", file); |
531 for (i = 0; flags; i++) | |
532 if (flags & (1 << i)) | |
533 { | |
534 flags &= ~(1 << i); | |
535 | |
536 if (comma) | |
537 fputc (',', file); | |
111 | 538 fputs (bitnames[i], file); |
539 comma = true; | |
0 | 540 } |
541 | |
542 fputc (')', file); | |
543 } | |
544 } | |
111 | 545 |
546 DEBUG_FUNCTION void | |
547 debug (edge_def &ref) | |
548 { | |
549 /* FIXME (crowl): Is this desireable? */ | |
131 | 550 dump_edge_info (stderr, &ref, TDF_NONE, false); |
551 dump_edge_info (stderr, &ref, TDF_NONE, true); | |
111 | 552 } |
553 | |
554 DEBUG_FUNCTION void | |
555 debug (edge_def *ptr) | |
556 { | |
557 if (ptr) | |
558 debug (*ptr); | |
559 else | |
560 fprintf (stderr, "<nil>\n"); | |
561 } | |
131 | 562 |
563 static void | |
564 debug_slim (edge e) | |
565 { | |
566 fprintf (stderr, "<edge 0x%p (%d -> %d)>", (void *) e, | |
567 e->src->index, e->dest->index); | |
568 } | |
569 | |
570 DEFINE_DEBUG_VEC (edge) | |
571 DEFINE_DEBUG_HASH_SET (edge) | |
0 | 572 |
573 /* Simple routines to easily allocate AUX fields of basic blocks. */ | |
574 | |
575 static struct obstack block_aux_obstack; | |
576 static void *first_block_aux_obj = 0; | |
577 static struct obstack edge_aux_obstack; | |
578 static void *first_edge_aux_obj = 0; | |
579 | |
580 /* Allocate a memory block of SIZE as BB->aux. The obstack must | |
581 be first initialized by alloc_aux_for_blocks. */ | |
582 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
583 static void |
0 | 584 alloc_aux_for_block (basic_block bb, int size) |
585 { | |
586 /* Verify that aux field is clear. */ | |
587 gcc_assert (!bb->aux && first_block_aux_obj); | |
588 bb->aux = obstack_alloc (&block_aux_obstack, size); | |
589 memset (bb->aux, 0, size); | |
590 } | |
591 | |
592 /* Initialize the block_aux_obstack and if SIZE is nonzero, call | |
593 alloc_aux_for_block for each basic block. */ | |
594 | |
595 void | |
596 alloc_aux_for_blocks (int size) | |
597 { | |
598 static int initialized; | |
599 | |
600 if (!initialized) | |
601 { | |
602 gcc_obstack_init (&block_aux_obstack); | |
603 initialized = 1; | |
604 } | |
605 else | |
606 /* Check whether AUX data are still allocated. */ | |
607 gcc_assert (!first_block_aux_obj); | |
608 | |
609 first_block_aux_obj = obstack_alloc (&block_aux_obstack, 0); | |
610 if (size) | |
611 { | |
612 basic_block bb; | |
613 | |
111 | 614 FOR_ALL_BB_FN (bb, cfun) |
0 | 615 alloc_aux_for_block (bb, size); |
616 } | |
617 } | |
618 | |
619 /* Clear AUX pointers of all blocks. */ | |
620 | |
621 void | |
622 clear_aux_for_blocks (void) | |
623 { | |
624 basic_block bb; | |
625 | |
111 | 626 FOR_ALL_BB_FN (bb, cfun) |
0 | 627 bb->aux = NULL; |
628 } | |
629 | |
630 /* Free data allocated in block_aux_obstack and clear AUX pointers | |
631 of all blocks. */ | |
632 | |
633 void | |
634 free_aux_for_blocks (void) | |
635 { | |
636 gcc_assert (first_block_aux_obj); | |
637 obstack_free (&block_aux_obstack, first_block_aux_obj); | |
638 first_block_aux_obj = NULL; | |
639 | |
640 clear_aux_for_blocks (); | |
641 } | |
642 | |
111 | 643 /* Allocate a memory edge of SIZE as E->aux. The obstack must |
0 | 644 be first initialized by alloc_aux_for_edges. */ |
645 | |
111 | 646 void |
0 | 647 alloc_aux_for_edge (edge e, int size) |
648 { | |
649 /* Verify that aux field is clear. */ | |
650 gcc_assert (!e->aux && first_edge_aux_obj); | |
651 e->aux = obstack_alloc (&edge_aux_obstack, size); | |
652 memset (e->aux, 0, size); | |
653 } | |
654 | |
655 /* Initialize the edge_aux_obstack and if SIZE is nonzero, call | |
656 alloc_aux_for_edge for each basic edge. */ | |
657 | |
658 void | |
659 alloc_aux_for_edges (int size) | |
660 { | |
661 static int initialized; | |
662 | |
663 if (!initialized) | |
664 { | |
665 gcc_obstack_init (&edge_aux_obstack); | |
666 initialized = 1; | |
667 } | |
668 else | |
669 /* Check whether AUX data are still allocated. */ | |
670 gcc_assert (!first_edge_aux_obj); | |
671 | |
672 first_edge_aux_obj = obstack_alloc (&edge_aux_obstack, 0); | |
673 if (size) | |
674 { | |
675 basic_block bb; | |
676 | |
111 | 677 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), |
678 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb) | |
0 | 679 { |
680 edge e; | |
681 edge_iterator ei; | |
682 | |
683 FOR_EACH_EDGE (e, ei, bb->succs) | |
684 alloc_aux_for_edge (e, size); | |
685 } | |
686 } | |
687 } | |
688 | |
689 /* Clear AUX pointers of all edges. */ | |
690 | |
691 void | |
692 clear_aux_for_edges (void) | |
693 { | |
694 basic_block bb; | |
695 edge e; | |
696 | |
111 | 697 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), |
698 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb) | |
0 | 699 { |
700 edge_iterator ei; | |
701 FOR_EACH_EDGE (e, ei, bb->succs) | |
702 e->aux = NULL; | |
703 } | |
704 } | |
705 | |
706 /* Free data allocated in edge_aux_obstack and clear AUX pointers | |
707 of all edges. */ | |
708 | |
709 void | |
710 free_aux_for_edges (void) | |
711 { | |
712 gcc_assert (first_edge_aux_obj); | |
713 obstack_free (&edge_aux_obstack, first_edge_aux_obj); | |
714 first_edge_aux_obj = NULL; | |
715 | |
716 clear_aux_for_edges (); | |
717 } | |
718 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
719 DEBUG_FUNCTION void |
0 | 720 debug_bb (basic_block bb) |
721 { | |
111 | 722 dump_bb (stderr, bb, 0, dump_flags); |
0 | 723 } |
724 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
725 DEBUG_FUNCTION basic_block |
0 | 726 debug_bb_n (int n) |
727 { | |
111 | 728 basic_block bb = BASIC_BLOCK_FOR_FN (cfun, n); |
729 debug_bb (bb); | |
0 | 730 return bb; |
731 } | |
732 | |
111 | 733 /* Dumps cfg related information about basic block BB to OUTF. |
734 If HEADER is true, dump things that appear before the instructions | |
735 contained in BB. If FOOTER is true, dump things that appear after. | |
736 Flags are the TDF_* masks as documented in dumpfile.h. | |
737 NB: With TDF_DETAILS, it is assumed that cfun is available, so | |
738 that maybe_hot_bb_p and probably_never_executed_bb_p don't ICE. */ | |
0 | 739 |
111 | 740 void |
741 dump_bb_info (FILE *outf, basic_block bb, int indent, dump_flags_t flags, | |
742 bool do_header, bool do_footer) | |
0 | 743 { |
744 edge_iterator ei; | |
111 | 745 edge e; |
0 | 746 static const char * const bb_bitnames[] = |
747 { | |
111 | 748 #define DEF_BASIC_BLOCK_FLAG(NAME,IDX) #NAME , |
749 #include "cfg-flags.def" | |
750 NULL | |
751 #undef DEF_BASIC_BLOCK_FLAG | |
0 | 752 }; |
753 const unsigned n_bitnames = sizeof (bb_bitnames) / sizeof (char *); | |
111 | 754 bool first; |
755 char *s_indent = (char *) alloca ((size_t) indent + 1); | |
756 memset ((void *) s_indent, ' ', (size_t) indent); | |
757 s_indent[indent] = '\0'; | |
758 | |
759 gcc_assert (bb->flags <= BB_ALL_FLAGS); | |
760 | |
761 if (do_header) | |
762 { | |
763 unsigned i; | |
764 | |
765 fputs (";; ", outf); | |
766 fprintf (outf, "%sbasic block %d, loop depth %d", | |
767 s_indent, bb->index, bb_loop_depth (bb)); | |
768 if (flags & TDF_DETAILS) | |
769 { | |
770 struct function *fun = DECL_STRUCT_FUNCTION (current_function_decl); | |
771 if (bb->count.initialized_p ()) | |
772 { | |
773 fputs (", count ", outf); | |
774 bb->count.dump (outf); | |
775 } | |
776 if (maybe_hot_bb_p (fun, bb)) | |
777 fputs (", maybe hot", outf); | |
778 if (probably_never_executed_bb_p (fun, bb)) | |
779 fputs (", probably never executed", outf); | |
780 } | |
781 fputc ('\n', outf); | |
782 | |
783 if (flags & TDF_DETAILS) | |
784 { | |
785 check_bb_profile (bb, outf, indent); | |
786 fputs (";; ", outf); | |
787 fprintf (outf, "%s prev block ", s_indent); | |
788 if (bb->prev_bb) | |
789 fprintf (outf, "%d", bb->prev_bb->index); | |
790 else | |
791 fprintf (outf, "(nil)"); | |
792 fprintf (outf, ", next block "); | |
793 if (bb->next_bb) | |
794 fprintf (outf, "%d", bb->next_bb->index); | |
795 else | |
796 fprintf (outf, "(nil)"); | |
0 | 797 |
111 | 798 fputs (", flags:", outf); |
799 first = true; | |
800 for (i = 0; i < n_bitnames; i++) | |
801 if (bb->flags & (1 << i)) | |
802 { | |
803 if (first) | |
804 fputs (" (", outf); | |
805 else | |
806 fputs (", ", outf); | |
807 first = false; | |
808 fputs (bb_bitnames[i], outf); | |
809 } | |
810 if (!first) | |
811 fputc (')', outf); | |
812 fputc ('\n', outf); | |
813 } | |
0 | 814 |
111 | 815 fputs (";; ", outf); |
816 fprintf (outf, "%s pred: ", s_indent); | |
817 first = true; | |
818 FOR_EACH_EDGE (e, ei, bb->preds) | |
819 { | |
820 if (! first) | |
821 { | |
822 fputs (";; ", outf); | |
823 fprintf (outf, "%s ", s_indent); | |
824 } | |
825 first = false; | |
826 dump_edge_info (outf, e, flags, 0); | |
827 fputc ('\n', outf); | |
828 } | |
829 if (first) | |
830 fputc ('\n', outf); | |
831 } | |
0 | 832 |
111 | 833 if (do_footer) |
834 { | |
835 fputs (";; ", outf); | |
836 fprintf (outf, "%s succ: ", s_indent); | |
837 first = true; | |
838 FOR_EACH_EDGE (e, ei, bb->succs) | |
839 { | |
840 if (! first) | |
841 { | |
842 fputs (";; ", outf); | |
843 fprintf (outf, "%s ", s_indent); | |
844 } | |
845 first = false; | |
846 dump_edge_info (outf, e, flags, 1); | |
847 fputc ('\n', outf); | |
848 } | |
849 if (first) | |
850 fputc ('\n', outf); | |
851 } | |
0 | 852 } |
853 | |
854 /* Dumps a brief description of cfg to FILE. */ | |
855 | |
856 void | |
111 | 857 brief_dump_cfg (FILE *file, dump_flags_t flags) |
0 | 858 { |
859 basic_block bb; | |
860 | |
111 | 861 FOR_EACH_BB_FN (bb, cfun) |
0 | 862 { |
111 | 863 dump_bb_info (file, bb, 0, flags & TDF_DETAILS, true, true); |
0 | 864 } |
865 } | |
866 | |
131 | 867 /* An edge originally destinating BB of COUNT has been proved to |
0 | 868 leave the block by TAKEN_EDGE. Update profile of BB such that edge E can be |
869 redirected to destination of TAKEN_EDGE. | |
870 | |
871 This function may leave the profile inconsistent in the case TAKEN_EDGE | |
131 | 872 frequency or count is believed to be lower than COUNT |
0 | 873 respectively. */ |
874 void | |
131 | 875 update_bb_profile_for_threading (basic_block bb, |
111 | 876 profile_count count, edge taken_edge) |
0 | 877 { |
878 edge c; | |
111 | 879 profile_probability prob; |
0 | 880 edge_iterator ei; |
881 | |
111 | 882 if (bb->count < count) |
0 | 883 { |
884 if (dump_file) | |
885 fprintf (dump_file, "bb %i count became negative after threading", | |
886 bb->index); | |
887 } | |
111 | 888 bb->count -= count; |
889 | |
0 | 890 /* Compute the probability of TAKEN_EDGE being reached via threaded edge. |
891 Watch for overflows. */ | |
131 | 892 if (bb->count.nonzero_p ()) |
893 prob = count.probability_in (bb->count); | |
0 | 894 else |
111 | 895 prob = profile_probability::never (); |
0 | 896 if (prob > taken_edge->probability) |
897 { | |
898 if (dump_file) | |
111 | 899 { |
900 fprintf (dump_file, "Jump threading proved probability of edge " | |
901 "%i->%i too small (it is ", | |
902 taken_edge->src->index, taken_edge->dest->index); | |
903 taken_edge->probability.dump (dump_file); | |
904 fprintf (dump_file, " should be "); | |
905 prob.dump (dump_file); | |
906 fprintf (dump_file, ")\n"); | |
907 } | |
908 prob = taken_edge->probability.apply_scale (6, 8); | |
0 | 909 } |
910 | |
911 /* Now rescale the probabilities. */ | |
912 taken_edge->probability -= prob; | |
111 | 913 prob = prob.invert (); |
914 if (prob == profile_probability::never ()) | |
0 | 915 { |
916 if (dump_file) | |
131 | 917 fprintf (dump_file, "Edge probabilities of bb %i has been reset, " |
918 "count of block should end up being 0, it is non-zero\n", | |
919 bb->index); | |
111 | 920 EDGE_SUCC (bb, 0)->probability = profile_probability::guessed_always (); |
0 | 921 ei = ei_start (bb->succs); |
922 ei_next (&ei); | |
923 for (; (c = ei_safe_edge (ei)); ei_next (&ei)) | |
111 | 924 c->probability = profile_probability::guessed_never (); |
0 | 925 } |
111 | 926 else if (!(prob == profile_probability::always ())) |
0 | 927 { |
928 FOR_EACH_EDGE (c, ei, bb->succs) | |
111 | 929 c->probability /= prob; |
0 | 930 } |
931 | |
932 gcc_assert (bb == taken_edge->src); | |
933 } | |
934 | |
935 /* Multiply all frequencies of basic blocks in array BBS of length NBBS | |
111 | 936 by NUM/DEN, in profile_count arithmetic. More accurate than previous |
937 function but considerably slower. */ | |
938 void | |
939 scale_bbs_frequencies_profile_count (basic_block *bbs, int nbbs, | |
940 profile_count num, profile_count den) | |
941 { | |
942 int i; | |
131 | 943 if (num == profile_count::zero () || den.nonzero_p ()) |
944 for (i = 0; i < nbbs; i++) | |
111 | 945 bbs[i]->count = bbs[i]->count.apply_scale (num, den); |
946 } | |
0 | 947 |
111 | 948 /* Multiply all frequencies of basic blocks in array BBS of length NBBS |
949 by NUM/DEN, in profile_count arithmetic. More accurate than previous | |
950 function but considerably slower. */ | |
951 void | |
952 scale_bbs_frequencies (basic_block *bbs, int nbbs, | |
953 profile_probability p) | |
954 { | |
955 int i; | |
956 | |
957 for (i = 0; i < nbbs; i++) | |
131 | 958 bbs[i]->count = bbs[i]->count.apply_probability (p); |
111 | 959 } |
960 | |
961 /* Helper types for hash tables. */ | |
0 | 962 |
963 struct htab_bb_copy_original_entry | |
964 { | |
965 /* Block we are attaching info to. */ | |
966 int index1; | |
967 /* Index of original or copy (depending on the hashtable) */ | |
968 int index2; | |
969 }; | |
970 | |
111 | 971 struct bb_copy_hasher : nofree_ptr_hash <htab_bb_copy_original_entry> |
0 | 972 { |
111 | 973 static inline hashval_t hash (const htab_bb_copy_original_entry *); |
974 static inline bool equal (const htab_bb_copy_original_entry *existing, | |
975 const htab_bb_copy_original_entry * candidate); | |
976 }; | |
0 | 977 |
111 | 978 inline hashval_t |
979 bb_copy_hasher::hash (const htab_bb_copy_original_entry *data) | |
980 { | |
0 | 981 return data->index1; |
982 } | |
111 | 983 |
984 inline bool | |
985 bb_copy_hasher::equal (const htab_bb_copy_original_entry *data, | |
986 const htab_bb_copy_original_entry *data2) | |
0 | 987 { |
988 return data->index1 == data2->index1; | |
989 } | |
990 | |
111 | 991 /* Data structures used to maintain mapping between basic blocks and |
992 copies. */ | |
993 static hash_table<bb_copy_hasher> *bb_original; | |
994 static hash_table<bb_copy_hasher> *bb_copy; | |
995 | |
996 /* And between loops and copies. */ | |
997 static hash_table<bb_copy_hasher> *loop_copy; | |
998 static object_allocator<htab_bb_copy_original_entry> *original_copy_bb_pool; | |
999 | |
0 | 1000 /* Initialize the data structures to maintain mapping between blocks |
1001 and its copies. */ | |
1002 void | |
1003 initialize_original_copy_tables (void) | |
1004 { | |
111 | 1005 original_copy_bb_pool = new object_allocator<htab_bb_copy_original_entry> |
1006 ("original_copy"); | |
1007 bb_original = new hash_table<bb_copy_hasher> (10); | |
1008 bb_copy = new hash_table<bb_copy_hasher> (10); | |
1009 loop_copy = new hash_table<bb_copy_hasher> (10); | |
1010 } | |
1011 | |
1012 /* Reset the data structures to maintain mapping between blocks and | |
1013 its copies. */ | |
1014 | |
1015 void | |
1016 reset_original_copy_tables (void) | |
1017 { | |
1018 gcc_assert (original_copy_bb_pool); | |
1019 bb_original->empty (); | |
1020 bb_copy->empty (); | |
1021 loop_copy->empty (); | |
0 | 1022 } |
1023 | |
1024 /* Free the data structures to maintain mapping between blocks and | |
1025 its copies. */ | |
1026 void | |
1027 free_original_copy_tables (void) | |
1028 { | |
1029 gcc_assert (original_copy_bb_pool); | |
111 | 1030 delete bb_copy; |
0 | 1031 bb_copy = NULL; |
111 | 1032 delete bb_original; |
0 | 1033 bb_original = NULL; |
111 | 1034 delete loop_copy; |
0 | 1035 loop_copy = NULL; |
111 | 1036 delete original_copy_bb_pool; |
0 | 1037 original_copy_bb_pool = NULL; |
1038 } | |
1039 | |
111 | 1040 /* Return true iff we have had a call to initialize_original_copy_tables |
1041 without a corresponding call to free_original_copy_tables. */ | |
1042 | |
1043 bool | |
1044 original_copy_tables_initialized_p (void) | |
1045 { | |
1046 return original_copy_bb_pool != NULL; | |
1047 } | |
1048 | |
0 | 1049 /* Removes the value associated with OBJ from table TAB. */ |
1050 | |
1051 static void | |
111 | 1052 copy_original_table_clear (hash_table<bb_copy_hasher> *tab, unsigned obj) |
0 | 1053 { |
111 | 1054 htab_bb_copy_original_entry **slot; |
0 | 1055 struct htab_bb_copy_original_entry key, *elt; |
1056 | |
1057 if (!original_copy_bb_pool) | |
1058 return; | |
1059 | |
1060 key.index1 = obj; | |
111 | 1061 slot = tab->find_slot (&key, NO_INSERT); |
0 | 1062 if (!slot) |
1063 return; | |
1064 | |
111 | 1065 elt = *slot; |
1066 tab->clear_slot (slot); | |
1067 original_copy_bb_pool->remove (elt); | |
0 | 1068 } |
1069 | |
1070 /* Sets the value associated with OBJ in table TAB to VAL. | |
1071 Do nothing when data structures are not initialized. */ | |
1072 | |
1073 static void | |
111 | 1074 copy_original_table_set (hash_table<bb_copy_hasher> *tab, |
1075 unsigned obj, unsigned val) | |
0 | 1076 { |
1077 struct htab_bb_copy_original_entry **slot; | |
1078 struct htab_bb_copy_original_entry key; | |
1079 | |
1080 if (!original_copy_bb_pool) | |
1081 return; | |
1082 | |
1083 key.index1 = obj; | |
111 | 1084 slot = tab->find_slot (&key, INSERT); |
0 | 1085 if (!*slot) |
1086 { | |
111 | 1087 *slot = original_copy_bb_pool->allocate (); |
0 | 1088 (*slot)->index1 = obj; |
1089 } | |
1090 (*slot)->index2 = val; | |
1091 } | |
1092 | |
1093 /* Set original for basic block. Do nothing when data structures are not | |
1094 initialized so passes not needing this don't need to care. */ | |
1095 void | |
1096 set_bb_original (basic_block bb, basic_block original) | |
1097 { | |
1098 copy_original_table_set (bb_original, bb->index, original->index); | |
1099 } | |
1100 | |
1101 /* Get the original basic block. */ | |
1102 basic_block | |
1103 get_bb_original (basic_block bb) | |
1104 { | |
1105 struct htab_bb_copy_original_entry *entry; | |
1106 struct htab_bb_copy_original_entry key; | |
1107 | |
1108 gcc_assert (original_copy_bb_pool); | |
1109 | |
1110 key.index1 = bb->index; | |
111 | 1111 entry = bb_original->find (&key); |
0 | 1112 if (entry) |
111 | 1113 return BASIC_BLOCK_FOR_FN (cfun, entry->index2); |
0 | 1114 else |
1115 return NULL; | |
1116 } | |
1117 | |
1118 /* Set copy for basic block. Do nothing when data structures are not | |
1119 initialized so passes not needing this don't need to care. */ | |
1120 void | |
1121 set_bb_copy (basic_block bb, basic_block copy) | |
1122 { | |
1123 copy_original_table_set (bb_copy, bb->index, copy->index); | |
1124 } | |
1125 | |
1126 /* Get the copy of basic block. */ | |
1127 basic_block | |
1128 get_bb_copy (basic_block bb) | |
1129 { | |
1130 struct htab_bb_copy_original_entry *entry; | |
1131 struct htab_bb_copy_original_entry key; | |
1132 | |
1133 gcc_assert (original_copy_bb_pool); | |
1134 | |
1135 key.index1 = bb->index; | |
111 | 1136 entry = bb_copy->find (&key); |
0 | 1137 if (entry) |
111 | 1138 return BASIC_BLOCK_FOR_FN (cfun, entry->index2); |
0 | 1139 else |
1140 return NULL; | |
1141 } | |
1142 | |
1143 /* Set copy for LOOP to COPY. Do nothing when data structures are not | |
1144 initialized so passes not needing this don't need to care. */ | |
1145 | |
1146 void | |
1147 set_loop_copy (struct loop *loop, struct loop *copy) | |
1148 { | |
1149 if (!copy) | |
1150 copy_original_table_clear (loop_copy, loop->num); | |
1151 else | |
1152 copy_original_table_set (loop_copy, loop->num, copy->num); | |
1153 } | |
1154 | |
1155 /* Get the copy of LOOP. */ | |
1156 | |
1157 struct loop * | |
1158 get_loop_copy (struct loop *loop) | |
1159 { | |
1160 struct htab_bb_copy_original_entry *entry; | |
1161 struct htab_bb_copy_original_entry key; | |
1162 | |
1163 gcc_assert (original_copy_bb_pool); | |
1164 | |
1165 key.index1 = loop->num; | |
111 | 1166 entry = loop_copy->find (&key); |
0 | 1167 if (entry) |
111 | 1168 return get_loop (cfun, entry->index2); |
0 | 1169 else |
1170 return NULL; | |
1171 } |