1 /* Hooks for cfg representation specific functions.
2 Copyright (C) 2003-2022 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <s.pop@laposte.net>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "rtl.h"
26 #include "cfghooks.h"
27 #include "timevar.h"
28 #include "pretty-print.h"
29 #include "diagnostic-core.h"
30 #include "dumpfile.h"
31 #include "cfganal.h"
32 #include "tree.h"
33 #include "tree-ssa.h"
34 #include "cfgloop.h"
35 #include "sreal.h"
36 #include "profile.h"
37
38 /* Disable warnings about missing quoting in GCC diagnostics. */
39 #if __GNUC__ >= 10
40 # pragma GCC diagnostic push
41 # pragma GCC diagnostic ignored "-Wformat-diag"
42 #endif
43
44 /* A pointer to one of the hooks containers. */
45 static struct cfg_hooks *cfg_hooks;
46
47 /* Initialization of functions specific to the rtl IR. */
48 void
rtl_register_cfg_hooks(void)49 rtl_register_cfg_hooks (void)
50 {
51 cfg_hooks = &rtl_cfg_hooks;
52 }
53
54 /* Initialization of functions specific to the rtl IR. */
55 void
cfg_layout_rtl_register_cfg_hooks(void)56 cfg_layout_rtl_register_cfg_hooks (void)
57 {
58 cfg_hooks = &cfg_layout_rtl_cfg_hooks;
59 }
60
61 /* Initialization of functions specific to the tree IR. */
62
63 void
gimple_register_cfg_hooks(void)64 gimple_register_cfg_hooks (void)
65 {
66 cfg_hooks = &gimple_cfg_hooks;
67 }
68
69 struct cfg_hooks
get_cfg_hooks(void)70 get_cfg_hooks (void)
71 {
72 return *cfg_hooks;
73 }
74
75 void
set_cfg_hooks(struct cfg_hooks new_cfg_hooks)76 set_cfg_hooks (struct cfg_hooks new_cfg_hooks)
77 {
78 *cfg_hooks = new_cfg_hooks;
79 }
80
81 /* Returns current ir type. */
82
83 enum ir_type
current_ir_type(void)84 current_ir_type (void)
85 {
86 if (cfg_hooks == &gimple_cfg_hooks)
87 return IR_GIMPLE;
88 else if (cfg_hooks == &rtl_cfg_hooks)
89 return IR_RTL_CFGRTL;
90 else if (cfg_hooks == &cfg_layout_rtl_cfg_hooks)
91 return IR_RTL_CFGLAYOUT;
92 else
93 gcc_unreachable ();
94 }
95
96 /* Verify the CFG consistency.
97
98 Currently it does following: checks edge and basic block list correctness
99 and calls into IL dependent checking then. */
100
101 DEBUG_FUNCTION void
verify_flow_info(void)102 verify_flow_info (void)
103 {
104 size_t *edge_checksum;
105 int err = 0;
106 basic_block bb, last_bb_seen;
107 basic_block *last_visited;
108
109 timevar_push (TV_CFG_VERIFY);
110 last_visited = XCNEWVEC (basic_block, last_basic_block_for_fn (cfun));
111 edge_checksum = XCNEWVEC (size_t, last_basic_block_for_fn (cfun));
112
113 /* Check bb chain & numbers. */
114 last_bb_seen = ENTRY_BLOCK_PTR_FOR_FN (cfun);
115 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb, NULL, next_bb)
116 {
117 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
118 && bb != BASIC_BLOCK_FOR_FN (cfun, bb->index))
119 {
120 error ("bb %d on wrong place", bb->index);
121 err = 1;
122 }
123
124 if (bb->prev_bb != last_bb_seen)
125 {
126 error ("prev_bb of %d should be %d, not %d",
127 bb->index, last_bb_seen->index, bb->prev_bb->index);
128 err = 1;
129 }
130
131 last_bb_seen = bb;
132 }
133
134 /* Now check the basic blocks (boundaries etc.) */
135 FOR_EACH_BB_REVERSE_FN (bb, cfun)
136 {
137 int n_fallthru = 0;
138 edge e;
139 edge_iterator ei;
140
141 if (bb->loop_father != NULL && current_loops == NULL)
142 {
143 error ("verify_flow_info: Block %i has loop_father, but there are no loops",
144 bb->index);
145 err = 1;
146 }
147 if (bb->loop_father == NULL && current_loops != NULL)
148 {
149 error ("verify_flow_info: Block %i lacks loop_father", bb->index);
150 err = 1;
151 }
152
153 if (!bb->count.verify ())
154 {
155 error ("verify_flow_info: Wrong count of block %i", bb->index);
156 err = 1;
157 }
158 /* FIXME: Graphite and SLJL and target code still tends to produce
159 edges with no probability. */
160 if (profile_status_for_fn (cfun) >= PROFILE_GUESSED
161 && !bb->count.initialized_p () && !flag_graphite && 0)
162 {
163 error ("verify_flow_info: Missing count of block %i", bb->index);
164 err = 1;
165 }
166
167 if (bb->flags & ~cfun->cfg->bb_flags_allocated)
168 {
169 error ("verify_flow_info: unallocated flag set on BB %d", bb->index);
170 err = 1;
171 }
172
173 FOR_EACH_EDGE (e, ei, bb->succs)
174 {
175 if (last_visited [e->dest->index] == bb)
176 {
177 error ("verify_flow_info: Duplicate edge %i->%i",
178 e->src->index, e->dest->index);
179 err = 1;
180 }
181 /* FIXME: Graphite and SLJL and target code still tends to produce
182 edges with no probability. */
183 if (profile_status_for_fn (cfun) >= PROFILE_GUESSED
184 && !e->probability.initialized_p () && !flag_graphite && 0)
185 {
186 error ("Uninitialized probability of edge %i->%i", e->src->index,
187 e->dest->index);
188 err = 1;
189 }
190 if (!e->probability.verify ())
191 {
192 error ("verify_flow_info: Wrong probability of edge %i->%i",
193 e->src->index, e->dest->index);
194 err = 1;
195 }
196
197 last_visited [e->dest->index] = bb;
198
199 if (e->flags & EDGE_FALLTHRU)
200 n_fallthru++;
201
202 if (e->src != bb)
203 {
204 error ("verify_flow_info: Basic block %d succ edge is corrupted",
205 bb->index);
206 fprintf (stderr, "Predecessor: ");
207 dump_edge_info (stderr, e, TDF_DETAILS, 0);
208 fprintf (stderr, "\nSuccessor: ");
209 dump_edge_info (stderr, e, TDF_DETAILS, 1);
210 fprintf (stderr, "\n");
211 err = 1;
212 }
213
214 if (e->flags & ~cfun->cfg->edge_flags_allocated)
215 {
216 error ("verify_flow_info: unallocated edge flag set on %d -> %d",
217 e->src->index, e->dest->index);
218 err = 1;
219 }
220
221 edge_checksum[e->dest->index] += (size_t) e;
222 }
223 if (n_fallthru > 1)
224 {
225 error ("wrong amount of branch edges after unconditional jump %i", bb->index);
226 err = 1;
227 }
228
229 FOR_EACH_EDGE (e, ei, bb->preds)
230 {
231 if (e->dest != bb)
232 {
233 error ("basic block %d pred edge is corrupted", bb->index);
234 fputs ("Predecessor: ", stderr);
235 dump_edge_info (stderr, e, TDF_DETAILS, 0);
236 fputs ("\nSuccessor: ", stderr);
237 dump_edge_info (stderr, e, TDF_DETAILS, 1);
238 fputc ('\n', stderr);
239 err = 1;
240 }
241
242 if (ei.index != e->dest_idx)
243 {
244 error ("basic block %d pred edge is corrupted", bb->index);
245 error ("its dest_idx should be %d, not %d",
246 ei.index, e->dest_idx);
247 fputs ("Predecessor: ", stderr);
248 dump_edge_info (stderr, e, TDF_DETAILS, 0);
249 fputs ("\nSuccessor: ", stderr);
250 dump_edge_info (stderr, e, TDF_DETAILS, 1);
251 fputc ('\n', stderr);
252 err = 1;
253 }
254
255 edge_checksum[e->dest->index] -= (size_t) e;
256 }
257 }
258
259 /* Complete edge checksumming for ENTRY and EXIT. */
260 {
261 edge e;
262 edge_iterator ei;
263
264 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
265 edge_checksum[e->dest->index] += (size_t) e;
266
267 FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
268 edge_checksum[e->dest->index] -= (size_t) e;
269 }
270
271 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
272 if (edge_checksum[bb->index])
273 {
274 error ("basic block %i edge lists are corrupted", bb->index);
275 err = 1;
276 }
277
278 /* Clean up. */
279 free (last_visited);
280 free (edge_checksum);
281
282 if (cfg_hooks->verify_flow_info)
283 err |= cfg_hooks->verify_flow_info ();
284 if (err)
285 internal_error ("verify_flow_info failed");
286 timevar_pop (TV_CFG_VERIFY);
287 }
288
289 /* Print out one basic block BB to file OUTF. INDENT is printed at the
290 start of each new line. FLAGS are the TDF_* flags in dumpfile.h.
291
292 This function takes care of the purely graph related information.
293 The cfg hook for the active representation should dump
294 representation-specific information. */
295
296 void
dump_bb(FILE * outf,basic_block bb,int indent,dump_flags_t flags)297 dump_bb (FILE *outf, basic_block bb, int indent, dump_flags_t flags)
298 {
299 if (flags & TDF_BLOCKS)
300 dump_bb_info (outf, bb, indent, flags, true, false);
301 if (cfg_hooks->dump_bb)
302 cfg_hooks->dump_bb (outf, bb, indent, flags);
303 if (flags & TDF_BLOCKS)
304 dump_bb_info (outf, bb, indent, flags, false, true);
305 fputc ('\n', outf);
306 }
307
308 DEBUG_FUNCTION void
debug(basic_block_def & ref)309 debug (basic_block_def &ref)
310 {
311 dump_bb (stderr, &ref, 0, TDF_NONE);
312 }
313
314 DEBUG_FUNCTION void
debug(basic_block_def * ptr)315 debug (basic_block_def *ptr)
316 {
317 if (ptr)
318 debug (*ptr);
319 else
320 fprintf (stderr, "<nil>\n");
321 }
322
323 static void
debug_slim(basic_block ptr)324 debug_slim (basic_block ptr)
325 {
326 fprintf (stderr, "<basic_block %p (%d)>", (void *) ptr, ptr->index);
327 }
328
329 DEFINE_DEBUG_VEC (basic_block_def *)
DEFINE_DEBUG_HASH_SET(basic_block_def *)330 DEFINE_DEBUG_HASH_SET (basic_block_def *)
331
332 /* Dumps basic block BB to pretty-printer PP, for use as a label of
333 a DOT graph record-node. The implementation of this hook is
334 expected to write the label to the stream that is attached to PP.
335 Field separators between instructions are pipe characters printed
336 verbatim. Instructions should be written with some characters
337 escaped, using pp_write_text_as_dot_label_to_stream(). */
338
339 void
340 dump_bb_for_graph (pretty_printer *pp, basic_block bb)
341 {
342 if (!cfg_hooks->dump_bb_for_graph)
343 internal_error ("%s does not support dump_bb_for_graph",
344 cfg_hooks->name);
345 /* TODO: Add pretty printer for counter. */
346 if (bb->count.initialized_p ())
347 pp_printf (pp, "COUNT:" "%" PRId64, bb->count.to_gcov_type ());
348 pp_write_text_to_stream (pp);
349 if (!(dump_flags & TDF_SLIM))
350 cfg_hooks->dump_bb_for_graph (pp, bb);
351 }
352
353 /* Dump the complete CFG to FILE. FLAGS are the TDF_* flags in dumpfile.h. */
354 void
dump_flow_info(FILE * file,dump_flags_t flags)355 dump_flow_info (FILE *file, dump_flags_t flags)
356 {
357 basic_block bb;
358
359 fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks_for_fn (cfun),
360 n_edges_for_fn (cfun));
361 FOR_ALL_BB_FN (bb, cfun)
362 dump_bb (file, bb, 0, flags);
363
364 putc ('\n', file);
365 }
366
367 /* Like above, but dump to stderr. To be called from debuggers. */
368 void debug_flow_info (void);
369 DEBUG_FUNCTION void
debug_flow_info(void)370 debug_flow_info (void)
371 {
372 dump_flow_info (stderr, TDF_DETAILS);
373 }
374
375 /* Redirect edge E to the given basic block DEST and update underlying program
376 representation. Returns edge representing redirected branch (that may not
377 be equivalent to E in the case of duplicate edges being removed) or NULL
378 if edge is not easily redirectable for whatever reason. */
379
380 edge
redirect_edge_and_branch(edge e,basic_block dest)381 redirect_edge_and_branch (edge e, basic_block dest)
382 {
383 edge ret;
384
385 if (!cfg_hooks->redirect_edge_and_branch)
386 internal_error ("%s does not support redirect_edge_and_branch",
387 cfg_hooks->name);
388
389 ret = cfg_hooks->redirect_edge_and_branch (e, dest);
390
391 /* If RET != E, then either the redirection failed, or the edge E
392 was removed since RET already lead to the same destination. */
393 if (current_loops != NULL && ret == e)
394 rescan_loop_exit (e, false, false);
395
396 return ret;
397 }
398
399 /* Returns true if it is possible to remove the edge E by redirecting it
400 to the destination of the other edge going from its source. */
401
402 bool
can_remove_branch_p(const_edge e)403 can_remove_branch_p (const_edge e)
404 {
405 if (!cfg_hooks->can_remove_branch_p)
406 internal_error ("%s does not support can_remove_branch_p",
407 cfg_hooks->name);
408
409 if (EDGE_COUNT (e->src->succs) != 2)
410 return false;
411
412 return cfg_hooks->can_remove_branch_p (e);
413 }
414
415 /* Removes E, by redirecting it to the destination of the other edge going
416 from its source. Can_remove_branch_p must be true for E, hence this
417 operation cannot fail. */
418
419 void
remove_branch(edge e)420 remove_branch (edge e)
421 {
422 edge other;
423 basic_block src = e->src;
424 int irr;
425
426 gcc_assert (EDGE_COUNT (e->src->succs) == 2);
427
428 other = EDGE_SUCC (src, EDGE_SUCC (src, 0) == e);
429 irr = other->flags & EDGE_IRREDUCIBLE_LOOP;
430
431 e = redirect_edge_and_branch (e, other->dest);
432 gcc_assert (e != NULL);
433
434 e->flags &= ~EDGE_IRREDUCIBLE_LOOP;
435 e->flags |= irr;
436 }
437
438 /* Removes edge E from cfg. Unlike remove_branch, it does not update IL. */
439
440 void
remove_edge(edge e)441 remove_edge (edge e)
442 {
443 if (current_loops != NULL)
444 {
445 rescan_loop_exit (e, false, true);
446
447 /* Removal of an edge inside an irreducible region or which leads
448 to an irreducible region can turn the region into a natural loop.
449 In that case, ask for the loop structure fixups.
450
451 FIXME: Note that LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS is not always
452 set, so always ask for fixups when removing an edge in that case. */
453 if (!loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
454 || (e->flags & EDGE_IRREDUCIBLE_LOOP)
455 || (e->dest->flags & BB_IRREDUCIBLE_LOOP))
456 loops_state_set (LOOPS_NEED_FIXUP);
457 }
458
459 /* This is probably not needed, but it doesn't hurt. */
460 /* FIXME: This should be called via a remove_edge hook. */
461 if (current_ir_type () == IR_GIMPLE)
462 redirect_edge_var_map_clear (e);
463
464 remove_edge_raw (e);
465 }
466
467 /* Like redirect_edge_succ but avoid possible duplicate edge. */
468
469 edge
redirect_edge_succ_nodup(edge e,basic_block new_succ)470 redirect_edge_succ_nodup (edge e, basic_block new_succ)
471 {
472 edge s;
473
474 s = find_edge (e->src, new_succ);
475 if (s && s != e)
476 {
477 s->flags |= e->flags;
478 s->probability += e->probability;
479 /* FIXME: This should be called via a hook and only for IR_GIMPLE. */
480 redirect_edge_var_map_dup (s, e);
481 remove_edge (e);
482 e = s;
483 }
484 else
485 redirect_edge_succ (e, new_succ);
486
487 return e;
488 }
489
490 /* Redirect the edge E to basic block DEST even if it requires creating
491 of a new basic block; then it returns the newly created basic block.
492 Aborts when redirection is impossible. */
493
494 basic_block
redirect_edge_and_branch_force(edge e,basic_block dest)495 redirect_edge_and_branch_force (edge e, basic_block dest)
496 {
497 basic_block ret, src = e->src;
498
499 if (!cfg_hooks->redirect_edge_and_branch_force)
500 internal_error ("%s does not support redirect_edge_and_branch_force",
501 cfg_hooks->name);
502
503 if (current_loops != NULL)
504 rescan_loop_exit (e, false, true);
505
506 ret = cfg_hooks->redirect_edge_and_branch_force (e, dest);
507
508 if (ret != NULL && dom_info_available_p (CDI_DOMINATORS))
509 set_immediate_dominator (CDI_DOMINATORS, ret, src);
510
511 if (current_loops != NULL)
512 {
513 if (ret != NULL)
514 {
515 class loop *loop
516 = find_common_loop (single_pred (ret)->loop_father,
517 single_succ (ret)->loop_father);
518 add_bb_to_loop (ret, loop);
519 }
520 else if (find_edge (src, dest) == e)
521 rescan_loop_exit (e, true, false);
522 }
523
524 return ret;
525 }
526
527 /* Splits basic block BB after the specified instruction I (but at least after
528 the labels). If I is NULL, splits just after labels. The newly created edge
529 is returned. The new basic block is created just after the old one. */
530
531 static edge
split_block_1(basic_block bb,void * i)532 split_block_1 (basic_block bb, void *i)
533 {
534 basic_block new_bb;
535 edge res;
536
537 if (!cfg_hooks->split_block)
538 internal_error ("%s does not support split_block", cfg_hooks->name);
539
540 new_bb = cfg_hooks->split_block (bb, i);
541 if (!new_bb)
542 return NULL;
543
544 new_bb->count = bb->count;
545 new_bb->discriminator = bb->discriminator;
546
547 if (dom_info_available_p (CDI_DOMINATORS))
548 {
549 redirect_immediate_dominators (CDI_DOMINATORS, bb, new_bb);
550 set_immediate_dominator (CDI_DOMINATORS, new_bb, bb);
551 }
552
553 if (current_loops != NULL)
554 {
555 edge_iterator ei;
556 edge e;
557 add_bb_to_loop (new_bb, bb->loop_father);
558 /* Identify all loops bb may have been the latch of and adjust them. */
559 FOR_EACH_EDGE (e, ei, new_bb->succs)
560 if (e->dest->loop_father->latch == bb)
561 e->dest->loop_father->latch = new_bb;
562 }
563
564 res = make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU);
565
566 if (bb->flags & BB_IRREDUCIBLE_LOOP)
567 {
568 new_bb->flags |= BB_IRREDUCIBLE_LOOP;
569 res->flags |= EDGE_IRREDUCIBLE_LOOP;
570 }
571
572 return res;
573 }
574
575 edge
split_block(basic_block bb,gimple * i)576 split_block (basic_block bb, gimple *i)
577 {
578 return split_block_1 (bb, i);
579 }
580
581 edge
split_block(basic_block bb,rtx i)582 split_block (basic_block bb, rtx i)
583 {
584 return split_block_1 (bb, i);
585 }
586
587 /* Splits block BB just after labels. The newly created edge is returned. */
588
589 edge
split_block_after_labels(basic_block bb)590 split_block_after_labels (basic_block bb)
591 {
592 return split_block_1 (bb, NULL);
593 }
594
595 /* Moves block BB immediately after block AFTER. Returns false if the
596 movement was impossible. */
597
598 bool
move_block_after(basic_block bb,basic_block after)599 move_block_after (basic_block bb, basic_block after)
600 {
601 bool ret;
602
603 if (!cfg_hooks->move_block_after)
604 internal_error ("%s does not support move_block_after", cfg_hooks->name);
605
606 ret = cfg_hooks->move_block_after (bb, after);
607
608 return ret;
609 }
610
611 /* Deletes the basic block BB. */
612
613 void
delete_basic_block(basic_block bb)614 delete_basic_block (basic_block bb)
615 {
616 if (!cfg_hooks->delete_basic_block)
617 internal_error ("%s does not support delete_basic_block", cfg_hooks->name);
618
619 cfg_hooks->delete_basic_block (bb);
620
621 if (current_loops != NULL)
622 {
623 class loop *loop = bb->loop_father;
624
625 /* If we remove the header or the latch of a loop, mark the loop for
626 removal. */
627 if (loop->latch == bb
628 || loop->header == bb)
629 mark_loop_for_removal (loop);
630
631 remove_bb_from_loops (bb);
632 }
633
634 /* Remove the edges into and out of this block. Note that there may
635 indeed be edges in, if we are removing an unreachable loop. */
636 while (EDGE_COUNT (bb->preds) != 0)
637 remove_edge (EDGE_PRED (bb, 0));
638 while (EDGE_COUNT (bb->succs) != 0)
639 remove_edge (EDGE_SUCC (bb, 0));
640
641 if (dom_info_available_p (CDI_DOMINATORS))
642 delete_from_dominance_info (CDI_DOMINATORS, bb);
643 if (dom_info_available_p (CDI_POST_DOMINATORS))
644 delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
645
646 /* Remove the basic block from the array. */
647 expunge_block (bb);
648 }
649
650 /* Splits edge E and returns the newly created basic block. */
651
652 basic_block
split_edge(edge e)653 split_edge (edge e)
654 {
655 basic_block ret;
656 profile_count count = e->count ();
657 edge f;
658 bool irr = (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
659 bool back = (e->flags & EDGE_DFS_BACK) != 0;
660 class loop *loop;
661 basic_block src = e->src, dest = e->dest;
662
663 if (!cfg_hooks->split_edge)
664 internal_error ("%s does not support split_edge", cfg_hooks->name);
665
666 if (current_loops != NULL)
667 rescan_loop_exit (e, false, true);
668
669 ret = cfg_hooks->split_edge (e);
670 ret->count = count;
671 single_succ_edge (ret)->probability = profile_probability::always ();
672
673 if (irr)
674 {
675 ret->flags |= BB_IRREDUCIBLE_LOOP;
676 single_pred_edge (ret)->flags |= EDGE_IRREDUCIBLE_LOOP;
677 single_succ_edge (ret)->flags |= EDGE_IRREDUCIBLE_LOOP;
678 }
679 if (back)
680 {
681 single_pred_edge (ret)->flags &= ~EDGE_DFS_BACK;
682 single_succ_edge (ret)->flags |= EDGE_DFS_BACK;
683 }
684
685 if (dom_info_available_p (CDI_DOMINATORS))
686 set_immediate_dominator (CDI_DOMINATORS, ret, single_pred (ret));
687
688 if (dom_info_state (CDI_DOMINATORS) >= DOM_NO_FAST_QUERY)
689 {
690 /* There are two cases:
691
692 If the immediate dominator of e->dest is not e->src, it
693 remains unchanged.
694
695 If immediate dominator of e->dest is e->src, it may become
696 ret, provided that all other predecessors of e->dest are
697 dominated by e->dest. */
698
699 if (get_immediate_dominator (CDI_DOMINATORS, single_succ (ret))
700 == single_pred (ret))
701 {
702 edge_iterator ei;
703 FOR_EACH_EDGE (f, ei, single_succ (ret)->preds)
704 {
705 if (f == single_succ_edge (ret))
706 continue;
707
708 if (!dominated_by_p (CDI_DOMINATORS, f->src,
709 single_succ (ret)))
710 break;
711 }
712
713 if (!f)
714 set_immediate_dominator (CDI_DOMINATORS, single_succ (ret), ret);
715 }
716 }
717
718 if (current_loops != NULL)
719 {
720 loop = find_common_loop (src->loop_father, dest->loop_father);
721 add_bb_to_loop (ret, loop);
722
723 /* If we split the latch edge of loop adjust the latch block. */
724 if (loop->latch == src
725 && loop->header == dest)
726 loop->latch = ret;
727 }
728
729 return ret;
730 }
731
732 /* Creates a new basic block just after the basic block AFTER.
733 HEAD and END are the first and the last statement belonging
734 to the block. If both are NULL, an empty block is created. */
735
736 static basic_block
create_basic_block_1(void * head,void * end,basic_block after)737 create_basic_block_1 (void *head, void *end, basic_block after)
738 {
739 basic_block ret;
740
741 if (!cfg_hooks->create_basic_block)
742 internal_error ("%s does not support create_basic_block", cfg_hooks->name);
743
744 ret = cfg_hooks->create_basic_block (head, end, after);
745
746 if (dom_info_available_p (CDI_DOMINATORS))
747 add_to_dominance_info (CDI_DOMINATORS, ret);
748 if (dom_info_available_p (CDI_POST_DOMINATORS))
749 add_to_dominance_info (CDI_POST_DOMINATORS, ret);
750
751 return ret;
752 }
753
754 basic_block
create_basic_block(gimple_seq seq,basic_block after)755 create_basic_block (gimple_seq seq, basic_block after)
756 {
757 return create_basic_block_1 (seq, NULL, after);
758 }
759
760 basic_block
create_basic_block(rtx head,rtx end,basic_block after)761 create_basic_block (rtx head, rtx end, basic_block after)
762 {
763 return create_basic_block_1 (head, end, after);
764 }
765
766
767 /* Creates an empty basic block just after basic block AFTER. */
768
769 basic_block
create_empty_bb(basic_block after)770 create_empty_bb (basic_block after)
771 {
772 return create_basic_block_1 (NULL, NULL, after);
773 }
774
775 /* Checks whether we may merge blocks BB1 and BB2. */
776
777 bool
can_merge_blocks_p(basic_block bb1,basic_block bb2)778 can_merge_blocks_p (basic_block bb1, basic_block bb2)
779 {
780 bool ret;
781
782 if (!cfg_hooks->can_merge_blocks_p)
783 internal_error ("%s does not support can_merge_blocks_p", cfg_hooks->name);
784
785 ret = cfg_hooks->can_merge_blocks_p (bb1, bb2);
786
787 return ret;
788 }
789
790 void
predict_edge(edge e,enum br_predictor predictor,int probability)791 predict_edge (edge e, enum br_predictor predictor, int probability)
792 {
793 if (!cfg_hooks->predict_edge)
794 internal_error ("%s does not support predict_edge", cfg_hooks->name);
795
796 cfg_hooks->predict_edge (e, predictor, probability);
797 }
798
799 bool
predicted_by_p(const_basic_block bb,enum br_predictor predictor)800 predicted_by_p (const_basic_block bb, enum br_predictor predictor)
801 {
802 if (!cfg_hooks->predict_edge)
803 internal_error ("%s does not support predicted_by_p", cfg_hooks->name);
804
805 return cfg_hooks->predicted_by_p (bb, predictor);
806 }
807
808 /* Merges basic block B into basic block A. */
809
810 void
merge_blocks(basic_block a,basic_block b)811 merge_blocks (basic_block a, basic_block b)
812 {
813 edge e;
814 edge_iterator ei;
815
816 if (!cfg_hooks->merge_blocks)
817 internal_error ("%s does not support merge_blocks", cfg_hooks->name);
818
819 cfg_hooks->merge_blocks (a, b);
820
821 if (current_loops != NULL)
822 {
823 /* If the block we merge into is a loop header do nothing unless ... */
824 if (a->loop_father->header == a)
825 {
826 /* ... we merge two loop headers, in which case we kill
827 the inner loop. */
828 if (b->loop_father->header == b)
829 mark_loop_for_removal (b->loop_father);
830 }
831 /* If we merge a loop header into its predecessor, update the loop
832 structure. */
833 else if (b->loop_father->header == b)
834 {
835 remove_bb_from_loops (a);
836 add_bb_to_loop (a, b->loop_father);
837 a->loop_father->header = a;
838 }
839 /* If we merge a loop latch into its predecessor, update the loop
840 structure. */
841 if (b->loop_father->latch
842 && b->loop_father->latch == b)
843 b->loop_father->latch = a;
844 remove_bb_from_loops (b);
845 }
846
847 /* Normally there should only be one successor of A and that is B, but
848 partway though the merge of blocks for conditional_execution we'll
849 be merging a TEST block with THEN and ELSE successors. Free the
850 whole lot of them and hope the caller knows what they're doing. */
851
852 while (EDGE_COUNT (a->succs) != 0)
853 remove_edge (EDGE_SUCC (a, 0));
854
855 /* Adjust the edges out of B for the new owner. */
856 FOR_EACH_EDGE (e, ei, b->succs)
857 {
858 e->src = a;
859 if (current_loops != NULL)
860 {
861 /* If b was a latch, a now is. */
862 if (e->dest->loop_father->latch == b)
863 e->dest->loop_father->latch = a;
864 rescan_loop_exit (e, true, false);
865 }
866 }
867 a->succs = b->succs;
868 a->flags |= b->flags;
869
870 /* B hasn't quite yet ceased to exist. Attempt to prevent mishap. */
871 b->preds = b->succs = NULL;
872
873 if (dom_info_available_p (CDI_DOMINATORS))
874 redirect_immediate_dominators (CDI_DOMINATORS, b, a);
875
876 if (dom_info_available_p (CDI_DOMINATORS))
877 delete_from_dominance_info (CDI_DOMINATORS, b);
878 if (dom_info_available_p (CDI_POST_DOMINATORS))
879 delete_from_dominance_info (CDI_POST_DOMINATORS, b);
880
881 expunge_block (b);
882 }
883
884 /* Split BB into entry part and the rest (the rest is the newly created block).
885 Redirect those edges for that REDIRECT_EDGE_P returns true to the entry
886 part. Returns the edge connecting the entry part to the rest. */
887
888 edge
make_forwarder_block(basic_block bb,bool (* redirect_edge_p)(edge),void (* new_bb_cbk)(basic_block))889 make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
890 void (*new_bb_cbk) (basic_block))
891 {
892 edge e, fallthru;
893 edge_iterator ei;
894 basic_block dummy, jump;
895 class loop *loop, *ploop, *cloop;
896
897 if (!cfg_hooks->make_forwarder_block)
898 internal_error ("%s does not support make_forwarder_block",
899 cfg_hooks->name);
900
901 fallthru = split_block_after_labels (bb);
902 dummy = fallthru->src;
903 dummy->count = profile_count::zero ();
904 bb = fallthru->dest;
905
906 /* Redirect back edges we want to keep. */
907 for (ei = ei_start (dummy->preds); (e = ei_safe_edge (ei)); )
908 {
909 basic_block e_src;
910
911 if (redirect_edge_p (e))
912 {
913 dummy->count += e->count ();
914 ei_next (&ei);
915 continue;
916 }
917
918 e_src = e->src;
919 jump = redirect_edge_and_branch_force (e, bb);
920 if (jump != NULL)
921 {
922 /* If we redirected the loop latch edge, the JUMP block now acts like
923 the new latch of the loop. */
924 if (current_loops != NULL
925 && dummy->loop_father != NULL
926 && dummy->loop_father->header == dummy
927 && dummy->loop_father->latch == e_src)
928 dummy->loop_father->latch = jump;
929
930 if (new_bb_cbk != NULL)
931 new_bb_cbk (jump);
932 }
933 }
934
935 if (dom_info_available_p (CDI_DOMINATORS))
936 {
937 vec<basic_block> doms_to_fix;
938 doms_to_fix.create (2);
939 doms_to_fix.quick_push (dummy);
940 doms_to_fix.quick_push (bb);
941 iterate_fix_dominators (CDI_DOMINATORS, doms_to_fix, false);
942 doms_to_fix.release ();
943 }
944
945 if (current_loops != NULL)
946 {
947 /* If we do not split a loop header, then both blocks belong to the
948 same loop. In case we split loop header and do not redirect the
949 latch edge to DUMMY, then DUMMY belongs to the outer loop, and
950 BB becomes the new header. If latch is not recorded for the loop,
951 we leave this updating on the caller (this may only happen during
952 loop analysis). */
953 loop = dummy->loop_father;
954 if (loop->header == dummy
955 && loop->latch != NULL
956 && find_edge (loop->latch, dummy) == NULL)
957 {
958 remove_bb_from_loops (dummy);
959 loop->header = bb;
960
961 cloop = loop;
962 FOR_EACH_EDGE (e, ei, dummy->preds)
963 {
964 cloop = find_common_loop (cloop, e->src->loop_father);
965 }
966 add_bb_to_loop (dummy, cloop);
967 }
968
969 /* In case we split loop latch, update it. */
970 for (ploop = loop; ploop; ploop = loop_outer (ploop))
971 if (ploop->latch == dummy)
972 ploop->latch = bb;
973 }
974
975 cfg_hooks->make_forwarder_block (fallthru);
976
977 return fallthru;
978 }
979
980 /* Try to make the edge fallthru. */
981
982 void
tidy_fallthru_edge(edge e)983 tidy_fallthru_edge (edge e)
984 {
985 if (cfg_hooks->tidy_fallthru_edge)
986 cfg_hooks->tidy_fallthru_edge (e);
987 }
988
989 /* Fix up edges that now fall through, or rather should now fall through
990 but previously required a jump around now deleted blocks. Simplify
991 the search by only examining blocks numerically adjacent, since this
992 is how they were created.
993
994 ??? This routine is currently RTL specific. */
995
996 void
tidy_fallthru_edges(void)997 tidy_fallthru_edges (void)
998 {
999 basic_block b, c;
1000
1001 if (!cfg_hooks->tidy_fallthru_edge)
1002 return;
1003
1004 if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
1005 return;
1006
1007 FOR_BB_BETWEEN (b, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb,
1008 EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb, next_bb)
1009 {
1010 edge s;
1011
1012 c = b->next_bb;
1013
1014 /* We care about simple conditional or unconditional jumps with
1015 a single successor.
1016
1017 If we had a conditional branch to the next instruction when
1018 CFG was built, then there will only be one out edge for the
1019 block which ended with the conditional branch (since we do
1020 not create duplicate edges).
1021
1022 Furthermore, the edge will be marked as a fallthru because we
1023 merge the flags for the duplicate edges. So we do not want to
1024 check that the edge is not a FALLTHRU edge. */
1025
1026 if (single_succ_p (b))
1027 {
1028 s = single_succ_edge (b);
1029 if (! (s->flags & EDGE_COMPLEX)
1030 && s->dest == c
1031 && !(JUMP_P (BB_END (b)) && CROSSING_JUMP_P (BB_END (b))))
1032 tidy_fallthru_edge (s);
1033 }
1034 }
1035 }
1036
1037 /* Edge E is assumed to be fallthru edge. Emit needed jump instruction
1038 (and possibly create new basic block) to make edge non-fallthru.
1039 Return newly created BB or NULL if none. */
1040
1041 basic_block
force_nonfallthru(edge e)1042 force_nonfallthru (edge e)
1043 {
1044 basic_block ret, src = e->src;
1045
1046 if (!cfg_hooks->force_nonfallthru)
1047 internal_error ("%s does not support force_nonfallthru",
1048 cfg_hooks->name);
1049
1050 ret = cfg_hooks->force_nonfallthru (e);
1051 if (ret != NULL)
1052 {
1053 if (dom_info_available_p (CDI_DOMINATORS))
1054 set_immediate_dominator (CDI_DOMINATORS, ret, src);
1055
1056 if (current_loops != NULL)
1057 {
1058 basic_block pred = single_pred (ret);
1059 basic_block succ = single_succ (ret);
1060 class loop *loop
1061 = find_common_loop (pred->loop_father, succ->loop_father);
1062 rescan_loop_exit (e, false, true);
1063 add_bb_to_loop (ret, loop);
1064
1065 /* If we split the latch edge of loop adjust the latch block. */
1066 if (loop->latch == pred
1067 && loop->header == succ)
1068 loop->latch = ret;
1069 }
1070 }
1071
1072 return ret;
1073 }
1074
1075 /* Returns true if we can duplicate basic block BB. */
1076
1077 bool
can_duplicate_block_p(const_basic_block bb)1078 can_duplicate_block_p (const_basic_block bb)
1079 {
1080 if (!cfg_hooks->can_duplicate_block_p)
1081 internal_error ("%s does not support can_duplicate_block_p",
1082 cfg_hooks->name);
1083
1084 if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun) || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
1085 return false;
1086
1087 return cfg_hooks->can_duplicate_block_p (bb);
1088 }
1089
1090 /* Duplicates basic block BB and redirects edge E to it. Returns the
1091 new basic block. The new basic block is placed after the basic block
1092 AFTER. */
1093
1094 basic_block
duplicate_block(basic_block bb,edge e,basic_block after,copy_bb_data * id)1095 duplicate_block (basic_block bb, edge e, basic_block after, copy_bb_data *id)
1096 {
1097 edge s, n;
1098 basic_block new_bb;
1099 profile_count new_count = e ? e->count (): profile_count::uninitialized ();
1100 edge_iterator ei;
1101
1102 if (!cfg_hooks->duplicate_block)
1103 internal_error ("%s does not support duplicate_block",
1104 cfg_hooks->name);
1105
1106 if (bb->count < new_count)
1107 new_count = bb->count;
1108
1109 gcc_checking_assert (can_duplicate_block_p (bb));
1110
1111 new_bb = cfg_hooks->duplicate_block (bb, id);
1112 if (after)
1113 move_block_after (new_bb, after);
1114
1115 new_bb->flags = (bb->flags & ~BB_DUPLICATED);
1116 FOR_EACH_EDGE (s, ei, bb->succs)
1117 {
1118 /* Since we are creating edges from a new block to successors
1119 of another block (which therefore are known to be disjoint), there
1120 is no need to actually check for duplicated edges. */
1121 n = unchecked_make_edge (new_bb, s->dest, s->flags);
1122 n->probability = s->probability;
1123 n->aux = s->aux;
1124 }
1125
1126 if (e)
1127 {
1128 new_bb->count = new_count;
1129 bb->count -= new_count;
1130
1131 redirect_edge_and_branch_force (e, new_bb);
1132 }
1133 else
1134 new_bb->count = bb->count;
1135
1136 set_bb_original (new_bb, bb);
1137 set_bb_copy (bb, new_bb);
1138
1139 /* Add the new block to the copy of the loop of BB, or directly to the loop
1140 of BB if the loop is not being copied. */
1141 if (current_loops != NULL)
1142 {
1143 class loop *cloop = bb->loop_father;
1144 class loop *copy = get_loop_copy (cloop);
1145 /* If we copied the loop header block but not the loop
1146 we have created a loop with multiple entries. Ditch the loop,
1147 add the new block to the outer loop and arrange for a fixup. */
1148 if (!copy
1149 && cloop->header == bb)
1150 {
1151 add_bb_to_loop (new_bb, loop_outer (cloop));
1152 mark_loop_for_removal (cloop);
1153 }
1154 else
1155 {
1156 add_bb_to_loop (new_bb, copy ? copy : cloop);
1157 /* If we copied the loop latch block but not the loop, adjust
1158 loop state. */
1159 if (!copy
1160 && cloop->latch == bb)
1161 {
1162 cloop->latch = NULL;
1163 loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
1164 }
1165 }
1166 }
1167
1168 return new_bb;
1169 }
1170
1171 /* Return 1 if BB ends with a call, possibly followed by some
1172 instructions that must stay with the call, 0 otherwise. */
1173
1174 bool
block_ends_with_call_p(basic_block bb)1175 block_ends_with_call_p (basic_block bb)
1176 {
1177 if (!cfg_hooks->block_ends_with_call_p)
1178 internal_error ("%s does not support block_ends_with_call_p", cfg_hooks->name);
1179
1180 return (cfg_hooks->block_ends_with_call_p) (bb);
1181 }
1182
1183 /* Return 1 if BB ends with a conditional branch, 0 otherwise. */
1184
1185 bool
block_ends_with_condjump_p(const_basic_block bb)1186 block_ends_with_condjump_p (const_basic_block bb)
1187 {
1188 if (!cfg_hooks->block_ends_with_condjump_p)
1189 internal_error ("%s does not support block_ends_with_condjump_p",
1190 cfg_hooks->name);
1191
1192 return (cfg_hooks->block_ends_with_condjump_p) (bb);
1193 }
1194
1195 /* Add fake edges to the function exit for any non constant and non noreturn
1196 calls, volatile inline assembly in the bitmap of blocks specified by
1197 BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
1198 that were split.
1199
1200 The goal is to expose cases in which entering a basic block does not imply
1201 that all subsequent instructions must be executed. */
1202
1203 int
flow_call_edges_add(sbitmap blocks)1204 flow_call_edges_add (sbitmap blocks)
1205 {
1206 if (!cfg_hooks->flow_call_edges_add)
1207 internal_error ("%s does not support flow_call_edges_add",
1208 cfg_hooks->name);
1209
1210 return (cfg_hooks->flow_call_edges_add) (blocks);
1211 }
1212
1213 /* This function is called immediately after edge E is added to the
1214 edge vector E->dest->preds. */
1215
1216 void
execute_on_growing_pred(edge e)1217 execute_on_growing_pred (edge e)
1218 {
1219 if (! (e->dest->flags & BB_DUPLICATED)
1220 && cfg_hooks->execute_on_growing_pred)
1221 cfg_hooks->execute_on_growing_pred (e);
1222 }
1223
1224 /* This function is called immediately before edge E is removed from
1225 the edge vector E->dest->preds. */
1226
1227 void
execute_on_shrinking_pred(edge e)1228 execute_on_shrinking_pred (edge e)
1229 {
1230 if (! (e->dest->flags & BB_DUPLICATED)
1231 && cfg_hooks->execute_on_shrinking_pred)
1232 cfg_hooks->execute_on_shrinking_pred (e);
1233 }
1234
1235 /* This is used inside loop versioning when we want to insert
1236 stmts/insns on the edges, which have a different behavior
1237 in tree's and in RTL, so we made a CFG hook. */
1238 void
lv_flush_pending_stmts(edge e)1239 lv_flush_pending_stmts (edge e)
1240 {
1241 if (cfg_hooks->flush_pending_stmts)
1242 cfg_hooks->flush_pending_stmts (e);
1243 }
1244
1245 /* Loop versioning uses the duplicate_loop_body_to_header_edge to create
1246 a new version of the loop basic-blocks, the parameters here are
1247 exactly the same as in duplicate_loop_body_to_header_edge or
1248 tree_duplicate_loop_body_to_header_edge; while in tree-ssa there is
1249 additional work to maintain ssa information that's why there is
1250 a need to call the tree_duplicate_loop_body_to_header_edge rather
1251 than duplicate_loop_body_to_header_edge when we are in tree mode. */
1252 bool
cfg_hook_duplicate_loop_body_to_header_edge(class loop * loop,edge e,unsigned int ndupl,sbitmap wont_exit,edge orig,vec<edge> * to_remove,int flags)1253 cfg_hook_duplicate_loop_body_to_header_edge (class loop *loop, edge e,
1254 unsigned int ndupl,
1255 sbitmap wont_exit, edge orig,
1256 vec<edge> *to_remove, int flags)
1257 {
1258 gcc_assert (cfg_hooks->cfg_hook_duplicate_loop_body_to_header_edge);
1259 return cfg_hooks->cfg_hook_duplicate_loop_body_to_header_edge (
1260 loop, e, ndupl, wont_exit, orig, to_remove, flags);
1261 }
1262
1263 /* Conditional jumps are represented differently in trees and RTL,
1264 this hook takes a basic block that is known to have a cond jump
1265 at its end and extracts the taken and not taken edges out of it
1266 and store it in E1 and E2 respectively. */
1267 void
extract_cond_bb_edges(basic_block b,edge * e1,edge * e2)1268 extract_cond_bb_edges (basic_block b, edge *e1, edge *e2)
1269 {
1270 gcc_assert (cfg_hooks->extract_cond_bb_edges);
1271 cfg_hooks->extract_cond_bb_edges (b, e1, e2);
1272 }
1273
1274 /* Responsible for updating the ssa info (PHI nodes) on the
1275 new condition basic block that guards the versioned loop. */
1276 void
lv_adjust_loop_header_phi(basic_block first,basic_block second,basic_block new_block,edge e)1277 lv_adjust_loop_header_phi (basic_block first, basic_block second,
1278 basic_block new_block, edge e)
1279 {
1280 if (cfg_hooks->lv_adjust_loop_header_phi)
1281 cfg_hooks->lv_adjust_loop_header_phi (first, second, new_block, e);
1282 }
1283
1284 /* Conditions in trees and RTL are different so we need
1285 a different handling when we add the condition to the
1286 versioning code. */
1287 void
lv_add_condition_to_bb(basic_block first,basic_block second,basic_block new_block,void * cond)1288 lv_add_condition_to_bb (basic_block first, basic_block second,
1289 basic_block new_block, void *cond)
1290 {
1291 gcc_assert (cfg_hooks->lv_add_condition_to_bb);
1292 cfg_hooks->lv_add_condition_to_bb (first, second, new_block, cond);
1293 }
1294
1295 /* Checks whether all N blocks in BBS array can be copied. */
1296 bool
can_copy_bbs_p(basic_block * bbs,unsigned n)1297 can_copy_bbs_p (basic_block *bbs, unsigned n)
1298 {
1299 unsigned i;
1300 edge e;
1301 int ret = true;
1302
1303 for (i = 0; i < n; i++)
1304 bbs[i]->flags |= BB_DUPLICATED;
1305
1306 for (i = 0; i < n; i++)
1307 {
1308 /* In case we should redirect abnormal edge during duplication, fail. */
1309 edge_iterator ei;
1310 FOR_EACH_EDGE (e, ei, bbs[i]->succs)
1311 if ((e->flags & EDGE_ABNORMAL)
1312 && (e->dest->flags & BB_DUPLICATED))
1313 {
1314 ret = false;
1315 goto end;
1316 }
1317
1318 if (!can_duplicate_block_p (bbs[i]))
1319 {
1320 ret = false;
1321 break;
1322 }
1323 }
1324
1325 end:
1326 for (i = 0; i < n; i++)
1327 bbs[i]->flags &= ~BB_DUPLICATED;
1328
1329 return ret;
1330 }
1331
1332 /* Duplicates N basic blocks stored in array BBS. Newly created basic blocks
1333 are placed into array NEW_BBS in the same order. Edges from basic blocks
1334 in BBS are also duplicated and copies of those that lead into BBS are
1335 redirected to appropriate newly created block. The function assigns bbs
1336 into loops (copy of basic block bb is assigned to bb->loop_father->copy
1337 loop, so this must be set up correctly in advance)
1338
1339 If UPDATE_DOMINANCE is true then this function updates dominators locally
1340 (LOOPS structure that contains the information about dominators is passed
1341 to enable this), otherwise it does not update the dominator information
1342 and it assumed that the caller will do this, perhaps by destroying and
1343 recreating it instead of trying to do an incremental update like this
1344 function does when update_dominance is true.
1345
1346 BASE is the superloop to that basic block belongs; if its header or latch
1347 is copied, we do not set the new blocks as header or latch.
1348
1349 Created copies of N_EDGES edges in array EDGES are stored in array NEW_EDGES,
1350 also in the same order.
1351
1352 Newly created basic blocks are put after the basic block AFTER in the
1353 instruction stream, and the order of the blocks in BBS array is preserved. */
1354
1355 void
copy_bbs(basic_block * bbs,unsigned n,basic_block * new_bbs,edge * edges,unsigned num_edges,edge * new_edges,class loop * base,basic_block after,bool update_dominance)1356 copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
1357 edge *edges, unsigned num_edges, edge *new_edges,
1358 class loop *base, basic_block after, bool update_dominance)
1359 {
1360 unsigned i, j;
1361 basic_block bb, new_bb, dom_bb;
1362 edge e;
1363 copy_bb_data id;
1364
1365 /* Mark the blocks to be copied. This is used by edge creation hooks
1366 to decide whether to reallocate PHI nodes capacity to avoid reallocating
1367 PHIs in the set of source BBs. */
1368 for (i = 0; i < n; i++)
1369 bbs[i]->flags |= BB_DUPLICATED;
1370
1371 /* Duplicate bbs, update dominators, assign bbs to loops. */
1372 for (i = 0; i < n; i++)
1373 {
1374 /* Duplicate. */
1375 bb = bbs[i];
1376 new_bb = new_bbs[i] = duplicate_block (bb, NULL, after, &id);
1377 after = new_bb;
1378 if (bb->loop_father)
1379 {
1380 /* Possibly set loop header. */
1381 if (bb->loop_father->header == bb && bb->loop_father != base)
1382 new_bb->loop_father->header = new_bb;
1383 /* Or latch. */
1384 if (bb->loop_father->latch == bb && bb->loop_father != base)
1385 new_bb->loop_father->latch = new_bb;
1386 }
1387 }
1388
1389 /* Set dominators. */
1390 if (update_dominance)
1391 {
1392 for (i = 0; i < n; i++)
1393 {
1394 bb = bbs[i];
1395 new_bb = new_bbs[i];
1396
1397 dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb);
1398 if (dom_bb->flags & BB_DUPLICATED)
1399 {
1400 dom_bb = get_bb_copy (dom_bb);
1401 set_immediate_dominator (CDI_DOMINATORS, new_bb, dom_bb);
1402 }
1403 }
1404 }
1405
1406 /* Redirect edges. */
1407 for (i = 0; i < n; i++)
1408 {
1409 edge_iterator ei;
1410 new_bb = new_bbs[i];
1411 bb = bbs[i];
1412
1413 FOR_EACH_EDGE (e, ei, new_bb->succs)
1414 {
1415 if (!(e->dest->flags & BB_DUPLICATED))
1416 continue;
1417 redirect_edge_and_branch_force (e, get_bb_copy (e->dest));
1418 }
1419 }
1420 for (j = 0; j < num_edges; j++)
1421 {
1422 if (!edges[j])
1423 new_edges[j] = NULL;
1424 else
1425 {
1426 basic_block src = edges[j]->src;
1427 basic_block dest = edges[j]->dest;
1428 if (src->flags & BB_DUPLICATED)
1429 src = get_bb_copy (src);
1430 if (dest->flags & BB_DUPLICATED)
1431 dest = get_bb_copy (dest);
1432 new_edges[j] = find_edge (src, dest);
1433 }
1434 }
1435
1436 /* Clear information about duplicates. */
1437 for (i = 0; i < n; i++)
1438 bbs[i]->flags &= ~BB_DUPLICATED;
1439 }
1440
1441 /* Return true if BB contains only labels or non-executable
1442 instructions */
1443 bool
empty_block_p(basic_block bb)1444 empty_block_p (basic_block bb)
1445 {
1446 gcc_assert (cfg_hooks->empty_block_p);
1447 return cfg_hooks->empty_block_p (bb);
1448 }
1449
1450 /* Split a basic block if it ends with a conditional branch and if
1451 the other part of the block is not empty. */
1452 basic_block
split_block_before_cond_jump(basic_block bb)1453 split_block_before_cond_jump (basic_block bb)
1454 {
1455 gcc_assert (cfg_hooks->split_block_before_cond_jump);
1456 return cfg_hooks->split_block_before_cond_jump (bb);
1457 }
1458
1459 /* Work-horse for passes.cc:check_profile_consistency.
1460 Do book-keeping of the CFG for the profile consistency checker.
1461 Store the counting in RECORD. */
1462
1463 void
profile_record_check_consistency(profile_record * record)1464 profile_record_check_consistency (profile_record *record)
1465 {
1466 basic_block bb;
1467 edge_iterator ei;
1468 edge e;
1469
1470 FOR_ALL_BB_FN (bb, cfun)
1471 {
1472 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
1473 && profile_status_for_fn (cfun) != PROFILE_ABSENT
1474 && EDGE_COUNT (bb->succs))
1475 {
1476 sreal sum = 0;
1477 bool found = false;
1478 FOR_EACH_EDGE (e, ei, bb->succs)
1479 {
1480 if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
1481 found = true;
1482 if (e->probability.initialized_p ())
1483 sum += e->probability.to_sreal ();
1484 }
1485 double dsum = sum.to_double ();
1486 if (found && (dsum < 0.9 || dsum > 1.1)
1487 && !(bb->count == profile_count::zero ()))
1488 {
1489 record->num_mismatched_prob_out++;
1490 dsum = dsum > 1 ? dsum - 1 : 1 - dsum;
1491 if (profile_info)
1492 {
1493 if (ENTRY_BLOCK_PTR_FOR_FN
1494 (cfun)->count.ipa ().initialized_p ()
1495 && ENTRY_BLOCK_PTR_FOR_FN
1496 (cfun)->count.ipa ().nonzero_p ()
1497 && bb->count.ipa ().initialized_p ())
1498 record->dyn_mismatched_prob_out
1499 += dsum * bb->count.ipa ().to_gcov_type ();
1500 }
1501 else if (bb->count.initialized_p ())
1502 record->dyn_mismatched_prob_out
1503 += dsum * bb->count.to_sreal_scale
1504 (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count).to_double ();
1505 }
1506 }
1507 if (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun)
1508 && profile_status_for_fn (cfun) != PROFILE_ABSENT)
1509 {
1510 profile_count lsum = profile_count::zero ();
1511 FOR_EACH_EDGE (e, ei, bb->preds)
1512 lsum += e->count ();
1513 if (lsum.differs_from_p (bb->count))
1514 {
1515 record->num_mismatched_count_in++;
1516 profile_count max;
1517 if (lsum < bb->count)
1518 max = bb->count;
1519 else
1520 max = lsum;
1521 if (profile_info)
1522 {
1523 if (ENTRY_BLOCK_PTR_FOR_FN
1524 (cfun)->count.ipa ().initialized_p ()
1525 && ENTRY_BLOCK_PTR_FOR_FN
1526 (cfun)->count.ipa ().nonzero_p ()
1527 && max.ipa ().initialized_p ())
1528 record->dyn_mismatched_count_in
1529 += max.ipa ().to_gcov_type ();
1530 }
1531 else if (bb->count.initialized_p ())
1532 record->dyn_mismatched_prob_out
1533 += max.to_sreal_scale
1534 (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count).to_double ();
1535 }
1536 }
1537 if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
1538 || bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
1539 continue;
1540 }
1541 }
1542
1543 /* Work-horse for passes.cc:acount_profile.
1544 Do book-keeping of the CFG for the profile accounting.
1545 Store the counting in RECORD. */
1546
1547 void
profile_record_account_profile(profile_record * record)1548 profile_record_account_profile (profile_record *record)
1549 {
1550 basic_block bb;
1551
1552 FOR_ALL_BB_FN (bb, cfun)
1553 {
1554 gcc_assert (cfg_hooks->account_profile_record);
1555 cfg_hooks->account_profile_record (bb, record);
1556 }
1557 }
1558
1559 #if __GNUC__ >= 10
1560 # pragma GCC diagnostic pop
1561 #endif
1562