]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/cfghooks.cc
tree-optimization/107833 - invariant motion of uninit uses
[thirdparty/gcc.git] / gcc / cfghooks.cc
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
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
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
64 gimple_register_cfg_hooks (void)
65 {
66 cfg_hooks = &gimple_cfg_hooks;
67 }
68
69 struct cfg_hooks
70 get_cfg_hooks (void)
71 {
72 return *cfg_hooks;
73 }
74
75 void
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
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
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
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
309 debug (basic_block_def &ref)
310 {
311 dump_bb (stderr, &ref, 0, TDF_NONE);
312 }
313
314 DEBUG_FUNCTION void
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
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 *)
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
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
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
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
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
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
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
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
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
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
546 if (dom_info_available_p (CDI_DOMINATORS))
547 {
548 redirect_immediate_dominators (CDI_DOMINATORS, bb, new_bb);
549 set_immediate_dominator (CDI_DOMINATORS, new_bb, bb);
550 }
551
552 if (current_loops != NULL)
553 {
554 edge_iterator ei;
555 edge e;
556 add_bb_to_loop (new_bb, bb->loop_father);
557 /* Identify all loops bb may have been the latch of and adjust them. */
558 FOR_EACH_EDGE (e, ei, new_bb->succs)
559 if (e->dest->loop_father->latch == bb)
560 e->dest->loop_father->latch = new_bb;
561 }
562
563 res = make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU);
564
565 if (bb->flags & BB_IRREDUCIBLE_LOOP)
566 {
567 new_bb->flags |= BB_IRREDUCIBLE_LOOP;
568 res->flags |= EDGE_IRREDUCIBLE_LOOP;
569 }
570
571 return res;
572 }
573
574 edge
575 split_block (basic_block bb, gimple *i)
576 {
577 return split_block_1 (bb, i);
578 }
579
580 edge
581 split_block (basic_block bb, rtx i)
582 {
583 return split_block_1 (bb, i);
584 }
585
586 /* Splits block BB just after labels. The newly created edge is returned. */
587
588 edge
589 split_block_after_labels (basic_block bb)
590 {
591 return split_block_1 (bb, NULL);
592 }
593
594 /* Moves block BB immediately after block AFTER. Returns false if the
595 movement was impossible. */
596
597 bool
598 move_block_after (basic_block bb, basic_block after)
599 {
600 bool ret;
601
602 if (!cfg_hooks->move_block_after)
603 internal_error ("%s does not support move_block_after", cfg_hooks->name);
604
605 ret = cfg_hooks->move_block_after (bb, after);
606
607 return ret;
608 }
609
610 /* Deletes the basic block BB. */
611
612 void
613 delete_basic_block (basic_block bb)
614 {
615 if (!cfg_hooks->delete_basic_block)
616 internal_error ("%s does not support delete_basic_block", cfg_hooks->name);
617
618 cfg_hooks->delete_basic_block (bb);
619
620 if (current_loops != NULL)
621 {
622 class loop *loop = bb->loop_father;
623
624 /* If we remove the header or the latch of a loop, mark the loop for
625 removal. */
626 if (loop->latch == bb
627 || loop->header == bb)
628 mark_loop_for_removal (loop);
629
630 remove_bb_from_loops (bb);
631 }
632
633 /* Remove the edges into and out of this block. Note that there may
634 indeed be edges in, if we are removing an unreachable loop. */
635 while (EDGE_COUNT (bb->preds) != 0)
636 remove_edge (EDGE_PRED (bb, 0));
637 while (EDGE_COUNT (bb->succs) != 0)
638 remove_edge (EDGE_SUCC (bb, 0));
639
640 if (dom_info_available_p (CDI_DOMINATORS))
641 delete_from_dominance_info (CDI_DOMINATORS, bb);
642 if (dom_info_available_p (CDI_POST_DOMINATORS))
643 delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
644
645 /* Remove the basic block from the array. */
646 expunge_block (bb);
647 }
648
649 /* Splits edge E and returns the newly created basic block. */
650
651 basic_block
652 split_edge (edge e)
653 {
654 basic_block ret;
655 profile_count count = e->count ();
656 edge f;
657 bool irr = (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
658 bool back = (e->flags & EDGE_DFS_BACK) != 0;
659 class loop *loop;
660 basic_block src = e->src, dest = e->dest;
661
662 if (!cfg_hooks->split_edge)
663 internal_error ("%s does not support split_edge", cfg_hooks->name);
664
665 if (current_loops != NULL)
666 rescan_loop_exit (e, false, true);
667
668 ret = cfg_hooks->split_edge (e);
669 ret->count = count;
670 single_succ_edge (ret)->probability = profile_probability::always ();
671
672 if (irr)
673 {
674 ret->flags |= BB_IRREDUCIBLE_LOOP;
675 single_pred_edge (ret)->flags |= EDGE_IRREDUCIBLE_LOOP;
676 single_succ_edge (ret)->flags |= EDGE_IRREDUCIBLE_LOOP;
677 }
678 if (back)
679 {
680 single_pred_edge (ret)->flags &= ~EDGE_DFS_BACK;
681 single_succ_edge (ret)->flags |= EDGE_DFS_BACK;
682 }
683
684 if (dom_info_available_p (CDI_DOMINATORS))
685 set_immediate_dominator (CDI_DOMINATORS, ret, single_pred (ret));
686
687 if (dom_info_state (CDI_DOMINATORS) >= DOM_NO_FAST_QUERY)
688 {
689 /* There are two cases:
690
691 If the immediate dominator of e->dest is not e->src, it
692 remains unchanged.
693
694 If immediate dominator of e->dest is e->src, it may become
695 ret, provided that all other predecessors of e->dest are
696 dominated by e->dest. */
697
698 if (get_immediate_dominator (CDI_DOMINATORS, single_succ (ret))
699 == single_pred (ret))
700 {
701 edge_iterator ei;
702 FOR_EACH_EDGE (f, ei, single_succ (ret)->preds)
703 {
704 if (f == single_succ_edge (ret))
705 continue;
706
707 if (!dominated_by_p (CDI_DOMINATORS, f->src,
708 single_succ (ret)))
709 break;
710 }
711
712 if (!f)
713 set_immediate_dominator (CDI_DOMINATORS, single_succ (ret), ret);
714 }
715 }
716
717 if (current_loops != NULL)
718 {
719 loop = find_common_loop (src->loop_father, dest->loop_father);
720 add_bb_to_loop (ret, loop);
721
722 /* If we split the latch edge of loop adjust the latch block. */
723 if (loop->latch == src
724 && loop->header == dest)
725 loop->latch = ret;
726 }
727
728 return ret;
729 }
730
731 /* Creates a new basic block just after the basic block AFTER.
732 HEAD and END are the first and the last statement belonging
733 to the block. If both are NULL, an empty block is created. */
734
735 static basic_block
736 create_basic_block_1 (void *head, void *end, basic_block after)
737 {
738 basic_block ret;
739
740 if (!cfg_hooks->create_basic_block)
741 internal_error ("%s does not support create_basic_block", cfg_hooks->name);
742
743 ret = cfg_hooks->create_basic_block (head, end, after);
744
745 if (dom_info_available_p (CDI_DOMINATORS))
746 add_to_dominance_info (CDI_DOMINATORS, ret);
747 if (dom_info_available_p (CDI_POST_DOMINATORS))
748 add_to_dominance_info (CDI_POST_DOMINATORS, ret);
749
750 return ret;
751 }
752
753 basic_block
754 create_basic_block (gimple_seq seq, basic_block after)
755 {
756 return create_basic_block_1 (seq, NULL, after);
757 }
758
759 basic_block
760 create_basic_block (rtx head, rtx end, basic_block after)
761 {
762 return create_basic_block_1 (head, end, after);
763 }
764
765
766 /* Creates an empty basic block just after basic block AFTER. */
767
768 basic_block
769 create_empty_bb (basic_block after)
770 {
771 return create_basic_block_1 (NULL, NULL, after);
772 }
773
774 /* Checks whether we may merge blocks BB1 and BB2. */
775
776 bool
777 can_merge_blocks_p (basic_block bb1, basic_block bb2)
778 {
779 bool ret;
780
781 if (!cfg_hooks->can_merge_blocks_p)
782 internal_error ("%s does not support can_merge_blocks_p", cfg_hooks->name);
783
784 ret = cfg_hooks->can_merge_blocks_p (bb1, bb2);
785
786 return ret;
787 }
788
789 void
790 predict_edge (edge e, enum br_predictor predictor, int probability)
791 {
792 if (!cfg_hooks->predict_edge)
793 internal_error ("%s does not support predict_edge", cfg_hooks->name);
794
795 cfg_hooks->predict_edge (e, predictor, probability);
796 }
797
798 bool
799 predicted_by_p (const_basic_block bb, enum br_predictor predictor)
800 {
801 if (!cfg_hooks->predict_edge)
802 internal_error ("%s does not support predicted_by_p", cfg_hooks->name);
803
804 return cfg_hooks->predicted_by_p (bb, predictor);
805 }
806
807 /* Merges basic block B into basic block A. */
808
809 void
810 merge_blocks (basic_block a, basic_block b)
811 {
812 edge e;
813 edge_iterator ei;
814
815 if (!cfg_hooks->merge_blocks)
816 internal_error ("%s does not support merge_blocks", cfg_hooks->name);
817
818 cfg_hooks->merge_blocks (a, b);
819
820 if (current_loops != NULL)
821 {
822 /* If the block we merge into is a loop header do nothing unless ... */
823 if (a->loop_father->header == a)
824 {
825 /* ... we merge two loop headers, in which case we kill
826 the inner loop. */
827 if (b->loop_father->header == b)
828 mark_loop_for_removal (b->loop_father);
829 }
830 /* If we merge a loop header into its predecessor, update the loop
831 structure. */
832 else if (b->loop_father->header == b)
833 {
834 remove_bb_from_loops (a);
835 add_bb_to_loop (a, b->loop_father);
836 a->loop_father->header = a;
837 }
838 /* If we merge a loop latch into its predecessor, update the loop
839 structure. */
840 if (b->loop_father->latch
841 && b->loop_father->latch == b)
842 b->loop_father->latch = a;
843 remove_bb_from_loops (b);
844 }
845
846 /* Normally there should only be one successor of A and that is B, but
847 partway though the merge of blocks for conditional_execution we'll
848 be merging a TEST block with THEN and ELSE successors. Free the
849 whole lot of them and hope the caller knows what they're doing. */
850
851 while (EDGE_COUNT (a->succs) != 0)
852 remove_edge (EDGE_SUCC (a, 0));
853
854 /* Adjust the edges out of B for the new owner. */
855 FOR_EACH_EDGE (e, ei, b->succs)
856 {
857 e->src = a;
858 if (current_loops != NULL)
859 {
860 /* If b was a latch, a now is. */
861 if (e->dest->loop_father->latch == b)
862 e->dest->loop_father->latch = a;
863 rescan_loop_exit (e, true, false);
864 }
865 }
866 a->succs = b->succs;
867 a->flags |= b->flags;
868
869 /* B hasn't quite yet ceased to exist. Attempt to prevent mishap. */
870 b->preds = b->succs = NULL;
871
872 if (dom_info_available_p (CDI_DOMINATORS))
873 redirect_immediate_dominators (CDI_DOMINATORS, b, a);
874
875 if (dom_info_available_p (CDI_DOMINATORS))
876 delete_from_dominance_info (CDI_DOMINATORS, b);
877 if (dom_info_available_p (CDI_POST_DOMINATORS))
878 delete_from_dominance_info (CDI_POST_DOMINATORS, b);
879
880 expunge_block (b);
881 }
882
883 /* Split BB into entry part and the rest (the rest is the newly created block).
884 Redirect those edges for that REDIRECT_EDGE_P returns true to the entry
885 part. Returns the edge connecting the entry part to the rest. */
886
887 edge
888 make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
889 void (*new_bb_cbk) (basic_block))
890 {
891 edge e, fallthru;
892 edge_iterator ei;
893 basic_block dummy, jump;
894 class loop *loop, *ploop, *cloop;
895
896 if (!cfg_hooks->make_forwarder_block)
897 internal_error ("%s does not support make_forwarder_block",
898 cfg_hooks->name);
899
900 fallthru = split_block_after_labels (bb);
901 dummy = fallthru->src;
902 dummy->count = profile_count::zero ();
903 bb = fallthru->dest;
904
905 /* Redirect back edges we want to keep. */
906 for (ei = ei_start (dummy->preds); (e = ei_safe_edge (ei)); )
907 {
908 basic_block e_src;
909
910 if (redirect_edge_p (e))
911 {
912 dummy->count += e->count ();
913 ei_next (&ei);
914 continue;
915 }
916
917 e_src = e->src;
918 jump = redirect_edge_and_branch_force (e, bb);
919 if (jump != NULL)
920 {
921 /* If we redirected the loop latch edge, the JUMP block now acts like
922 the new latch of the loop. */
923 if (current_loops != NULL
924 && dummy->loop_father != NULL
925 && dummy->loop_father->header == dummy
926 && dummy->loop_father->latch == e_src)
927 dummy->loop_father->latch = jump;
928
929 if (new_bb_cbk != NULL)
930 new_bb_cbk (jump);
931 }
932 }
933
934 if (dom_info_available_p (CDI_DOMINATORS))
935 {
936 vec<basic_block> doms_to_fix;
937 doms_to_fix.create (2);
938 doms_to_fix.quick_push (dummy);
939 doms_to_fix.quick_push (bb);
940 iterate_fix_dominators (CDI_DOMINATORS, doms_to_fix, false);
941 doms_to_fix.release ();
942 }
943
944 if (current_loops != NULL)
945 {
946 /* If we do not split a loop header, then both blocks belong to the
947 same loop. In case we split loop header and do not redirect the
948 latch edge to DUMMY, then DUMMY belongs to the outer loop, and
949 BB becomes the new header. If latch is not recorded for the loop,
950 we leave this updating on the caller (this may only happen during
951 loop analysis). */
952 loop = dummy->loop_father;
953 if (loop->header == dummy
954 && loop->latch != NULL
955 && find_edge (loop->latch, dummy) == NULL)
956 {
957 remove_bb_from_loops (dummy);
958 loop->header = bb;
959
960 cloop = loop;
961 FOR_EACH_EDGE (e, ei, dummy->preds)
962 {
963 cloop = find_common_loop (cloop, e->src->loop_father);
964 }
965 add_bb_to_loop (dummy, cloop);
966 }
967
968 /* In case we split loop latch, update it. */
969 for (ploop = loop; ploop; ploop = loop_outer (ploop))
970 if (ploop->latch == dummy)
971 ploop->latch = bb;
972 }
973
974 cfg_hooks->make_forwarder_block (fallthru);
975
976 return fallthru;
977 }
978
979 /* Try to make the edge fallthru. */
980
981 void
982 tidy_fallthru_edge (edge e)
983 {
984 if (cfg_hooks->tidy_fallthru_edge)
985 cfg_hooks->tidy_fallthru_edge (e);
986 }
987
988 /* Fix up edges that now fall through, or rather should now fall through
989 but previously required a jump around now deleted blocks. Simplify
990 the search by only examining blocks numerically adjacent, since this
991 is how they were created.
992
993 ??? This routine is currently RTL specific. */
994
995 void
996 tidy_fallthru_edges (void)
997 {
998 basic_block b, c;
999
1000 if (!cfg_hooks->tidy_fallthru_edge)
1001 return;
1002
1003 if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
1004 return;
1005
1006 FOR_BB_BETWEEN (b, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb,
1007 EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb, next_bb)
1008 {
1009 edge s;
1010
1011 c = b->next_bb;
1012
1013 /* We care about simple conditional or unconditional jumps with
1014 a single successor.
1015
1016 If we had a conditional branch to the next instruction when
1017 CFG was built, then there will only be one out edge for the
1018 block which ended with the conditional branch (since we do
1019 not create duplicate edges).
1020
1021 Furthermore, the edge will be marked as a fallthru because we
1022 merge the flags for the duplicate edges. So we do not want to
1023 check that the edge is not a FALLTHRU edge. */
1024
1025 if (single_succ_p (b))
1026 {
1027 s = single_succ_edge (b);
1028 if (! (s->flags & EDGE_COMPLEX)
1029 && s->dest == c
1030 && !(JUMP_P (BB_END (b)) && CROSSING_JUMP_P (BB_END (b))))
1031 tidy_fallthru_edge (s);
1032 }
1033 }
1034 }
1035
1036 /* Edge E is assumed to be fallthru edge. Emit needed jump instruction
1037 (and possibly create new basic block) to make edge non-fallthru.
1038 Return newly created BB or NULL if none. */
1039
1040 basic_block
1041 force_nonfallthru (edge e)
1042 {
1043 basic_block ret, src = e->src;
1044
1045 if (!cfg_hooks->force_nonfallthru)
1046 internal_error ("%s does not support force_nonfallthru",
1047 cfg_hooks->name);
1048
1049 ret = cfg_hooks->force_nonfallthru (e);
1050 if (ret != NULL)
1051 {
1052 if (dom_info_available_p (CDI_DOMINATORS))
1053 set_immediate_dominator (CDI_DOMINATORS, ret, src);
1054
1055 if (current_loops != NULL)
1056 {
1057 basic_block pred = single_pred (ret);
1058 basic_block succ = single_succ (ret);
1059 class loop *loop
1060 = find_common_loop (pred->loop_father, succ->loop_father);
1061 rescan_loop_exit (e, false, true);
1062 add_bb_to_loop (ret, loop);
1063
1064 /* If we split the latch edge of loop adjust the latch block. */
1065 if (loop->latch == pred
1066 && loop->header == succ)
1067 loop->latch = ret;
1068 }
1069 }
1070
1071 return ret;
1072 }
1073
1074 /* Returns true if we can duplicate basic block BB. */
1075
1076 bool
1077 can_duplicate_block_p (const_basic_block bb)
1078 {
1079 if (!cfg_hooks->can_duplicate_block_p)
1080 internal_error ("%s does not support can_duplicate_block_p",
1081 cfg_hooks->name);
1082
1083 if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun) || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
1084 return false;
1085
1086 return cfg_hooks->can_duplicate_block_p (bb);
1087 }
1088
1089 /* Duplicate basic block BB, place it after AFTER (if non-null) and redirect
1090 edge E to it (if non-null). Return the new basic block.
1091
1092 If BB contains a returns_twice call, the caller is responsible for recreating
1093 incoming abnormal edges corresponding to the "second return" for the copy.
1094 gimple_can_duplicate_bb_p rejects such blocks, while RTL likes to live
1095 dangerously.
1096
1097 If BB has incoming abnormal edges for some other reason, their destinations
1098 should be tied to label(s) of the original BB and not the copy. */
1099
1100 basic_block
1101 duplicate_block (basic_block bb, edge e, basic_block after, copy_bb_data *id)
1102 {
1103 edge s, n;
1104 basic_block new_bb;
1105 profile_count new_count = e ? e->count (): profile_count::uninitialized ();
1106 edge_iterator ei;
1107
1108 if (!cfg_hooks->duplicate_block)
1109 internal_error ("%s does not support duplicate_block",
1110 cfg_hooks->name);
1111
1112 if (bb->count < new_count)
1113 new_count = bb->count;
1114
1115 gcc_checking_assert (can_duplicate_block_p (bb));
1116
1117 new_bb = cfg_hooks->duplicate_block (bb, id);
1118 if (after)
1119 move_block_after (new_bb, after);
1120
1121 new_bb->flags = (bb->flags & ~BB_DUPLICATED);
1122 FOR_EACH_EDGE (s, ei, bb->succs)
1123 {
1124 /* Since we are creating edges from a new block to successors
1125 of another block (which therefore are known to be disjoint), there
1126 is no need to actually check for duplicated edges. */
1127 n = unchecked_make_edge (new_bb, s->dest, s->flags);
1128 n->probability = s->probability;
1129 n->aux = s->aux;
1130 }
1131
1132 if (e)
1133 {
1134 new_bb->count = new_count;
1135 bb->count -= new_count;
1136
1137 redirect_edge_and_branch_force (e, new_bb);
1138 }
1139 else
1140 new_bb->count = bb->count;
1141
1142 set_bb_original (new_bb, bb);
1143 set_bb_copy (bb, new_bb);
1144
1145 /* Add the new block to the copy of the loop of BB, or directly to the loop
1146 of BB if the loop is not being copied. */
1147 if (current_loops != NULL)
1148 {
1149 class loop *cloop = bb->loop_father;
1150 class loop *copy = get_loop_copy (cloop);
1151 /* If we copied the loop header block but not the loop
1152 we have created a loop with multiple entries. Ditch the loop,
1153 add the new block to the outer loop and arrange for a fixup. */
1154 if (!copy
1155 && cloop->header == bb)
1156 {
1157 add_bb_to_loop (new_bb, loop_outer (cloop));
1158 mark_loop_for_removal (cloop);
1159 }
1160 else
1161 {
1162 add_bb_to_loop (new_bb, copy ? copy : cloop);
1163 /* If we copied the loop latch block but not the loop, adjust
1164 loop state. */
1165 if (!copy
1166 && cloop->latch == bb)
1167 {
1168 cloop->latch = NULL;
1169 loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
1170 }
1171 }
1172 }
1173
1174 return new_bb;
1175 }
1176
1177 /* Return 1 if BB ends with a call, possibly followed by some
1178 instructions that must stay with the call, 0 otherwise. */
1179
1180 bool
1181 block_ends_with_call_p (basic_block bb)
1182 {
1183 if (!cfg_hooks->block_ends_with_call_p)
1184 internal_error ("%s does not support block_ends_with_call_p", cfg_hooks->name);
1185
1186 return (cfg_hooks->block_ends_with_call_p) (bb);
1187 }
1188
1189 /* Return 1 if BB ends with a conditional branch, 0 otherwise. */
1190
1191 bool
1192 block_ends_with_condjump_p (const_basic_block bb)
1193 {
1194 if (!cfg_hooks->block_ends_with_condjump_p)
1195 internal_error ("%s does not support block_ends_with_condjump_p",
1196 cfg_hooks->name);
1197
1198 return (cfg_hooks->block_ends_with_condjump_p) (bb);
1199 }
1200
1201 /* Add fake edges to the function exit for any non constant and non noreturn
1202 calls, volatile inline assembly in the bitmap of blocks specified by
1203 BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
1204 that were split.
1205
1206 The goal is to expose cases in which entering a basic block does not imply
1207 that all subsequent instructions must be executed. */
1208
1209 int
1210 flow_call_edges_add (sbitmap blocks)
1211 {
1212 if (!cfg_hooks->flow_call_edges_add)
1213 internal_error ("%s does not support flow_call_edges_add",
1214 cfg_hooks->name);
1215
1216 return (cfg_hooks->flow_call_edges_add) (blocks);
1217 }
1218
1219 /* This function is called immediately after edge E is added to the
1220 edge vector E->dest->preds. */
1221
1222 void
1223 execute_on_growing_pred (edge e)
1224 {
1225 if (! (e->dest->flags & BB_DUPLICATED)
1226 && cfg_hooks->execute_on_growing_pred)
1227 cfg_hooks->execute_on_growing_pred (e);
1228 }
1229
1230 /* This function is called immediately before edge E is removed from
1231 the edge vector E->dest->preds. */
1232
1233 void
1234 execute_on_shrinking_pred (edge e)
1235 {
1236 if (! (e->dest->flags & BB_DUPLICATED)
1237 && cfg_hooks->execute_on_shrinking_pred)
1238 cfg_hooks->execute_on_shrinking_pred (e);
1239 }
1240
1241 /* This is used inside loop versioning when we want to insert
1242 stmts/insns on the edges, which have a different behavior
1243 in tree's and in RTL, so we made a CFG hook. */
1244 void
1245 lv_flush_pending_stmts (edge e)
1246 {
1247 if (cfg_hooks->flush_pending_stmts)
1248 cfg_hooks->flush_pending_stmts (e);
1249 }
1250
1251 /* Loop versioning uses the duplicate_loop_body_to_header_edge to create
1252 a new version of the loop basic-blocks, the parameters here are
1253 exactly the same as in duplicate_loop_body_to_header_edge or
1254 tree_duplicate_loop_body_to_header_edge; while in tree-ssa there is
1255 additional work to maintain ssa information that's why there is
1256 a need to call the tree_duplicate_loop_body_to_header_edge rather
1257 than duplicate_loop_body_to_header_edge when we are in tree mode. */
1258 bool
1259 cfg_hook_duplicate_loop_body_to_header_edge (class loop *loop, edge e,
1260 unsigned int ndupl,
1261 sbitmap wont_exit, edge orig,
1262 vec<edge> *to_remove, int flags)
1263 {
1264 gcc_assert (cfg_hooks->cfg_hook_duplicate_loop_body_to_header_edge);
1265 return cfg_hooks->cfg_hook_duplicate_loop_body_to_header_edge (
1266 loop, e, ndupl, wont_exit, orig, to_remove, flags);
1267 }
1268
1269 /* Conditional jumps are represented differently in trees and RTL,
1270 this hook takes a basic block that is known to have a cond jump
1271 at its end and extracts the taken and not taken edges out of it
1272 and store it in E1 and E2 respectively. */
1273 void
1274 extract_cond_bb_edges (basic_block b, edge *e1, edge *e2)
1275 {
1276 gcc_assert (cfg_hooks->extract_cond_bb_edges);
1277 cfg_hooks->extract_cond_bb_edges (b, e1, e2);
1278 }
1279
1280 /* Responsible for updating the ssa info (PHI nodes) on the
1281 new condition basic block that guards the versioned loop. */
1282 void
1283 lv_adjust_loop_header_phi (basic_block first, basic_block second,
1284 basic_block new_block, edge e)
1285 {
1286 if (cfg_hooks->lv_adjust_loop_header_phi)
1287 cfg_hooks->lv_adjust_loop_header_phi (first, second, new_block, e);
1288 }
1289
1290 /* Conditions in trees and RTL are different so we need
1291 a different handling when we add the condition to the
1292 versioning code. */
1293 void
1294 lv_add_condition_to_bb (basic_block first, basic_block second,
1295 basic_block new_block, void *cond)
1296 {
1297 gcc_assert (cfg_hooks->lv_add_condition_to_bb);
1298 cfg_hooks->lv_add_condition_to_bb (first, second, new_block, cond);
1299 }
1300
1301 /* Checks whether all N blocks in BBS array can be copied. */
1302 bool
1303 can_copy_bbs_p (basic_block *bbs, unsigned n)
1304 {
1305 unsigned i;
1306 edge e;
1307 int ret = true;
1308
1309 for (i = 0; i < n; i++)
1310 bbs[i]->flags |= BB_DUPLICATED;
1311
1312 for (i = 0; i < n; i++)
1313 {
1314 /* In case we should redirect abnormal edge during duplication, fail. */
1315 edge_iterator ei;
1316 FOR_EACH_EDGE (e, ei, bbs[i]->succs)
1317 if ((e->flags & EDGE_ABNORMAL)
1318 && (e->dest->flags & BB_DUPLICATED))
1319 {
1320 ret = false;
1321 goto end;
1322 }
1323
1324 if (!can_duplicate_block_p (bbs[i]))
1325 {
1326 ret = false;
1327 break;
1328 }
1329 }
1330
1331 end:
1332 for (i = 0; i < n; i++)
1333 bbs[i]->flags &= ~BB_DUPLICATED;
1334
1335 return ret;
1336 }
1337
1338 /* Duplicates N basic blocks stored in array BBS. Newly created basic blocks
1339 are placed into array NEW_BBS in the same order. Edges from basic blocks
1340 in BBS are also duplicated and copies of those that lead into BBS are
1341 redirected to appropriate newly created block. The function assigns bbs
1342 into loops (copy of basic block bb is assigned to bb->loop_father->copy
1343 loop, so this must be set up correctly in advance)
1344
1345 If UPDATE_DOMINANCE is true then this function updates dominators locally
1346 (LOOPS structure that contains the information about dominators is passed
1347 to enable this), otherwise it does not update the dominator information
1348 and it assumed that the caller will do this, perhaps by destroying and
1349 recreating it instead of trying to do an incremental update like this
1350 function does when update_dominance is true.
1351
1352 BASE is the superloop to that basic block belongs; if its header or latch
1353 is copied, we do not set the new blocks as header or latch.
1354
1355 Created copies of N_EDGES edges in array EDGES are stored in array NEW_EDGES,
1356 also in the same order.
1357
1358 Newly created basic blocks are put after the basic block AFTER in the
1359 instruction stream, and the order of the blocks in BBS array is preserved. */
1360
1361 void
1362 copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
1363 edge *edges, unsigned num_edges, edge *new_edges,
1364 class loop *base, basic_block after, bool update_dominance)
1365 {
1366 unsigned i, j;
1367 basic_block bb, new_bb, dom_bb;
1368 edge e;
1369 copy_bb_data id;
1370
1371 /* Mark the blocks to be copied. This is used by edge creation hooks
1372 to decide whether to reallocate PHI nodes capacity to avoid reallocating
1373 PHIs in the set of source BBs. */
1374 for (i = 0; i < n; i++)
1375 bbs[i]->flags |= BB_DUPLICATED;
1376
1377 /* Duplicate bbs, update dominators, assign bbs to loops. */
1378 for (i = 0; i < n; i++)
1379 {
1380 /* Duplicate. */
1381 bb = bbs[i];
1382 new_bb = new_bbs[i] = duplicate_block (bb, NULL, after, &id);
1383 after = new_bb;
1384 if (bb->loop_father)
1385 {
1386 /* Possibly set loop header. */
1387 if (bb->loop_father->header == bb && bb->loop_father != base)
1388 new_bb->loop_father->header = new_bb;
1389 /* Or latch. */
1390 if (bb->loop_father->latch == bb && bb->loop_father != base)
1391 new_bb->loop_father->latch = new_bb;
1392 }
1393 }
1394
1395 /* Set dominators. */
1396 if (update_dominance)
1397 {
1398 for (i = 0; i < n; i++)
1399 {
1400 bb = bbs[i];
1401 new_bb = new_bbs[i];
1402
1403 dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb);
1404 if (dom_bb->flags & BB_DUPLICATED)
1405 {
1406 dom_bb = get_bb_copy (dom_bb);
1407 set_immediate_dominator (CDI_DOMINATORS, new_bb, dom_bb);
1408 }
1409 }
1410 }
1411
1412 /* Redirect edges. */
1413 for (i = 0; i < n; i++)
1414 {
1415 edge_iterator ei;
1416 new_bb = new_bbs[i];
1417 bb = bbs[i];
1418
1419 FOR_EACH_EDGE (e, ei, new_bb->succs)
1420 {
1421 if (!(e->dest->flags & BB_DUPLICATED))
1422 continue;
1423 redirect_edge_and_branch_force (e, get_bb_copy (e->dest));
1424 }
1425 }
1426 for (j = 0; j < num_edges; j++)
1427 {
1428 if (!edges[j])
1429 new_edges[j] = NULL;
1430 else
1431 {
1432 basic_block src = edges[j]->src;
1433 basic_block dest = edges[j]->dest;
1434 if (src->flags & BB_DUPLICATED)
1435 src = get_bb_copy (src);
1436 if (dest->flags & BB_DUPLICATED)
1437 dest = get_bb_copy (dest);
1438 new_edges[j] = find_edge (src, dest);
1439 }
1440 }
1441
1442 /* Clear information about duplicates. */
1443 for (i = 0; i < n; i++)
1444 bbs[i]->flags &= ~BB_DUPLICATED;
1445 }
1446
1447 /* Return true if BB contains only labels or non-executable
1448 instructions */
1449 bool
1450 empty_block_p (basic_block bb)
1451 {
1452 gcc_assert (cfg_hooks->empty_block_p);
1453 return cfg_hooks->empty_block_p (bb);
1454 }
1455
1456 /* Split a basic block if it ends with a conditional branch and if
1457 the other part of the block is not empty. */
1458 basic_block
1459 split_block_before_cond_jump (basic_block bb)
1460 {
1461 gcc_assert (cfg_hooks->split_block_before_cond_jump);
1462 return cfg_hooks->split_block_before_cond_jump (bb);
1463 }
1464
1465 /* Work-horse for passes.cc:check_profile_consistency.
1466 Do book-keeping of the CFG for the profile consistency checker.
1467 Store the counting in RECORD. */
1468
1469 void
1470 profile_record_check_consistency (profile_record *record)
1471 {
1472 basic_block bb;
1473 edge_iterator ei;
1474 edge e;
1475
1476 FOR_ALL_BB_FN (bb, cfun)
1477 {
1478 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
1479 && profile_status_for_fn (cfun) != PROFILE_ABSENT
1480 && EDGE_COUNT (bb->succs))
1481 {
1482 sreal sum = 0;
1483 bool found = false;
1484 FOR_EACH_EDGE (e, ei, bb->succs)
1485 {
1486 if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
1487 found = true;
1488 if (e->probability.initialized_p ())
1489 sum += e->probability.to_sreal ();
1490 }
1491 double dsum = sum.to_double ();
1492 if (found && (dsum < 0.9 || dsum > 1.1)
1493 && !(bb->count == profile_count::zero ()))
1494 {
1495 record->num_mismatched_prob_out++;
1496 dsum = dsum > 1 ? dsum - 1 : 1 - dsum;
1497 if (profile_info)
1498 {
1499 if (ENTRY_BLOCK_PTR_FOR_FN
1500 (cfun)->count.ipa ().initialized_p ()
1501 && ENTRY_BLOCK_PTR_FOR_FN
1502 (cfun)->count.ipa ().nonzero_p ()
1503 && bb->count.ipa ().initialized_p ())
1504 record->dyn_mismatched_prob_out
1505 += dsum * bb->count.ipa ().to_gcov_type ();
1506 }
1507 else if (bb->count.initialized_p ())
1508 record->dyn_mismatched_prob_out
1509 += dsum * bb->count.to_sreal_scale
1510 (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count).to_double ();
1511 }
1512 }
1513 if (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun)
1514 && profile_status_for_fn (cfun) != PROFILE_ABSENT)
1515 {
1516 profile_count lsum = profile_count::zero ();
1517 FOR_EACH_EDGE (e, ei, bb->preds)
1518 lsum += e->count ();
1519 if (lsum.differs_from_p (bb->count))
1520 {
1521 record->num_mismatched_count_in++;
1522 profile_count max;
1523 if (lsum < bb->count)
1524 max = bb->count;
1525 else
1526 max = lsum;
1527 if (profile_info)
1528 {
1529 if (ENTRY_BLOCK_PTR_FOR_FN
1530 (cfun)->count.ipa ().initialized_p ()
1531 && ENTRY_BLOCK_PTR_FOR_FN
1532 (cfun)->count.ipa ().nonzero_p ()
1533 && max.ipa ().initialized_p ())
1534 record->dyn_mismatched_count_in
1535 += max.ipa ().to_gcov_type ();
1536 }
1537 else if (bb->count.initialized_p ())
1538 record->dyn_mismatched_prob_out
1539 += max.to_sreal_scale
1540 (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count).to_double ();
1541 }
1542 }
1543 if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
1544 || bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
1545 continue;
1546 }
1547 }
1548
1549 /* Work-horse for passes.cc:acount_profile.
1550 Do book-keeping of the CFG for the profile accounting.
1551 Store the counting in RECORD. */
1552
1553 void
1554 profile_record_account_profile (profile_record *record)
1555 {
1556 basic_block bb;
1557
1558 FOR_ALL_BB_FN (bb, cfun)
1559 {
1560 gcc_assert (cfg_hooks->account_profile_record);
1561 cfg_hooks->account_profile_record (bb, record);
1562 }
1563 }
1564
1565 #if __GNUC__ >= 10
1566 # pragma GCC diagnostic pop
1567 #endif