Use new tail-calling mechanism on ARM.
[official-gcc.git] / gcc / bb-reorder.c
blobc0c808a7636a60090b3c205f598f4a1a48c94924
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)
9 any later version.
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. */
21 /* References:
23 "Profile Guided Code Positioning"
24 Pettis and Hanson; PLDI '90.
27 #include "config.h"
28 #include "system.h"
29 #include "tree.h"
30 #include "rtl.h"
31 #include "tm_p.h"
32 #include "basic-block.h"
33 #include "insn-config.h"
34 #include "regs.h"
35 #include "hard-reg-set.h"
36 #include "flags.h"
37 #include "output.h"
38 #include "function.h"
39 #include "except.h"
40 #include "toplev.h"
41 #include "recog.h"
42 #include "insn-flags.h"
43 #include "expr.h"
44 #include "obstack.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
58 int level;
60 /* The NOTE_INSN_BLOCK_BEG that started this scope. */
61 rtx note_beg;
63 /* The NOTE_INSN_BLOCK_END that ended this scope. */
64 rtx note_end;
66 /* The bb containing note_beg (if any). */
67 basic_block bb_beg;
69 /* The bb containing note_end (if any). */
70 basic_block bb_end;
72 /* List of basic blocks contained within this scope. */
73 basic_block *bbs;
75 /* Number of blocks contained within this scope. */
76 int num_bbs;
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;
89 } *scope;
91 /* Structure to hold information about the scope forest. */
92 typedef struct
94 /* Number of trees in forest. */
95 int num_trees;
97 /* List of tree roots. */
98 scope *trees;
99 } scope_forest_info;
102 typedef struct reorder_block_def {
103 int flags;
104 int index;
105 basic_block add_jump;
106 rtx eff_head;
107 rtx eff_end;
108 scope scope;
109 } *reorder_block_def;
111 static struct reorder_block_def rbd_init
113 0, /* flags */
114 0, /* index */
115 NULL, /* add_jump */
116 NULL_RTX, /* eff_head */
117 NULL_RTX, /* eff_end */
118 NULL /* scope */
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));
156 #endif
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. */
176 static rtx
177 skip_insns_after_block (bb)
178 basic_block bb;
180 rtx insn, last_insn;
182 last_insn = bb->end;
184 if (bb == EXIT_BLOCK_PTR)
185 return 0;
187 for (insn = NEXT_INSN (bb->end);
188 insn;
189 last_insn = insn, insn = NEXT_INSN (insn))
191 if (bb->index + 1 != n_basic_blocks
192 && insn == BASIC_BLOCK (bb->index + 1)->head)
193 break;
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)))
200 continue;
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);
208 continue;
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))
215 continue;
217 break;
220 return last_insn;
224 /* Return common destination for blocks BB0 and BB1. */
226 static basic_block
227 get_common_dest (bb0, bb1)
228 basic_block bb0, bb1;
230 edge e0, e1;
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)
238 return e0->dest;
242 return 0;
246 /* Move the destination block for edge E after chain end block CEB
247 Adding jumps and labels is deferred until fixup_reorder_chain. */
249 static basic_block
250 chain_reorder_blocks (e, ceb)
251 edge e;
252 basic_block ceb;
254 basic_block sb = e->src;
255 basic_block db = e->dest;
256 rtx cebe_insn, dbh_insn, dbe_insn;
257 edge ee, last_edge;
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,
264 NO_ELSE_BLOCK};
265 enum cond_block_types cond_block_type;
267 if (rtl_dump_file)
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))
276 return db;
278 e_fallthru = e_jump = e;
280 /* Get the type of block and type of condition. */
281 cond_type = NO_COND;
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)
288 if (e == sb->succ)
289 e_jump = sb->succ->succ_next;
290 else if (e == sb->succ->succ_next)
291 e_jump = sb->succ;
292 else
293 abort ();
295 else
297 if (e == sb->succ)
298 e_fallthru = sb->succ->succ_next;
299 else if (e == sb->succ->succ_next)
300 e_fallthru = sb->succ;
301 else
302 abort ();
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;
309 else
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;
319 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;
327 else
328 cond_type = PREDICT_THEN_NO_ELSE;
331 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;
338 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;
347 else
348 cond_type = PREDICT_THEN_WITH_ELSE;
353 if (rtl_dump_file)
355 static const char * cond_type_str [] = {"not cond jump", "predict then",
356 "predict else",
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",
360 "then block",
361 "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))
374 if (rtl_dump_file)
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;
388 for (ee = jbb->succ;
389 ee && ! (ee->flags & EDGE_FALLTHRU);
390 ee = ee->succ_next)
391 continue;
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))
404 last_edge=db->succ;
406 if (last_edge
407 && last_edge->dest != EXIT_BLOCK_PTR
408 && GET_CODE (last_edge->dest->head) == CODE_LABEL
409 && ! (GET_CODE (db->end) == JUMP_INSN))
411 if (rtl_dump_file)
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)
425 continue;
427 if (last_edge
428 && last_edge->dest != EXIT_BLOCK_PTR
429 && (REORDER_BLOCK_FLAGS (last_edge->dest)
430 & REORDER_BLOCK_VISITED))
432 if (rtl_dump_file)
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;
451 return db;
455 /* Reorder blocks starting at block BB. */
457 static void
458 make_reorder_chain (bb)
459 basic_block bb;
461 edge e;
462 basic_block visited_edge = NULL;
463 rtx block_end;
464 int probability;
466 if (bb == EXIT_BLOCK_PTR)
467 return;
469 /* Find the most probable block. */
470 e = bb->succ;
471 block_end = bb->end;
472 if (GET_CODE (block_end) == JUMP_INSN && condjump_p (block_end))
474 rtx note = find_reg_note (block_end, REG_BR_PROB, 0);
476 if (note)
477 probability = INTVAL (XEXP (note, 0));
478 else
479 probability = 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
487 && e->dest != e->src
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);
505 if (e->dest
506 && ! (REORDER_BLOCK_FLAGS (e->dest)
507 & REORDER_BLOCK_VISITED))
508 make_reorder_chain (e->dest);
510 else
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)
523 continue;
525 if (e->dest
526 && e->dest != e->src
527 && e->dest != visited_edge
528 && ! (REORDER_BLOCK_FLAGS (e->dest)
529 & REORDER_BLOCK_VISITED))
531 reorder_last_visited
532 = chain_reorder_blocks (e, reorder_last_visited);
533 make_reorder_chain (e->dest);
539 /* Fixup jumps and labels after reordering basic blocks. */
541 static void
542 fixup_reorder_chain ()
544 int i, j;
545 rtx insn;
546 int orig_num_blocks = n_basic_blocks;
548 /* Set the new last insn. */
550 int max_val = 0;
551 int max_index = 0;
552 for (j = 0; j < n_basic_blocks; j++)
554 int val = REORDER_BLOCK_INDEX (BASIC_BLOCK (j));
555 if (val > max_val)
557 max_val = val;
558 max_index = 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++)
569 int need_block = 0;
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;
577 else
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),
588 bbi->end);
589 bbi->end = jump_insn;
590 need_block = 0;
592 else
594 jump_insn = emit_jump_insn_after (gen_jump (label_insn),
595 REORDER_BLOCK_EFF_END (bbi));
596 need_block = 1;
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. */
605 if (need_block)
607 basic_block nb;
609 VARRAY_GROW (basic_block_info, ++n_basic_blocks);
610 create_basic_block (n_basic_blocks - 1, jump_insn,
611 jump_insn, NULL);
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;
628 nb->succ->src = nb;
630 make_edge (NULL, bbi, nb, 0);
631 bbi->succ->succ_next
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;
646 else
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
655 reverse direction.
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
659 static void
660 verify_insn_chain ()
662 rtx x,
663 prevx,
664 nextx;
665 int insn_cnt1,
666 insn_cnt2;
668 prevx = NULL;
669 insn_cnt1 = 1;
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");
676 debug_rtx (prevx);
677 fprintf (stderr, "current insn:\n");
678 debug_rtx (x);
679 abort ();
681 ++insn_cnt1;
682 prevx = x;
685 if (prevx != get_last_insn ())
687 fprintf (stderr, "last_insn corrupt.\n");
688 abort ();
691 nextx = NULL;
692 insn_cnt2 = 1;
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");
699 debug_rtx (x);
700 fprintf (stderr, "next insn:\n");
701 debug_rtx (nextx);
702 abort ();
704 ++insn_cnt2;
705 nextx = x;
708 if (insn_cnt1 != insn_cnt2)
710 fprintf (stderr, "insn_cnt1 (%d) not equal to insn_cnt2 (%d).\n",
711 insn_cnt1, insn_cnt2);
712 abort ();
715 #endif
717 static rtx
718 get_next_bb_note (x)
719 rtx x;
721 while (x)
723 if (GET_CODE (x) == NOTE
724 && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
725 return x;
726 x = NEXT_INSN (x);
728 return NULL;
732 static rtx
733 get_prev_bb_note (x)
734 rtx x;
736 while (x)
738 if (GET_CODE (x) == NOTE
739 && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
740 return x;
741 x = PREV_INSN (x);
743 return NULL;
747 /* Determine and record the relationships between basic blocks and
748 scopes in scope tree S. */
750 static void
751 relate_bbs_with_scopes (s)
752 scope s;
754 scope p;
755 int i, bbi1, bbi2, bbs_spanned;
756 rtx bbnote;
758 for (p = s->inner; p; p = p->next)
759 relate_bbs_with_scopes (p);
761 bbi1 = bbi2 = -1;
762 bbs_spanned = 0;
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
767 determination. */
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
774 this scope. */
775 bbi1 = s->bb_beg->index;
776 bbi2 = s->bb_end->index;
777 bbs_spanned = 1;
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
784 block. */
785 bbnote = get_next_bb_note (s->note_beg);
786 if (! bbnote)
787 abort ();
788 if (NOTE_BASIC_BLOCK (bbnote) == s->bb_end)
790 bbs_spanned = 0;
791 s->bb_beg = NOTE_BASIC_BLOCK (bbnote);
793 else
795 bbi1 = NOTE_BASIC_BLOCK (bbnote)->index;
796 bbi2 = s->bb_end->index;
797 s->bb_end = NULL;
798 bbs_spanned = 1;
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
806 block. */
807 bbnote = get_prev_bb_note (s->note_end);
808 if (! bbnote)
809 abort ();
810 if (NOTE_BASIC_BLOCK (bbnote) == s->bb_beg)
812 bbs_spanned = 0;
813 s->bb_end = NOTE_BASIC_BLOCK (bbnote);
815 else
817 bbi1 = s->bb_beg->index;
818 bbi2 = NOTE_BASIC_BLOCK (bbnote)->index;
819 s->bb_beg = NULL;
820 bbs_spanned = 1;
824 else
826 if (s->bb_beg)
827 /* Both notes are in the same bb, which implies the block
828 contains this scope. */
829 bbs_spanned = 0;
830 else
832 rtx x1, x2;
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
835 this scope.
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);
842 if (! (x1 && x2))
844 s->level = -1;
845 bbs_spanned = 0;
847 else
849 bbi1 = NOTE_BASIC_BLOCK (x1)->index;
850 bbi2 = NOTE_BASIC_BLOCK (x2)->index;
851 bbs_spanned = 1;
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. */
861 if (bbs_spanned)
863 int j = 0;
865 s->num_bbs = 0;
866 for (i = bbi1; i <= bbi2; i++)
867 if (! REORDER_BLOCK_SCOPE (BASIC_BLOCK (i)))
868 s->num_bbs++;
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;
881 else
882 s->num_bbs = 0;
886 /* Allocate and initialize a new scope structure with scope level LEVEL,
887 and record the NOTE beginning the scope. */
889 static scope
890 make_new_scope (level, note)
891 int level;
892 rtx 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;
906 return new_scope;
910 /* Build a forest representing the scope structure of the function.
911 Return a pointer to a structure describing the forest. */
913 static void
914 build_scope_forest (forest)
915 scope_forest_info *forest;
917 rtx x;
918 int level, bbi, i;
919 basic_block curr_bb;
920 scope root, curr_scope;
922 forest->num_trees = 0;
923 forest->trees = NULL;
924 level = -1;
925 root = NULL;
926 curr_bb = NULL;
927 bbi = 0;
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)
937 if (root)
939 scope new_scope;
940 if (! curr_scope)
941 abort();
942 level++;
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;
951 else
953 curr_scope->inner_last->next = new_scope;
954 curr_scope->inner_last = new_scope;
956 curr_scope = curr_scope->inner_last;
958 else
960 int ntrees = forest->num_trees;
961 level++;
962 curr_scope = make_new_scope (level, x);
963 root = curr_scope;
964 if (ntrees == 0)
965 forest->trees = xcalloc (1, sizeof (scope));
966 else
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;
977 level--;
978 curr_scope = curr_scope->outer;
979 if (level == -1)
980 root = NULL;
982 } /* if note */
984 if (curr_bb && curr_bb->end == x)
986 curr_bb = NULL;
987 bbi++;
990 } /* for */
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
998 the insn chain. */
1000 static void
1001 remove_scope_notes ()
1003 rtx x, next;
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)
1021 abort ();
1023 if (PREV_INSN (x))
1025 NEXT_INSN (PREV_INSN (x)) = next;
1026 PREV_INSN (next) = PREV_INSN (x);
1028 NEXT_INSN (x) = NULL;
1029 PREV_INSN (x) = NULL;
1031 else
1032 abort ();
1038 /* Insert scope note pairs for a contained scope tree S after insn IP. */
1039 static void
1040 insert_intra_1 (s, ip)
1041 scope s;
1042 rtx *ip;
1044 scope p;
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. */
1066 static void
1067 insert_intra_bb_scope_notes (bb)
1068 basic_block bb;
1070 scope s = REORDER_BLOCK_SCOPE (bb);
1071 scope p;
1072 rtx ip;
1074 if (! s)
1075 return;
1077 ip = bb->head;
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. */
1095 static void
1096 insert_inter_bb_scope_notes (bb1, bb2)
1097 basic_block bb1;
1098 basic_block bb2;
1100 rtx ip;
1101 scope com;
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. */
1105 if (bb1 && bb2)
1107 scope s1 = REORDER_BLOCK_SCOPE (bb1);
1108 scope s2 = REORDER_BLOCK_SCOPE (bb2);
1109 if (! s1 && ! s2)
1110 return;
1111 if (! s1)
1112 bb1 = NULL;
1113 else if (! s2)
1114 bb2 = NULL;
1117 /* Find common ancestor scope. */
1118 if (bb1 && bb2)
1120 scope s1 = REORDER_BLOCK_SCOPE (bb1);
1121 scope s2 = REORDER_BLOCK_SCOPE (bb2);
1122 while (s1 != s2)
1124 if (! (s1 && s2))
1125 abort ();
1126 if (s1->level > s2->level)
1127 s1 = s1->outer;
1128 else if (s2->level > s1->level)
1129 s2 = s2->outer;
1130 else
1132 s1 = s1->outer;
1133 s2 = s2->outer;
1136 com = s1;
1138 else
1139 com = NULL;
1141 /* Close scopes. */
1142 if (bb1)
1144 scope s = REORDER_BLOCK_SCOPE (bb1);
1145 ip = REORDER_BLOCK_EFF_END (bb1);
1146 while (s != com)
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);
1153 s = s->outer;
1157 /* Open scopes. */
1158 if (bb2)
1160 scope s = REORDER_BLOCK_SCOPE (bb2);
1161 ip = bb2->head;
1162 while (s != com)
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);
1169 s = s->outer;
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. */
1178 static void
1179 rebuild_scope_notes (forest)
1180 scope_forest_info *forest;
1182 int i;
1184 if (forest->num_trees == 0)
1185 return;
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. */
1208 static void
1209 free_scope_forest_1 (s)
1210 scope s;
1212 scope p, next;
1214 for (p = s->inner; p; p = next)
1216 next = p->next;
1217 free_scope_forest_1 (p);
1220 if (s->bbs)
1221 free (s->bbs);
1222 free (s);
1226 /* Free the storage associated with the scope forest. */
1228 static void
1229 free_scope_forest (forest)
1230 scope_forest_info *forest;
1232 int i;
1233 for (i = 0; i < forest->num_trees; i++)
1234 free_scope_forest_1 (forest->trees[i]);
1238 /* Visualize the scope forest. */
1240 void
1241 dump_scope_forest (forest)
1242 scope_forest_info *forest;
1244 if (forest->num_trees == 0)
1245 fprintf (stderr, "\n< Empty scope forest >\n");
1246 else
1248 int i;
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. */
1258 static void
1259 dump_scope_forest_1 (s, indent)
1260 scope s;
1261 int indent;
1263 scope p;
1264 int i;
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. */
1293 void
1294 reorder_basic_blocks ()
1296 int i, j;
1297 struct loops loops_info;
1298 int num_loops;
1299 scope_forest_info forest;
1301 if (profile_arc_flag)
1302 return;
1304 if (n_basic_blocks <= 1)
1305 return;
1307 /* Exception edges are not currently handled. */
1308 for (i = 0; i < n_basic_blocks; i++)
1310 edge e;
1312 for (e = BASIC_BLOCK (i)->succ; e && ! (e->flags & EDGE_EH);
1313 e = e->succ_next)
1314 continue;
1316 if (e && (e->flags & EDGE_EH))
1317 return;
1320 reorder_index = 0;
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);
1344 if (i == 0)
1345 REORDER_BLOCK_EFF_HEAD (bbi) = get_insns ();
1346 else
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
1360 #endif
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 ();
1375 #endif
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++)
1381 continue;
1383 if (REORDER_BLOCK_INDEX (BASIC_BLOCK (j)) == i
1384 && i != j)
1386 basic_block tempbb;
1387 int temprbi;
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);
1401 reorder_blocks ();
1403 #ifdef ENABLE_CHECKING
1404 verify_flow_info ();
1405 #endif
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);