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;
110 } *reorder_block_def;
112 static struct reorder_block_def rbd_init
118 NULL_RTX, /* eff_head */
119 NULL_RTX, /* eff_end */
124 #define REORDER_BLOCK_HEAD 0x1
125 #define REORDER_BLOCK_VISITED 0x2
127 #define REORDER_BLOCK_FLAGS(bb) \
128 ((reorder_block_def) (bb)->aux)->flags
130 #define REORDER_BLOCK_INDEX(bb) \
131 ((reorder_block_def) (bb)->aux)->index
133 #define REORDER_BLOCK_ADD_JUMP(bb) \
134 ((reorder_block_def) (bb)->aux)->add_jump
136 #define REORDER_BLOCK_SUCC(bb) \
137 ((reorder_block_def) (bb)->aux)->succ
139 #define REORDER_BLOCK_EFF_HEAD(bb) \
140 ((reorder_block_def) (bb)->aux)->eff_head
142 #define REORDER_BLOCK_EFF_END(bb) \
143 ((reorder_block_def) (bb)->aux)->eff_end
145 #define REORDER_BLOCK_SCOPE(bb) \
146 ((reorder_block_def) (bb)->aux)->scope
149 static int reorder_index;
150 static basic_block reorder_last_visited;
152 enum reorder_skip_type {REORDER_SKIP_BEFORE, REORDER_SKIP_AFTER,
153 REORDER_SKIP_BLOCK_END};
156 /* Local function prototypes. */
157 static rtx skip_insns_between_block PARAMS ((basic_block,
158 enum reorder_skip_type));
159 static basic_block get_common_dest PARAMS ((basic_block, basic_block));
160 static basic_block chain_reorder_blocks PARAMS ((edge, basic_block));
161 static void make_reorder_chain PARAMS ((basic_block));
162 static void fixup_reorder_chain PARAMS ((void));
163 #ifdef ENABLE_CHECKING
164 static void verify_insn_chain PARAMS ((void));
166 static void relate_bbs_with_scopes PARAMS ((scope));
167 static scope make_new_scope PARAMS ((int, rtx));
168 static void build_scope_forest PARAMS ((scope_forest_info *));
169 static void remove_scope_notes PARAMS ((void));
170 static void insert_intra_1 PARAMS ((scope, rtx *));
171 static void insert_intra_bb_scope_notes PARAMS ((basic_block));
172 static void insert_inter_bb_scope_notes PARAMS ((basic_block, basic_block));
173 static void rebuild_scope_notes PARAMS ((scope_forest_info *));
174 static void free_scope_forest_1 PARAMS ((scope));
175 static void free_scope_forest PARAMS ((scope_forest_info *));
176 void dump_scope_forest PARAMS ((scope_forest_info *));
177 static void dump_scope_forest_1 PARAMS ((scope, int));
179 /* Skip over insns BEFORE or AFTER BB which are typically associated with
183 skip_insns_between_block (bb, skip_type)
185 enum reorder_skip_type skip_type;
189 if (skip_type == REORDER_SKIP_BEFORE)
191 if (bb == ENTRY_BLOCK_PTR)
194 last_insn = bb->head;
195 for (insn = PREV_INSN (bb->head);
196 insn && insn != BASIC_BLOCK (bb->index - 1)->end;
197 last_insn = insn, insn = PREV_INSN (insn))
199 if (NEXT_INSN (insn) != last_insn)
202 if (GET_CODE (insn) == NOTE
203 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_END
204 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK
205 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_END)
215 if (bb == EXIT_BLOCK_PTR)
218 for (insn = NEXT_INSN (bb->end);
220 last_insn = insn, insn = NEXT_INSN (insn))
222 if (bb->index + 1 != n_basic_blocks
223 && insn == BASIC_BLOCK (bb->index + 1)->head)
226 if (GET_CODE (insn) == BARRIER
227 || GET_CODE (insn) == JUMP_INSN
228 || (GET_CODE (insn) == NOTE
229 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
230 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)))
233 if (GET_CODE (insn) == CODE_LABEL
234 && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
235 && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
237 (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
239 insn = NEXT_INSN (insn);
243 /* Skip to next non-deleted insn. */
244 if (GET_CODE (insn) == NOTE
245 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED
246 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL))
252 if (skip_type == REORDER_SKIP_BLOCK_END)
254 int found_block_end = 0;
256 for (; insn; last_insn = insn, insn = NEXT_INSN (insn))
258 if (bb->index + 1 != n_basic_blocks
259 && insn == BASIC_BLOCK (bb->index + 1)->head)
262 if (GET_CODE (insn) == NOTE
263 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
269 if (GET_CODE (insn) == NOTE
270 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
273 if (GET_CODE (insn) == NOTE
274 && NOTE_LINE_NUMBER (insn) >= 0
276 && GET_CODE (NEXT_INSN (insn)) == NOTE
277 && (NOTE_LINE_NUMBER (NEXT_INSN (insn))
278 == NOTE_INSN_BLOCK_END))
283 if (! found_block_end)
292 /* Return common destination for blocks BB0 and BB1. */
295 get_common_dest (bb0, bb1)
296 basic_block bb0, bb1;
300 for (e0 = bb0->succ; e0; e0 = e0->succ_next)
302 for (e1 = bb1->succ; e1; e1 = e1->succ_next)
304 if (e0->dest == e1->dest)
314 /* Move the destination block for edge E after chain end block CEB
315 Adding jumps and labels is deferred until fixup_reorder_chain. */
318 chain_reorder_blocks (e, ceb)
322 basic_block sb = e->src;
323 basic_block db = e->dest;
324 rtx cebe_insn, dbh_insn, dbe_insn;
326 edge e_fallthru, e_jump;
328 enum cond_types {NO_COND, PREDICT_THEN_WITH_ELSE, PREDICT_ELSE,
329 PREDICT_THEN_NO_ELSE, PREDICT_NOT_THEN_NO_ELSE};
330 enum cond_types cond_type;
331 enum cond_block_types {NO_COND_BLOCK, THEN_BLOCK, ELSE_BLOCK,
333 enum cond_block_types cond_block_type;
336 fprintf (rtl_dump_file,
337 "Edge from basic block %d to basic block %d last visited %d\n",
338 sb->index, db->index, ceb->index);
339 cebe_insn = REORDER_BLOCK_EFF_END (ceb);
341 /* Blocks are in original order. */
342 if (sb->index == ceb->index
343 && ceb->index + 1 == db->index && NEXT_INSN (cebe_insn))
346 e_fallthru = e_jump = e;
348 /* Get the type of block and type of condition. */
350 cond_block_type = NO_COND_BLOCK;
351 if (GET_CODE (sb->end) == JUMP_INSN && ! simplejump_p (sb->end)
352 && condjump_p (sb->end))
354 if (e->flags & EDGE_FALLTHRU)
357 e_jump = sb->succ->succ_next;
358 else if (e == sb->succ->succ_next)
366 e_fallthru = sb->succ->succ_next;
367 else if (e == sb->succ->succ_next)
368 e_fallthru = sb->succ;
373 if (e->flags & EDGE_FALLTHRU)
374 cond_block_type = THEN_BLOCK;
375 else if (get_common_dest (e_fallthru->dest, sb))
376 cond_block_type = NO_ELSE_BLOCK;
378 cond_block_type = ELSE_BLOCK;
380 if (get_common_dest (e_fallthru->dest, sb))
382 if (cond_block_type == THEN_BLOCK)
384 if (! (REORDER_BLOCK_FLAGS (e->dest)
385 & REORDER_BLOCK_VISITED))
386 cond_type = PREDICT_THEN_NO_ELSE;
388 cond_type = PREDICT_NOT_THEN_NO_ELSE;
390 else if (cond_block_type == NO_ELSE_BLOCK)
392 if (! (REORDER_BLOCK_FLAGS (e->dest)
393 & REORDER_BLOCK_VISITED))
394 cond_type = PREDICT_NOT_THEN_NO_ELSE;
396 cond_type = PREDICT_THEN_NO_ELSE;
401 if (cond_block_type == THEN_BLOCK)
403 if (! (REORDER_BLOCK_FLAGS (e->dest)
404 & REORDER_BLOCK_VISITED))
405 cond_type = PREDICT_THEN_WITH_ELSE;
407 cond_type = PREDICT_ELSE;
409 else if (cond_block_type == ELSE_BLOCK
410 && e_fallthru->dest != EXIT_BLOCK_PTR)
412 if (! (REORDER_BLOCK_FLAGS (e->dest)
413 & REORDER_BLOCK_VISITED))
414 cond_type = PREDICT_ELSE;
416 cond_type = PREDICT_THEN_WITH_ELSE;
423 static const char * cond_type_str [] = {"not cond jump", "predict then",
425 "predict then w/o else",
426 "predict not then w/o else"};
427 static const char * cond_block_type_str [] = {"not then or else block",
430 "then w/o else block"};
432 fprintf (rtl_dump_file, " %s (looking at %s)\n",
433 cond_type_str[(int)cond_type],
434 cond_block_type_str[(int)cond_block_type]);
437 /* Reflect that then block will move and we'll jump to it. */
438 if (cond_block_type != THEN_BLOCK
439 && (cond_type == PREDICT_ELSE
440 || cond_type == PREDICT_NOT_THEN_NO_ELSE))
443 fprintf (rtl_dump_file,
444 " then jump from block %d to block %d\n",
445 sb->index, e_fallthru->dest->index);
447 /* Jump to reordered then block. */
448 REORDER_BLOCK_ADD_JUMP (sb) = e_fallthru->dest;
451 /* Reflect that then block will jump back when we have no else. */
452 if (cond_block_type != THEN_BLOCK
453 && cond_type == PREDICT_NOT_THEN_NO_ELSE)
455 basic_block jbb = e_fallthru->dest;
457 ee && ! (ee->flags & EDGE_FALLTHRU);
461 if (ee && ! (GET_CODE (jbb->end) == JUMP_INSN
462 && ! simplejump_p (jbb->end)))
464 REORDER_BLOCK_ADD_JUMP (jbb) = ee->dest;
468 /* Reflect that else block will jump back. */
469 if (cond_block_type == ELSE_BLOCK
470 && (cond_type == PREDICT_THEN_WITH_ELSE || cond_type == PREDICT_ELSE))
475 && last_edge->dest != EXIT_BLOCK_PTR
476 && GET_CODE (last_edge->dest->head) == CODE_LABEL
477 && ! (GET_CODE (db->end) == JUMP_INSN))
480 fprintf (rtl_dump_file,
481 " else jump from block %d to block %d\n",
482 db->index, last_edge->dest->index);
484 REORDER_BLOCK_ADD_JUMP (db) = last_edge->dest;
488 /* This block's successor has already been reordered. This can happen
489 when we reorder a chain starting at a then or else. */
490 for (last_edge = db->succ;
491 last_edge && ! (last_edge->flags & EDGE_FALLTHRU);
492 last_edge = last_edge->succ_next)
496 && last_edge->dest != EXIT_BLOCK_PTR
497 && (REORDER_BLOCK_FLAGS (last_edge->dest)
498 & REORDER_BLOCK_VISITED))
501 fprintf (rtl_dump_file,
502 " end of chain jump from block %d to block %d\n",
503 db->index, last_edge->dest->index);
505 REORDER_BLOCK_ADD_JUMP (db) = last_edge->dest;
508 dbh_insn = REORDER_BLOCK_EFF_HEAD (db);
509 cebe_insn = REORDER_BLOCK_EFF_END (ceb);
510 dbe_insn = REORDER_BLOCK_EFF_END (db);
512 /* Rechain predicted block. */
513 NEXT_INSN (cebe_insn) = dbh_insn;
514 PREV_INSN (dbh_insn) = cebe_insn;
516 if (db->index != n_basic_blocks - 1)
517 NEXT_INSN (dbe_insn) = 0;
523 /* Reorder blocks starting at block BB. */
526 make_reorder_chain (bb)
530 basic_block visited_edge = NULL;
534 if (bb == EXIT_BLOCK_PTR)
537 /* Find the most probable block. */
540 if (GET_CODE (block_end) == JUMP_INSN && condjump_p (block_end))
542 rtx note = find_reg_note (block_end, REG_BR_PROB, 0);
545 probability = INTVAL (XEXP (note, 0));
549 if (probability >= REG_BR_PROB_BASE / 2)
550 e = bb->succ->succ_next;
553 /* Add chosen successor to chain and recurse on it. */
554 if (e && e->dest != EXIT_BLOCK_PTR
556 && (! (REORDER_BLOCK_FLAGS (e->dest) & REORDER_BLOCK_VISITED)
557 || (REORDER_BLOCK_FLAGS (e->dest) == REORDER_BLOCK_HEAD)))
559 if (! (REORDER_BLOCK_FLAGS (bb) & REORDER_BLOCK_VISITED))
561 REORDER_BLOCK_FLAGS (bb) |= REORDER_BLOCK_HEAD;
562 REORDER_BLOCK_INDEX (bb) = reorder_index++;
563 REORDER_BLOCK_FLAGS (bb) |= REORDER_BLOCK_VISITED;
566 if (REORDER_BLOCK_FLAGS (e->dest) & REORDER_BLOCK_VISITED)
567 REORDER_BLOCK_FLAGS (e->dest) &= ~REORDER_BLOCK_HEAD;
569 REORDER_BLOCK_SUCC (bb) = e;
571 visited_edge = e->dest;
573 reorder_last_visited = chain_reorder_blocks (e, bb);
576 && ! (REORDER_BLOCK_FLAGS (e->dest)
577 & REORDER_BLOCK_VISITED))
578 make_reorder_chain (e->dest);
582 if (! (REORDER_BLOCK_FLAGS (bb) & REORDER_BLOCK_VISITED))
584 REORDER_BLOCK_INDEX (bb) = reorder_index++;
585 REORDER_BLOCK_FLAGS (bb) |= REORDER_BLOCK_VISITED;
589 /* Recurse on the successors. */
590 for (e = bb->succ; e; e = e->succ_next)
592 if (e->dest && e->dest == EXIT_BLOCK_PTR)
597 && e->dest != visited_edge
598 && ! (REORDER_BLOCK_FLAGS (e->dest)
599 & REORDER_BLOCK_VISITED))
602 = chain_reorder_blocks (e, reorder_last_visited);
603 make_reorder_chain (e->dest);
609 /* Fixup jumps and labels after reordering basic blocks. */
612 fixup_reorder_chain ()
616 int orig_num_blocks = n_basic_blocks;
618 /* Set the new last insn. */
622 for (j = 0; j < n_basic_blocks; j++)
624 int val = REORDER_BLOCK_INDEX (BASIC_BLOCK (j));
631 insn = REORDER_BLOCK_EFF_END (BASIC_BLOCK (max_index));
632 NEXT_INSN (insn) = NULL_RTX;
633 set_last_insn (insn);
636 /* Add jumps and labels to fixup blocks. */
637 for (i = 0; i < orig_num_blocks; i++)
640 basic_block bbi = BASIC_BLOCK (i);
641 if (REORDER_BLOCK_ADD_JUMP (bbi))
643 rtx label_insn, jump_insn, barrier_insn;
645 if (GET_CODE (REORDER_BLOCK_ADD_JUMP (bbi)->head) == CODE_LABEL)
646 label_insn = REORDER_BLOCK_ADD_JUMP (bbi)->head;
649 rtx new_label = gen_label_rtx ();
650 label_insn = emit_label_before (new_label,
651 REORDER_BLOCK_ADD_JUMP (bbi)->head);
652 REORDER_BLOCK_ADD_JUMP (bbi)->head = label_insn;
655 if (GET_CODE (bbi->end) != JUMP_INSN)
657 jump_insn = emit_jump_insn_after (gen_jump (label_insn),
659 bbi->end = jump_insn;
664 jump_insn = emit_jump_insn_after (gen_jump (label_insn),
665 REORDER_BLOCK_EFF_END (bbi));
669 JUMP_LABEL (jump_insn) = label_insn;
670 ++LABEL_NUSES (label_insn);
671 barrier_insn = emit_barrier_after (jump_insn);
673 /* Add block for jump. Typically this is when a then is not
674 predicted and we are jumping to the moved then block. */
679 VARRAY_GROW (basic_block_info, ++n_basic_blocks);
680 create_basic_block (n_basic_blocks - 1, jump_insn,
682 nb = BASIC_BLOCK (n_basic_blocks - 1);
683 nb->global_live_at_start
684 = OBSTACK_ALLOC_REG_SET (function_obstack);
685 nb->global_live_at_end
686 = OBSTACK_ALLOC_REG_SET (function_obstack);
688 COPY_REG_SET (nb->global_live_at_start,
689 bbi->global_live_at_start);
690 COPY_REG_SET (nb->global_live_at_end,
691 bbi->global_live_at_start);
692 BASIC_BLOCK (nb->index)->local_set = 0;
694 nb->aux = xcalloc (1, sizeof (struct reorder_block_def));
695 REORDER_BLOCK_INDEX (nb) = REORDER_BLOCK_INDEX (bbi) + 1;
696 /* Relink to new block. */
697 nb->succ = bbi->succ;
700 make_edge (NULL, bbi, nb, 0);
702 = bbi->succ->succ_next->succ_next;
703 nb->succ->succ_next = 0;
704 /* Fix reorder block index to reflect new block. */
705 for (j = 0; j < n_basic_blocks - 1; j++)
707 basic_block bbj = BASIC_BLOCK (j);
708 if (REORDER_BLOCK_INDEX (bbj)
709 >= REORDER_BLOCK_INDEX (bbi) + 1)
710 REORDER_BLOCK_INDEX (bbj)++;
712 REORDER_BLOCK_SCOPE (nb) = REORDER_BLOCK_SCOPE (bbi);
713 REORDER_BLOCK_EFF_HEAD (nb) = nb->head;
714 REORDER_BLOCK_EFF_END (nb) = barrier_insn;
717 REORDER_BLOCK_EFF_END (bbi) = barrier_insn;
723 /* Perform sanity checks on the insn chain.
724 1. Check that next/prev pointers are consistent in both the forward and
726 2. Count insns in chain, going both directions, and check if equal.
727 3. Check that get_last_insn () returns the actual end of chain. */
728 #ifdef ENABLE_CHECKING
740 for (x = get_insns (); x; x = NEXT_INSN (x))
742 if (PREV_INSN (x) != prevx)
744 fprintf (stderr, "Forward traversal: insn chain corrupt.\n");
745 fprintf (stderr, "previous insn:\n");
747 fprintf (stderr, "current insn:\n");
755 if (prevx != get_last_insn ())
757 fprintf (stderr, "last_insn corrupt.\n");
763 for (x = get_last_insn (); x; x = PREV_INSN (x))
765 if (NEXT_INSN (x) != nextx)
767 fprintf (stderr, "Reverse traversal: insn chain corrupt.\n");
768 fprintf (stderr, "current insn:\n");
770 fprintf (stderr, "next insn:\n");
778 if (insn_cnt1 != insn_cnt2)
780 fprintf (stderr, "insn_cnt1 (%d) not equal to insn_cnt2 (%d).\n",
781 insn_cnt1, insn_cnt2);
793 if (GET_CODE (x) == NOTE
794 && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
808 if (GET_CODE (x) == NOTE
809 && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
817 /* Determine and record the relationships between basic blocks and
818 scopes in scope tree S. */
821 relate_bbs_with_scopes (s)
825 int i, bbi1, bbi2, bbs_spanned;
828 for (p = s->inner; p; p = p->next)
829 relate_bbs_with_scopes (p);
834 /* If the begin and end notes are both inside the same basic block,
835 or if they are both outside of basic blocks, then we know immediately
836 how they are related. Otherwise, we need to poke around to make the
838 if (s->bb_beg != s->bb_end)
840 if (s->bb_beg && s->bb_end)
842 /* Both notes are in different bbs. This implies that all the
843 basic blocks spanned by the pair of notes are contained in
845 bbi1 = s->bb_beg->index;
846 bbi2 = s->bb_end->index;
849 else if (! s->bb_beg)
851 /* First note is outside of a bb. If the scope spans more than
852 one basic block, then they all are contained within this
853 scope. Otherwise, this scope is contained within the basic
855 bbnote = get_next_bb_note (s->note_beg);
858 if (NOTE_BASIC_BLOCK (bbnote) == s->bb_end)
861 s->bb_beg = NOTE_BASIC_BLOCK (bbnote);
865 bbi1 = NOTE_BASIC_BLOCK (bbnote)->index;
866 bbi2 = s->bb_end->index;
871 else /* ! s->bb_end */
873 /* Second note is outside of a bb. If the scope spans more than
874 one basic block, then they all are contained within this
875 scope. Otherwise, this scope is contained within the basic
877 bbnote = get_prev_bb_note (s->note_end);
880 if (NOTE_BASIC_BLOCK (bbnote) == s->bb_beg)
883 s->bb_end = NOTE_BASIC_BLOCK (bbnote);
887 bbi1 = s->bb_beg->index;
888 bbi2 = NOTE_BASIC_BLOCK (bbnote)->index;
897 /* Both notes are in the same bb, which implies the block
898 contains this scope. */
903 /* Both notes are outside of any bbs. This implies that all the
904 basic blocks spanned by the pair of notes are contained in
906 There is a degenerate case to consider. If the notes do not
907 span any basic blocks, then it is an empty scope that can
908 safely be deleted or ignored. Mark these with level = -1. */
910 x1 = get_next_bb_note (s->note_beg);
911 x2 = get_prev_bb_note (s->note_end);
919 bbi1 = NOTE_BASIC_BLOCK (x1)->index;
920 bbi2 = NOTE_BASIC_BLOCK (x2)->index;
927 /* If the scope spans one or more basic blocks, we record them. We
928 only record the bbs that are immediately contained within this
929 scope. Note that if a scope is contained within a bb, we can tell
930 by checking that bb_beg = bb_end and that they are non-null. */
936 for (i = bbi1; i <= bbi2; i++)
937 if (! REORDER_BLOCK_SCOPE (BASIC_BLOCK (i)))
940 s->bbs = xcalloc (s->num_bbs, sizeof (struct basic_block_def));
941 for (i = bbi1; i <= bbi2; i++)
943 basic_block curr_bb = BASIC_BLOCK (i);
944 if (! REORDER_BLOCK_SCOPE (curr_bb))
946 s->bbs[j++] = curr_bb;
947 REORDER_BLOCK_SCOPE (curr_bb) = s;
956 /* Allocate and initialize a new scope structure with scope level LEVEL,
957 and record the NOTE beginning the scope. */
960 make_new_scope (level, note)
964 scope new_scope = xcalloc (1, sizeof (struct scope_def));
965 new_scope->level = level;
966 new_scope->note_beg = note;
967 new_scope->note_end = NULL;
968 new_scope->bb_beg = NULL;
969 new_scope->bb_end = NULL;
970 new_scope->inner = NULL;
971 new_scope->inner_last = NULL;
972 new_scope->outer = NULL;
973 new_scope->next = NULL;
974 new_scope->num_bbs = 0;
975 new_scope->bbs = NULL;
980 /* Build a forest representing the scope structure of the function.
981 Return a pointer to a structure describing the forest. */
984 build_scope_forest (forest)
985 scope_forest_info *forest;
990 scope root, curr_scope;
992 forest->num_trees = 0;
993 forest->trees = NULL;
998 for (x = get_insns (); x; x = NEXT_INSN (x))
1000 if (bbi < n_basic_blocks && x == BASIC_BLOCK (bbi)->head)
1001 curr_bb = BASIC_BLOCK (bbi);
1003 if (GET_CODE (x) == NOTE)
1005 if (NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_BEG)
1013 new_scope = make_new_scope (level, x);
1014 new_scope->outer = curr_scope;
1015 new_scope->next = NULL;
1016 if (! curr_scope->inner)
1018 curr_scope->inner = new_scope;
1019 curr_scope->inner_last = new_scope;
1023 curr_scope->inner_last->next = new_scope;
1024 curr_scope->inner_last = new_scope;
1026 curr_scope = curr_scope->inner_last;
1030 int ntrees = forest->num_trees;
1032 curr_scope = make_new_scope (level, x);
1035 forest->trees = xcalloc (1, sizeof (scope));
1037 forest->trees = xrealloc (forest->trees,
1038 sizeof (scope) * (ntrees + 1));
1039 forest->trees[forest->num_trees++] = root;
1041 curr_scope->bb_beg = curr_bb;
1043 else if (NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_END)
1045 curr_scope->bb_end = curr_bb;
1046 curr_scope->note_end = x;
1048 curr_scope = curr_scope->outer;
1054 if (curr_bb && curr_bb->end == x)
1062 for (i = 0; i < forest->num_trees; i++)
1063 relate_bbs_with_scopes (forest->trees[i]);
1067 /* Remove all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes from
1071 remove_scope_notes ()
1074 basic_block currbb = NULL;
1076 for (x = get_insns (); x; x = next)
1078 next = NEXT_INSN (x);
1079 if (GET_CODE (x) == NOTE
1080 && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
1081 currbb = NOTE_BASIC_BLOCK (x);
1083 if (GET_CODE (x) == NOTE
1084 && (NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_BEG
1085 || NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_END))
1087 /* Check if the scope note happens to be the end of a bb. */
1088 if (currbb && x == currbb->end)
1089 currbb->end = PREV_INSN (x);
1090 if (currbb && x == currbb->head)
1095 NEXT_INSN (PREV_INSN (x)) = next;
1096 PREV_INSN (next) = PREV_INSN (x);
1098 NEXT_INSN (x) = NULL;
1099 PREV_INSN (x) = NULL;
1108 /* Insert scope note pairs for a contained scope tree S after insn IP. */
1110 insert_intra_1 (s, ip)
1116 if (NOTE_BLOCK (s->note_beg))
1118 *ip = emit_note_after (NOTE_INSN_BLOCK_BEG, *ip);
1119 NOTE_BLOCK (*ip) = NOTE_BLOCK (s->note_beg);
1122 for (p = s->inner; p; p = p->next)
1123 insert_intra_1 (p, ip);
1125 if (NOTE_BLOCK (s->note_beg))
1127 *ip = emit_note_after (NOTE_INSN_BLOCK_END, *ip);
1128 NOTE_BLOCK (*ip) = NOTE_BLOCK (s->note_end);
1133 /* Insert NOTE_INSN_BLOCK_END notes and NOTE_INSN_BLOCK_BEG notes for
1134 scopes that are contained within BB. */
1137 insert_intra_bb_scope_notes (bb)
1140 scope s = REORDER_BLOCK_SCOPE (bb);
1148 if (GET_CODE (ip) == CODE_LABEL)
1149 ip = NEXT_INSN (ip);
1151 for (p = s->inner; p; p = p->next)
1153 if (p->bb_beg != NULL && p->bb_beg == p->bb_end && p->bb_beg == bb)
1154 insert_intra_1 (p, &ip);
1159 /* Given two consecutive basic blocks BB1 and BB2 with different scopes,
1160 insert NOTE_INSN_BLOCK_END notes after BB1 and NOTE_INSN_BLOCK_BEG
1161 notes before BB2 such that the notes are correctly balanced. If BB1 or
1162 BB2 is NULL, we are inserting scope notes for the first and last basic
1163 blocks, respectively. */
1166 insert_inter_bb_scope_notes (bb1, bb2)
1173 /* It is possible that a basic block is not contained in any scope.
1174 In that case, we either open or close a scope but not both. */
1177 scope s1 = REORDER_BLOCK_SCOPE (bb1);
1178 scope s2 = REORDER_BLOCK_SCOPE (bb2);
1187 /* Find common ancestor scope. */
1190 scope s1 = REORDER_BLOCK_SCOPE (bb1);
1191 scope s2 = REORDER_BLOCK_SCOPE (bb2);
1196 if (s1->level > s2->level)
1198 else if (s2->level > s1->level)
1214 scope s = REORDER_BLOCK_SCOPE (bb1);
1215 ip = REORDER_BLOCK_EFF_END (bb1);
1218 if (NOTE_BLOCK (s->note_beg))
1220 ip = emit_note_after (NOTE_INSN_BLOCK_END, ip);
1221 NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_end);
1230 scope s = REORDER_BLOCK_SCOPE (bb2);
1234 if (NOTE_BLOCK (s->note_beg))
1236 ip = emit_note_before (NOTE_INSN_BLOCK_BEG, ip);
1237 NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_beg);
1245 /* Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based
1246 on the scope forest and the newly reordered basic blocks. */
1249 rebuild_scope_notes (forest)
1250 scope_forest_info *forest;
1254 if (forest->num_trees == 0)
1257 /* Start by opening the scopes before the first basic block. */
1258 insert_inter_bb_scope_notes (NULL, BASIC_BLOCK (0));
1260 /* Then, open and close scopes as needed between blocks. */
1261 for (i = 0; i < n_basic_blocks - 1; i++)
1263 basic_block bb1 = BASIC_BLOCK (i);
1264 basic_block bb2 = BASIC_BLOCK (i + 1);
1265 if (REORDER_BLOCK_SCOPE (bb1) != REORDER_BLOCK_SCOPE (bb2))
1266 insert_inter_bb_scope_notes (bb1, bb2);
1267 insert_intra_bb_scope_notes (bb1);
1270 /* Finally, close the scopes after the last basic block. */
1271 insert_inter_bb_scope_notes (BASIC_BLOCK (n_basic_blocks - 1), NULL);
1272 insert_intra_bb_scope_notes (BASIC_BLOCK (n_basic_blocks - 1));
1276 /* Free the storage associated with the scope tree at S. */
1279 free_scope_forest_1 (s)
1284 for (p = s->inner; p; p = next)
1287 free_scope_forest_1 (p);
1296 /* Free the storage associated with the scope forest. */
1299 free_scope_forest (forest)
1300 scope_forest_info *forest;
1303 for (i = 0; i < forest->num_trees; i++)
1304 free_scope_forest_1 (forest->trees[i]);
1308 /* Visualize the scope forest. */
1311 dump_scope_forest (forest)
1312 scope_forest_info *forest;
1314 if (forest->num_trees == 0)
1315 fprintf (stderr, "\n< Empty scope forest >\n");
1319 fprintf (stderr, "\n< Scope forest >\n");
1320 for (i = 0; i < forest->num_trees; i++)
1321 dump_scope_forest_1 (forest->trees[i], 0);
1326 /* Recursive portion of dump_scope_forest. */
1329 dump_scope_forest_1 (s, indent)
1336 if (s->bb_beg != NULL && s->bb_beg == s->bb_end
1337 && REORDER_BLOCK_SCOPE (s->bb_beg)
1338 && REORDER_BLOCK_SCOPE (s->bb_beg)->level + 1 == s->level)
1340 fprintf (stderr, "%*s", indent, "");
1341 fprintf (stderr, "BB%d:\n", s->bb_beg->index);
1344 fprintf (stderr, "%*s", indent, "");
1345 fprintf (stderr, "{ level %d (block %p)\n", s->level,
1346 NOTE_BLOCK (s->note_beg));
1348 fprintf (stderr, "%*s%s", indent, "", "bbs:");
1349 for (i = 0; i < s->num_bbs; i++)
1350 fprintf (stderr, " %d", s->bbs[i]->index);
1351 fprintf (stderr, "\n");
1353 for (p = s->inner; p; p = p->next)
1354 dump_scope_forest_1 (p, indent + 2);
1356 fprintf (stderr, "%*s", indent, "");
1357 fprintf (stderr, "}\n");
1361 /* Reorder basic blocks. */
1364 reorder_basic_blocks ()
1367 struct loops loops_info;
1369 scope_forest_info forest;
1371 if (profile_arc_flag)
1374 if (n_basic_blocks <= 1)
1377 /* Exception edges are not currently handled. */
1378 for (i = 0; i < n_basic_blocks; i++)
1382 for (e = BASIC_BLOCK (i)->succ; e && ! (e->flags & EDGE_EH);
1386 if (e && (e->flags & EDGE_EH))
1392 /* Find natural loops using the CFG. */
1393 num_loops = flow_loops_find (&loops_info);
1395 /* Dump loop information. */
1396 flow_loops_dump (&loops_info, rtl_dump_file, 0);
1398 reorder_last_visited = BASIC_BLOCK (0);
1400 for (i = 0; i < n_basic_blocks; i++)
1402 basic_block bbi = BASIC_BLOCK (i);
1403 bbi->aux = xcalloc (1, sizeof (struct reorder_block_def));
1404 *((struct reorder_block_def *)bbi->aux) = rbd_init;
1407 build_scope_forest (&forest);
1408 remove_scope_notes ();
1410 for (i = 0; i < n_basic_blocks; i++)
1412 basic_block bbi = BASIC_BLOCK (i);
1413 REORDER_BLOCK_EFF_END (bbi)
1414 = skip_insns_between_block (bbi, REORDER_SKIP_AFTER);
1416 REORDER_BLOCK_EFF_HEAD (bbi) = get_insns ();
1419 rtx prev_eff_end = REORDER_BLOCK_EFF_END (BASIC_BLOCK (i - 1));
1420 REORDER_BLOCK_EFF_HEAD (bbi) = NEXT_INSN (prev_eff_end);
1424 /* If we've not got epilogue in RTL, we must fallthru to the exit.
1425 Force the last block to be at the end. */
1426 /* ??? Some ABIs (e.g. MIPS) require the return insn to be at the
1427 end of the function for stack unwinding purposes. */
1429 #ifndef HAVE_epilogue
1430 #define HAVE_epilogue 0
1433 if (! HAVE_epilogue)
1435 basic_block last = BASIC_BLOCK (n_basic_blocks - 1);
1436 REORDER_BLOCK_INDEX (last) = n_basic_blocks - 1;
1437 REORDER_BLOCK_FLAGS (last) |= REORDER_BLOCK_VISITED;
1440 make_reorder_chain (BASIC_BLOCK (0));
1442 fixup_reorder_chain ();
1444 #ifdef ENABLE_CHECKING
1445 verify_insn_chain ();
1448 /* Put basic_block_info in new order. */
1449 for (i = 0; i < n_basic_blocks - 1; i++)
1451 for (j = i; i != REORDER_BLOCK_INDEX (BASIC_BLOCK (j)); j++)
1454 if (REORDER_BLOCK_INDEX (BASIC_BLOCK (j)) == i
1459 int rbi = REORDER_BLOCK_INDEX (BASIC_BLOCK (j));
1461 temprbi = BASIC_BLOCK (rbi)->index;
1462 BASIC_BLOCK (rbi)->index = BASIC_BLOCK (j)->index;
1463 BASIC_BLOCK (j)->index = temprbi;
1464 tempbb = BASIC_BLOCK (rbi);
1465 BASIC_BLOCK (rbi) = BASIC_BLOCK (j);
1466 BASIC_BLOCK (j) = tempbb;
1470 rebuild_scope_notes (&forest);
1471 free_scope_forest (&forest);
1474 #ifdef ENABLE_CHECKING
1475 verify_flow_info ();
1478 for (i = 0; i < n_basic_blocks; i++)
1479 free (BASIC_BLOCK (i)->aux);
1481 /* Free loop information. */
1482 flow_loops_free (&loops_info);