1 /* Basic block reordering routines for the GNU compiler.
2 Copyright (C) 2000 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
23 "Profile Guided Code Positioning"
24 Pettis and Hanson; PLDI '90.
32 #include "basic-block.h"
33 #include "insn-config.h"
35 #include "hard-reg-set.h"
42 #include "insn-flags.h"
47 /* The contents of the current function definition are allocated
48 in this obstack, and all are freed at the end of the function.
49 For top-level functions, this is temporary_obstack.
50 Separate obstacks are made for nested functions. */
52 extern struct obstack *function_obstack;
55 /* Structure to hold information about lexical scopes. */
56 typedef struct scope_def
60 /* The NOTE_INSN_BLOCK_BEG that started this scope. */
63 /* The NOTE_INSN_BLOCK_END that ended this scope. */
66 /* The bb containing note_beg (if any). */
69 /* The bb containing note_end (if any). */
72 /* List of basic blocks contained within this scope. */
75 /* Number of blocks contained within this scope. */
78 /* The outer scope or NULL if outermost scope. */
79 struct scope_def *outer;
81 /* The first inner scope or NULL if innermost scope. */
82 struct scope_def *inner;
84 /* The last inner scope or NULL if innermost scope. */
85 struct scope_def *inner_last;
87 /* Link to the next (sibling) scope. */
88 struct scope_def *next;
91 /* Structure to hold information about the scope forest. */
94 /* Number of trees in forest. */
97 /* List of tree roots. */
102 typedef struct reorder_block_def {
105 basic_block add_jump;
109 } *reorder_block_def;
111 static struct reorder_block_def rbd_init
116 NULL_RTX, /* eff_head */
117 NULL_RTX, /* eff_end */
122 #define REORDER_BLOCK_HEAD 0x1
123 #define REORDER_BLOCK_VISITED 0x2
125 #define REORDER_BLOCK_FLAGS(bb) \
126 ((reorder_block_def) (bb)->aux)->flags
128 #define REORDER_BLOCK_INDEX(bb) \
129 ((reorder_block_def) (bb)->aux)->index
131 #define REORDER_BLOCK_ADD_JUMP(bb) \
132 ((reorder_block_def) (bb)->aux)->add_jump
134 #define REORDER_BLOCK_EFF_HEAD(bb) \
135 ((reorder_block_def) (bb)->aux)->eff_head
137 #define REORDER_BLOCK_EFF_END(bb) \
138 ((reorder_block_def) (bb)->aux)->eff_end
140 #define REORDER_BLOCK_SCOPE(bb) \
141 ((reorder_block_def) (bb)->aux)->scope
144 static int reorder_index;
145 static basic_block reorder_last_visited;
148 /* Local function prototypes. */
149 static rtx skip_insns_after_block PARAMS ((basic_block));
150 static basic_block get_common_dest PARAMS ((basic_block, basic_block));
151 static basic_block chain_reorder_blocks PARAMS ((edge, basic_block));
152 static void make_reorder_chain PARAMS ((basic_block));
153 static void fixup_reorder_chain PARAMS ((void));
154 #ifdef ENABLE_CHECKING
155 static void verify_insn_chain PARAMS ((void));
157 static void relate_bbs_with_scopes PARAMS ((scope));
158 static scope make_new_scope PARAMS ((int, rtx));
159 static void build_scope_forest PARAMS ((scope_forest_info *));
160 static void remove_scope_notes PARAMS ((void));
161 static void insert_intra_1 PARAMS ((scope, rtx *));
162 static void insert_intra_bb_scope_notes PARAMS ((basic_block));
163 static void insert_inter_bb_scope_notes PARAMS ((basic_block, basic_block));
164 static void rebuild_scope_notes PARAMS ((scope_forest_info *));
165 static void free_scope_forest_1 PARAMS ((scope));
166 static void free_scope_forest PARAMS ((scope_forest_info *));
167 void dump_scope_forest PARAMS ((scope_forest_info *));
168 static void dump_scope_forest_1 PARAMS ((scope, int));
169 static rtx get_next_bb_note PARAMS ((rtx));
170 static rtx get_prev_bb_note PARAMS ((rtx));
172 /* Skip over inter-block insns occurring after BB which are typically
173 associated with BB (e.g., barriers). If there are any such insns,
174 we return the last one. Otherwise, we return the end of BB. */
177 skip_insns_after_block (bb)
184 if (bb == EXIT_BLOCK_PTR)
187 for (insn = NEXT_INSN (bb->end);
189 last_insn = insn, insn = NEXT_INSN (insn))
191 if (bb->index + 1 != n_basic_blocks
192 && insn == BASIC_BLOCK (bb->index + 1)->head)
195 if (GET_CODE (insn) == BARRIER
196 || GET_CODE (insn) == JUMP_INSN
197 || (GET_CODE (insn) == NOTE
198 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
199 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)))
202 if (GET_CODE (insn) == CODE_LABEL
203 && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
204 && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
205 || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
207 insn = NEXT_INSN (insn);
211 /* Skip to next non-deleted insn. */
212 if (GET_CODE (insn) == NOTE
213 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED
214 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL))
224 /* Return common destination for blocks BB0 and BB1. */
227 get_common_dest (bb0, bb1)
228 basic_block bb0, bb1;
232 for (e0 = bb0->succ; e0; e0 = e0->succ_next)
234 for (e1 = bb1->succ; e1; e1 = e1->succ_next)
236 if (e0->dest == e1->dest)
246 /* Move the destination block for edge E after chain end block CEB
247 Adding jumps and labels is deferred until fixup_reorder_chain. */
250 chain_reorder_blocks (e, ceb)
254 basic_block sb = e->src;
255 basic_block db = e->dest;
256 rtx cebe_insn, dbh_insn, dbe_insn;
258 edge e_fallthru, e_jump;
260 enum cond_types {NO_COND, PREDICT_THEN_WITH_ELSE, PREDICT_ELSE,
261 PREDICT_THEN_NO_ELSE, PREDICT_NOT_THEN_NO_ELSE};
262 enum cond_types cond_type;
263 enum cond_block_types {NO_COND_BLOCK, THEN_BLOCK, ELSE_BLOCK,
265 enum cond_block_types cond_block_type;
268 fprintf (rtl_dump_file,
269 "Edge from basic block %d to basic block %d last visited %d\n",
270 sb->index, db->index, ceb->index);
271 cebe_insn = REORDER_BLOCK_EFF_END (ceb);
273 /* Blocks are in original order. */
274 if (sb->index == ceb->index
275 && ceb->index + 1 == db->index && NEXT_INSN (cebe_insn))
278 e_fallthru = e_jump = e;
280 /* Get the type of block and type of condition. */
282 cond_block_type = NO_COND_BLOCK;
283 if (GET_CODE (sb->end) == JUMP_INSN && ! simplejump_p (sb->end)
284 && condjump_p (sb->end))
286 if (e->flags & EDGE_FALLTHRU)
289 e_jump = sb->succ->succ_next;
290 else if (e == sb->succ->succ_next)
298 e_fallthru = sb->succ->succ_next;
299 else if (e == sb->succ->succ_next)
300 e_fallthru = sb->succ;
305 if (e->flags & EDGE_FALLTHRU)
306 cond_block_type = THEN_BLOCK;
307 else if (get_common_dest (e_fallthru->dest, sb))
308 cond_block_type = NO_ELSE_BLOCK;
310 cond_block_type = ELSE_BLOCK;
312 if (get_common_dest (e_fallthru->dest, sb))
314 if (cond_block_type == THEN_BLOCK)
316 if (! (REORDER_BLOCK_FLAGS (e->dest)
317 & REORDER_BLOCK_VISITED))
318 cond_type = PREDICT_THEN_NO_ELSE;
320 cond_type = PREDICT_NOT_THEN_NO_ELSE;
322 else if (cond_block_type == NO_ELSE_BLOCK)
324 if (! (REORDER_BLOCK_FLAGS (e->dest)
325 & REORDER_BLOCK_VISITED))
326 cond_type = PREDICT_NOT_THEN_NO_ELSE;
328 cond_type = PREDICT_THEN_NO_ELSE;
333 if (cond_block_type == THEN_BLOCK)
335 if (! (REORDER_BLOCK_FLAGS (e->dest)
336 & REORDER_BLOCK_VISITED))
337 cond_type = PREDICT_THEN_WITH_ELSE;
339 cond_type = PREDICT_ELSE;
341 else if (cond_block_type == ELSE_BLOCK
342 && e_fallthru->dest != EXIT_BLOCK_PTR)
344 if (! (REORDER_BLOCK_FLAGS (e->dest)
345 & REORDER_BLOCK_VISITED))
346 cond_type = PREDICT_ELSE;
348 cond_type = PREDICT_THEN_WITH_ELSE;
355 static const char * cond_type_str [] = {"not cond jump", "predict then",
357 "predict then w/o else",
358 "predict not then w/o else"};
359 static const char * cond_block_type_str [] = {"not then or else block",
362 "then w/o else block"};
364 fprintf (rtl_dump_file, " %s (looking at %s)\n",
365 cond_type_str[(int)cond_type],
366 cond_block_type_str[(int)cond_block_type]);
369 /* Reflect that then block will move and we'll jump to it. */
370 if (cond_block_type != THEN_BLOCK
371 && (cond_type == PREDICT_ELSE
372 || cond_type == PREDICT_NOT_THEN_NO_ELSE))
375 fprintf (rtl_dump_file,
376 " then jump from block %d to block %d\n",
377 sb->index, e_fallthru->dest->index);
379 /* Jump to reordered then block. */
380 REORDER_BLOCK_ADD_JUMP (sb) = e_fallthru->dest;
383 /* Reflect that then block will jump back when we have no else. */
384 if (cond_block_type != THEN_BLOCK
385 && cond_type == PREDICT_NOT_THEN_NO_ELSE)
387 basic_block jbb = e_fallthru->dest;
389 ee && ! (ee->flags & EDGE_FALLTHRU);
393 if (ee && ! (GET_CODE (jbb->end) == JUMP_INSN
394 && ! simplejump_p (jbb->end)))
396 REORDER_BLOCK_ADD_JUMP (jbb) = ee->dest;
400 /* Reflect that else block will jump back. */
401 if (cond_block_type == ELSE_BLOCK
402 && (cond_type == PREDICT_THEN_WITH_ELSE || cond_type == PREDICT_ELSE))
407 && last_edge->dest != EXIT_BLOCK_PTR
408 && GET_CODE (last_edge->dest->head) == CODE_LABEL
409 && ! (GET_CODE (db->end) == JUMP_INSN))
412 fprintf (rtl_dump_file,
413 " else jump from block %d to block %d\n",
414 db->index, last_edge->dest->index);
416 REORDER_BLOCK_ADD_JUMP (db) = last_edge->dest;
420 /* This block's successor has already been reordered. This can happen
421 when we reorder a chain starting at a then or else. */
422 for (last_edge = db->succ;
423 last_edge && ! (last_edge->flags & EDGE_FALLTHRU);
424 last_edge = last_edge->succ_next)
428 && last_edge->dest != EXIT_BLOCK_PTR
429 && (REORDER_BLOCK_FLAGS (last_edge->dest)
430 & REORDER_BLOCK_VISITED))
433 fprintf (rtl_dump_file,
434 " end of chain jump from block %d to block %d\n",
435 db->index, last_edge->dest->index);
437 REORDER_BLOCK_ADD_JUMP (db) = last_edge->dest;
440 dbh_insn = REORDER_BLOCK_EFF_HEAD (db);
441 cebe_insn = REORDER_BLOCK_EFF_END (ceb);
442 dbe_insn = REORDER_BLOCK_EFF_END (db);
444 /* Rechain predicted block. */
445 NEXT_INSN (cebe_insn) = dbh_insn;
446 PREV_INSN (dbh_insn) = cebe_insn;
448 if (db->index != n_basic_blocks - 1)
449 NEXT_INSN (dbe_insn) = 0;
455 /* Reorder blocks starting at block BB. */
458 make_reorder_chain (bb)
462 basic_block visited_edge = NULL;
466 if (bb == EXIT_BLOCK_PTR)
469 /* Find the most probable block. */
472 if (GET_CODE (block_end) == JUMP_INSN && condjump_p (block_end))
474 rtx note = find_reg_note (block_end, REG_BR_PROB, 0);
477 probability = INTVAL (XEXP (note, 0));
481 if (probability >= REG_BR_PROB_BASE / 2)
482 e = bb->succ->succ_next;
485 /* Add chosen successor to chain and recurse on it. */
486 if (e && e->dest != EXIT_BLOCK_PTR
488 && (! (REORDER_BLOCK_FLAGS (e->dest) & REORDER_BLOCK_VISITED)
489 || (REORDER_BLOCK_FLAGS (e->dest) == REORDER_BLOCK_HEAD)))
491 if (! (REORDER_BLOCK_FLAGS (bb) & REORDER_BLOCK_VISITED))
493 REORDER_BLOCK_FLAGS (bb) |= REORDER_BLOCK_HEAD;
494 REORDER_BLOCK_INDEX (bb) = reorder_index++;
495 REORDER_BLOCK_FLAGS (bb) |= REORDER_BLOCK_VISITED;
498 if (REORDER_BLOCK_FLAGS (e->dest) & REORDER_BLOCK_VISITED)
499 REORDER_BLOCK_FLAGS (e->dest) &= ~REORDER_BLOCK_HEAD;
501 visited_edge = e->dest;
503 reorder_last_visited = chain_reorder_blocks (e, bb);
506 && ! (REORDER_BLOCK_FLAGS (e->dest)
507 & REORDER_BLOCK_VISITED))
508 make_reorder_chain (e->dest);
512 if (! (REORDER_BLOCK_FLAGS (bb) & REORDER_BLOCK_VISITED))
514 REORDER_BLOCK_INDEX (bb) = reorder_index++;
515 REORDER_BLOCK_FLAGS (bb) |= REORDER_BLOCK_VISITED;
519 /* Recurse on the successors. */
520 for (e = bb->succ; e; e = e->succ_next)
522 if (e->dest && e->dest == EXIT_BLOCK_PTR)
527 && e->dest != visited_edge
528 && ! (REORDER_BLOCK_FLAGS (e->dest)
529 & REORDER_BLOCK_VISITED))
532 = chain_reorder_blocks (e, reorder_last_visited);
533 make_reorder_chain (e->dest);
539 /* Fixup jumps and labels after reordering basic blocks. */
542 fixup_reorder_chain ()
546 int orig_num_blocks = n_basic_blocks;
548 /* Set the new last insn. */
552 for (j = 0; j < n_basic_blocks; j++)
554 int val = REORDER_BLOCK_INDEX (BASIC_BLOCK (j));
561 insn = REORDER_BLOCK_EFF_END (BASIC_BLOCK (max_index));
562 NEXT_INSN (insn) = NULL_RTX;
563 set_last_insn (insn);
566 /* Add jumps and labels to fixup blocks. */
567 for (i = 0; i < orig_num_blocks; i++)
570 basic_block bbi = BASIC_BLOCK (i);
571 if (REORDER_BLOCK_ADD_JUMP (bbi))
573 rtx label_insn, jump_insn, barrier_insn;
575 if (GET_CODE (REORDER_BLOCK_ADD_JUMP (bbi)->head) == CODE_LABEL)
576 label_insn = REORDER_BLOCK_ADD_JUMP (bbi)->head;
579 rtx new_label = gen_label_rtx ();
580 label_insn = emit_label_before (new_label,
581 REORDER_BLOCK_ADD_JUMP (bbi)->head);
582 REORDER_BLOCK_ADD_JUMP (bbi)->head = label_insn;
585 if (GET_CODE (bbi->end) != JUMP_INSN)
587 jump_insn = emit_jump_insn_after (gen_jump (label_insn),
589 bbi->end = jump_insn;
594 jump_insn = emit_jump_insn_after (gen_jump (label_insn),
595 REORDER_BLOCK_EFF_END (bbi));
599 JUMP_LABEL (jump_insn) = label_insn;
600 ++LABEL_NUSES (label_insn);
601 barrier_insn = emit_barrier_after (jump_insn);
603 /* Add block for jump. Typically this is when a then is not
604 predicted and we are jumping to the moved then block. */
609 VARRAY_GROW (basic_block_info, ++n_basic_blocks);
610 create_basic_block (n_basic_blocks - 1, jump_insn,
612 nb = BASIC_BLOCK (n_basic_blocks - 1);
613 nb->global_live_at_start
614 = OBSTACK_ALLOC_REG_SET (function_obstack);
615 nb->global_live_at_end
616 = OBSTACK_ALLOC_REG_SET (function_obstack);
618 COPY_REG_SET (nb->global_live_at_start,
619 bbi->global_live_at_start);
620 COPY_REG_SET (nb->global_live_at_end,
621 bbi->global_live_at_start);
622 BASIC_BLOCK (nb->index)->local_set = 0;
624 nb->aux = xcalloc (1, sizeof (struct reorder_block_def));
625 REORDER_BLOCK_INDEX (nb) = REORDER_BLOCK_INDEX (bbi) + 1;
626 /* Relink to new block. */
627 nb->succ = bbi->succ;
630 make_edge (NULL, bbi, nb, 0);
632 = bbi->succ->succ_next->succ_next;
633 nb->succ->succ_next = 0;
634 /* Fix reorder block index to reflect new block. */
635 for (j = 0; j < n_basic_blocks - 1; j++)
637 basic_block bbj = BASIC_BLOCK (j);
638 if (REORDER_BLOCK_INDEX (bbj)
639 >= REORDER_BLOCK_INDEX (bbi) + 1)
640 REORDER_BLOCK_INDEX (bbj)++;
642 REORDER_BLOCK_SCOPE (nb) = REORDER_BLOCK_SCOPE (bbi);
643 REORDER_BLOCK_EFF_HEAD (nb) = nb->head;
644 REORDER_BLOCK_EFF_END (nb) = barrier_insn;
647 REORDER_BLOCK_EFF_END (bbi) = barrier_insn;
653 /* Perform sanity checks on the insn chain.
654 1. Check that next/prev pointers are consistent in both the forward and
656 2. Count insns in chain, going both directions, and check if equal.
657 3. Check that get_last_insn () returns the actual end of chain. */
658 #ifdef ENABLE_CHECKING
670 for (x = get_insns (); x; x = NEXT_INSN (x))
672 if (PREV_INSN (x) != prevx)
674 fprintf (stderr, "Forward traversal: insn chain corrupt.\n");
675 fprintf (stderr, "previous insn:\n");
677 fprintf (stderr, "current insn:\n");
685 if (prevx != get_last_insn ())
687 fprintf (stderr, "last_insn corrupt.\n");
693 for (x = get_last_insn (); x; x = PREV_INSN (x))
695 if (NEXT_INSN (x) != nextx)
697 fprintf (stderr, "Reverse traversal: insn chain corrupt.\n");
698 fprintf (stderr, "current insn:\n");
700 fprintf (stderr, "next insn:\n");
708 if (insn_cnt1 != insn_cnt2)
710 fprintf (stderr, "insn_cnt1 (%d) not equal to insn_cnt2 (%d).\n",
711 insn_cnt1, insn_cnt2);
723 if (GET_CODE (x) == NOTE
724 && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
738 if (GET_CODE (x) == NOTE
739 && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
747 /* Determine and record the relationships between basic blocks and
748 scopes in scope tree S. */
751 relate_bbs_with_scopes (s)
755 int i, bbi1, bbi2, bbs_spanned;
758 for (p = s->inner; p; p = p->next)
759 relate_bbs_with_scopes (p);
764 /* If the begin and end notes are both inside the same basic block,
765 or if they are both outside of basic blocks, then we know immediately
766 how they are related. Otherwise, we need to poke around to make the
768 if (s->bb_beg != s->bb_end)
770 if (s->bb_beg && s->bb_end)
772 /* Both notes are in different bbs. This implies that all the
773 basic blocks spanned by the pair of notes are contained in
775 bbi1 = s->bb_beg->index;
776 bbi2 = s->bb_end->index;
779 else if (! s->bb_beg)
781 /* First note is outside of a bb. If the scope spans more than
782 one basic block, then they all are contained within this
783 scope. Otherwise, this scope is contained within the basic
785 bbnote = get_next_bb_note (s->note_beg);
788 if (NOTE_BASIC_BLOCK (bbnote) == s->bb_end)
791 s->bb_beg = NOTE_BASIC_BLOCK (bbnote);
795 bbi1 = NOTE_BASIC_BLOCK (bbnote)->index;
796 bbi2 = s->bb_end->index;
801 else /* ! s->bb_end */
803 /* Second note is outside of a bb. If the scope spans more than
804 one basic block, then they all are contained within this
805 scope. Otherwise, this scope is contained within the basic
807 bbnote = get_prev_bb_note (s->note_end);
810 if (NOTE_BASIC_BLOCK (bbnote) == s->bb_beg)
813 s->bb_end = NOTE_BASIC_BLOCK (bbnote);
817 bbi1 = s->bb_beg->index;
818 bbi2 = NOTE_BASIC_BLOCK (bbnote)->index;
827 /* Both notes are in the same bb, which implies the block
828 contains this scope. */
833 /* Both notes are outside of any bbs. This implies that all the
834 basic blocks spanned by the pair of notes are contained in
836 There is a degenerate case to consider. If the notes do not
837 span any basic blocks, then it is an empty scope that can
838 safely be deleted or ignored. Mark these with level = -1. */
840 x1 = get_next_bb_note (s->note_beg);
841 x2 = get_prev_bb_note (s->note_end);
849 bbi1 = NOTE_BASIC_BLOCK (x1)->index;
850 bbi2 = NOTE_BASIC_BLOCK (x2)->index;
857 /* If the scope spans one or more basic blocks, we record them. We
858 only record the bbs that are immediately contained within this
859 scope. Note that if a scope is contained within a bb, we can tell
860 by checking that bb_beg = bb_end and that they are non-null. */
866 for (i = bbi1; i <= bbi2; i++)
867 if (! REORDER_BLOCK_SCOPE (BASIC_BLOCK (i)))
870 s->bbs = xcalloc (s->num_bbs, sizeof (struct basic_block_def));
871 for (i = bbi1; i <= bbi2; i++)
873 basic_block curr_bb = BASIC_BLOCK (i);
874 if (! REORDER_BLOCK_SCOPE (curr_bb))
876 s->bbs[j++] = curr_bb;
877 REORDER_BLOCK_SCOPE (curr_bb) = s;
886 /* Allocate and initialize a new scope structure with scope level LEVEL,
887 and record the NOTE beginning the scope. */
890 make_new_scope (level, note)
894 scope new_scope = xcalloc (1, sizeof (struct scope_def));
895 new_scope->level = level;
896 new_scope->note_beg = note;
897 new_scope->note_end = NULL;
898 new_scope->bb_beg = NULL;
899 new_scope->bb_end = NULL;
900 new_scope->inner = NULL;
901 new_scope->inner_last = NULL;
902 new_scope->outer = NULL;
903 new_scope->next = NULL;
904 new_scope->num_bbs = 0;
905 new_scope->bbs = NULL;
910 /* Build a forest representing the scope structure of the function.
911 Return a pointer to a structure describing the forest. */
914 build_scope_forest (forest)
915 scope_forest_info *forest;
920 scope root, curr_scope;
922 forest->num_trees = 0;
923 forest->trees = NULL;
928 for (x = get_insns (); x; x = NEXT_INSN (x))
930 if (bbi < n_basic_blocks && x == BASIC_BLOCK (bbi)->head)
931 curr_bb = BASIC_BLOCK (bbi);
933 if (GET_CODE (x) == NOTE)
935 if (NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_BEG)
943 new_scope = make_new_scope (level, x);
944 new_scope->outer = curr_scope;
945 new_scope->next = NULL;
946 if (! curr_scope->inner)
948 curr_scope->inner = new_scope;
949 curr_scope->inner_last = new_scope;
953 curr_scope->inner_last->next = new_scope;
954 curr_scope->inner_last = new_scope;
956 curr_scope = curr_scope->inner_last;
960 int ntrees = forest->num_trees;
962 curr_scope = make_new_scope (level, x);
965 forest->trees = xcalloc (1, sizeof (scope));
967 forest->trees = xrealloc (forest->trees,
968 sizeof (scope) * (ntrees + 1));
969 forest->trees[forest->num_trees++] = root;
971 curr_scope->bb_beg = curr_bb;
973 else if (NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_END)
975 curr_scope->bb_end = curr_bb;
976 curr_scope->note_end = x;
978 curr_scope = curr_scope->outer;
984 if (curr_bb && curr_bb->end == x)
992 for (i = 0; i < forest->num_trees; i++)
993 relate_bbs_with_scopes (forest->trees[i]);
997 /* Remove all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes from
1001 remove_scope_notes ()
1004 basic_block currbb = NULL;
1006 for (x = get_insns (); x; x = next)
1008 next = NEXT_INSN (x);
1009 if (GET_CODE (x) == NOTE
1010 && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
1011 currbb = NOTE_BASIC_BLOCK (x);
1013 if (GET_CODE (x) == NOTE
1014 && (NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_BEG
1015 || NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_END))
1017 /* Check if the scope note happens to be the end of a bb. */
1018 if (currbb && x == currbb->end)
1019 currbb->end = PREV_INSN (x);
1020 if (currbb && x == currbb->head)
1025 NEXT_INSN (PREV_INSN (x)) = next;
1026 PREV_INSN (next) = PREV_INSN (x);
1028 NEXT_INSN (x) = NULL;
1029 PREV_INSN (x) = NULL;
1038 /* Insert scope note pairs for a contained scope tree S after insn IP. */
1040 insert_intra_1 (s, ip)
1046 if (NOTE_BLOCK (s->note_beg))
1048 *ip = emit_note_after (NOTE_INSN_BLOCK_BEG, *ip);
1049 NOTE_BLOCK (*ip) = NOTE_BLOCK (s->note_beg);
1052 for (p = s->inner; p; p = p->next)
1053 insert_intra_1 (p, ip);
1055 if (NOTE_BLOCK (s->note_beg))
1057 *ip = emit_note_after (NOTE_INSN_BLOCK_END, *ip);
1058 NOTE_BLOCK (*ip) = NOTE_BLOCK (s->note_end);
1063 /* Insert NOTE_INSN_BLOCK_END notes and NOTE_INSN_BLOCK_BEG notes for
1064 scopes that are contained within BB. */
1067 insert_intra_bb_scope_notes (bb)
1070 scope s = REORDER_BLOCK_SCOPE (bb);
1078 if (GET_CODE (ip) == CODE_LABEL)
1079 ip = NEXT_INSN (ip);
1081 for (p = s->inner; p; p = p->next)
1083 if (p->bb_beg != NULL && p->bb_beg == p->bb_end && p->bb_beg == bb)
1084 insert_intra_1 (p, &ip);
1089 /* Given two consecutive basic blocks BB1 and BB2 with different scopes,
1090 insert NOTE_INSN_BLOCK_END notes after BB1 and NOTE_INSN_BLOCK_BEG
1091 notes before BB2 such that the notes are correctly balanced. If BB1 or
1092 BB2 is NULL, we are inserting scope notes for the first and last basic
1093 blocks, respectively. */
1096 insert_inter_bb_scope_notes (bb1, bb2)
1103 /* It is possible that a basic block is not contained in any scope.
1104 In that case, we either open or close a scope but not both. */
1107 scope s1 = REORDER_BLOCK_SCOPE (bb1);
1108 scope s2 = REORDER_BLOCK_SCOPE (bb2);
1117 /* Find common ancestor scope. */
1120 scope s1 = REORDER_BLOCK_SCOPE (bb1);
1121 scope s2 = REORDER_BLOCK_SCOPE (bb2);
1126 if (s1->level > s2->level)
1128 else if (s2->level > s1->level)
1144 scope s = REORDER_BLOCK_SCOPE (bb1);
1145 ip = REORDER_BLOCK_EFF_END (bb1);
1148 if (NOTE_BLOCK (s->note_beg))
1150 ip = emit_note_after (NOTE_INSN_BLOCK_END, ip);
1151 NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_end);
1160 scope s = REORDER_BLOCK_SCOPE (bb2);
1164 if (NOTE_BLOCK (s->note_beg))
1166 ip = emit_note_before (NOTE_INSN_BLOCK_BEG, ip);
1167 NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_beg);
1175 /* Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based
1176 on the scope forest and the newly reordered basic blocks. */
1179 rebuild_scope_notes (forest)
1180 scope_forest_info *forest;
1184 if (forest->num_trees == 0)
1187 /* Start by opening the scopes before the first basic block. */
1188 insert_inter_bb_scope_notes (NULL, BASIC_BLOCK (0));
1190 /* Then, open and close scopes as needed between blocks. */
1191 for (i = 0; i < n_basic_blocks - 1; i++)
1193 basic_block bb1 = BASIC_BLOCK (i);
1194 basic_block bb2 = BASIC_BLOCK (i + 1);
1195 if (REORDER_BLOCK_SCOPE (bb1) != REORDER_BLOCK_SCOPE (bb2))
1196 insert_inter_bb_scope_notes (bb1, bb2);
1197 insert_intra_bb_scope_notes (bb1);
1200 /* Finally, close the scopes after the last basic block. */
1201 insert_inter_bb_scope_notes (BASIC_BLOCK (n_basic_blocks - 1), NULL);
1202 insert_intra_bb_scope_notes (BASIC_BLOCK (n_basic_blocks - 1));
1206 /* Free the storage associated with the scope tree at S. */
1209 free_scope_forest_1 (s)
1214 for (p = s->inner; p; p = next)
1217 free_scope_forest_1 (p);
1226 /* Free the storage associated with the scope forest. */
1229 free_scope_forest (forest)
1230 scope_forest_info *forest;
1233 for (i = 0; i < forest->num_trees; i++)
1234 free_scope_forest_1 (forest->trees[i]);
1238 /* Visualize the scope forest. */
1241 dump_scope_forest (forest)
1242 scope_forest_info *forest;
1244 if (forest->num_trees == 0)
1245 fprintf (stderr, "\n< Empty scope forest >\n");
1249 fprintf (stderr, "\n< Scope forest >\n");
1250 for (i = 0; i < forest->num_trees; i++)
1251 dump_scope_forest_1 (forest->trees[i], 0);
1256 /* Recursive portion of dump_scope_forest. */
1259 dump_scope_forest_1 (s, indent)
1266 if (s->bb_beg != NULL && s->bb_beg == s->bb_end
1267 && REORDER_BLOCK_SCOPE (s->bb_beg)
1268 && REORDER_BLOCK_SCOPE (s->bb_beg)->level + 1 == s->level)
1270 fprintf (stderr, "%*s", indent, "");
1271 fprintf (stderr, "BB%d:\n", s->bb_beg->index);
1274 fprintf (stderr, "%*s", indent, "");
1275 fprintf (stderr, "{ level %d (block %p)\n", s->level,
1276 NOTE_BLOCK (s->note_beg));
1278 fprintf (stderr, "%*s%s", indent, "", "bbs:");
1279 for (i = 0; i < s->num_bbs; i++)
1280 fprintf (stderr, " %d", s->bbs[i]->index);
1281 fprintf (stderr, "\n");
1283 for (p = s->inner; p; p = p->next)
1284 dump_scope_forest_1 (p, indent + 2);
1286 fprintf (stderr, "%*s", indent, "");
1287 fprintf (stderr, "}\n");
1291 /* Reorder basic blocks. */
1294 reorder_basic_blocks ()
1297 struct loops loops_info;
1299 scope_forest_info forest;
1301 if (profile_arc_flag)
1304 if (n_basic_blocks <= 1)
1307 /* Exception edges are not currently handled. */
1308 for (i = 0; i < n_basic_blocks; i++)
1312 for (e = BASIC_BLOCK (i)->succ; e && ! (e->flags & EDGE_EH);
1316 if (e && (e->flags & EDGE_EH))
1322 /* Find natural loops using the CFG. */
1323 num_loops = flow_loops_find (&loops_info);
1325 /* Dump loop information. */
1326 flow_loops_dump (&loops_info, rtl_dump_file, 0);
1328 reorder_last_visited = BASIC_BLOCK (0);
1330 for (i = 0; i < n_basic_blocks; i++)
1332 basic_block bbi = BASIC_BLOCK (i);
1333 bbi->aux = xcalloc (1, sizeof (struct reorder_block_def));
1334 *((struct reorder_block_def *)bbi->aux) = rbd_init;
1337 build_scope_forest (&forest);
1338 remove_scope_notes ();
1340 for (i = 0; i < n_basic_blocks; i++)
1342 basic_block bbi = BASIC_BLOCK (i);
1343 REORDER_BLOCK_EFF_END (bbi) = skip_insns_after_block (bbi);
1345 REORDER_BLOCK_EFF_HEAD (bbi) = get_insns ();
1348 rtx prev_eff_end = REORDER_BLOCK_EFF_END (BASIC_BLOCK (i - 1));
1349 REORDER_BLOCK_EFF_HEAD (bbi) = NEXT_INSN (prev_eff_end);
1353 /* If we've not got epilogue in RTL, we must fallthru to the exit.
1354 Force the last block to be at the end. */
1355 /* ??? Some ABIs (e.g. MIPS) require the return insn to be at the
1356 end of the function for stack unwinding purposes. */
1358 #ifndef HAVE_epilogue
1359 #define HAVE_epilogue 0
1362 if (! HAVE_epilogue)
1364 basic_block last = BASIC_BLOCK (n_basic_blocks - 1);
1365 REORDER_BLOCK_INDEX (last) = n_basic_blocks - 1;
1366 REORDER_BLOCK_FLAGS (last) |= REORDER_BLOCK_VISITED;
1369 make_reorder_chain (BASIC_BLOCK (0));
1371 fixup_reorder_chain ();
1373 #ifdef ENABLE_CHECKING
1374 verify_insn_chain ();
1377 /* Put basic_block_info in new order. */
1378 for (i = 0; i < n_basic_blocks - 1; i++)
1380 for (j = i; i != REORDER_BLOCK_INDEX (BASIC_BLOCK (j)); j++)
1383 if (REORDER_BLOCK_INDEX (BASIC_BLOCK (j)) == i
1388 int rbi = REORDER_BLOCK_INDEX (BASIC_BLOCK (j));
1390 temprbi = BASIC_BLOCK (rbi)->index;
1391 BASIC_BLOCK (rbi)->index = BASIC_BLOCK (j)->index;
1392 BASIC_BLOCK (j)->index = temprbi;
1393 tempbb = BASIC_BLOCK (rbi);
1394 BASIC_BLOCK (rbi) = BASIC_BLOCK (j);
1395 BASIC_BLOCK (j) = tempbb;
1399 rebuild_scope_notes (&forest);
1400 free_scope_forest (&forest);
1403 #ifdef ENABLE_CHECKING
1404 verify_flow_info ();
1407 for (i = 0; i < n_basic_blocks; i++)
1408 free (BASIC_BLOCK (i)->aux);
1410 /* Free loop information. */
1411 flow_loops_free (&loops_info);