bb-reorder.c (struct reorder_block_def): Remove members end, block_begin, and block_end.
[gcc.git] / gcc / bb-reorder.c
1 /* Basic block reordering routines for the GNU compiler.
2 Copyright (C) 2000 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
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.
10
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.
15
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. */
20
21 /* References:
22
23 "Profile Guided Code Positioning"
24 Pettis and Hanson; PLDI '90.
25 */
26
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"
45
46
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. */
51
52 extern struct obstack *function_obstack;
53
54
55 /* Structure to hold information about lexical scopes. */
56 typedef struct scope_def
57 {
58 int level;
59
60 /* The NOTE_INSN_BLOCK_BEG that started this scope. */
61 rtx note_beg;
62
63 /* The NOTE_INSN_BLOCK_END that ended this scope. */
64 rtx note_end;
65
66 /* The bb containing note_beg (if any). */
67 basic_block bb_beg;
68
69 /* The bb containing note_end (if any). */
70 basic_block bb_end;
71
72 /* List of basic blocks contained within this scope. */
73 basic_block *bbs;
74
75 /* Number of blocks contained within this scope. */
76 int num_bbs;
77
78 /* The outer scope or NULL if outermost scope. */
79 struct scope_def *outer;
80
81 /* The first inner scope or NULL if innermost scope. */
82 struct scope_def *inner;
83
84 /* The last inner scope or NULL if innermost scope. */
85 struct scope_def *inner_last;
86
87 /* Link to the next (sibling) scope. */
88 struct scope_def *next;
89 } *scope;
90
91 /* Structure to hold information about the scope forest. */
92 typedef struct
93 {
94 /* Number of trees in forest. */
95 int num_trees;
96
97 /* List of tree roots. */
98 scope *trees;
99 } scope_forest_info;
100
101
102 typedef struct reorder_block_def {
103 int flags;
104 int index;
105 basic_block add_jump;
106 edge succ;
107 rtx eff_head;
108 rtx eff_end;
109 scope scope;
110 } *reorder_block_def;
111
112 static struct reorder_block_def rbd_init
113 = {
114 0, /* flags */
115 0, /* index */
116 NULL, /* add_jump */
117 NULL, /* succ */
118 NULL_RTX, /* eff_head */
119 NULL_RTX, /* eff_end */
120 NULL /* scope */
121 };
122
123
124 #define REORDER_BLOCK_HEAD 0x1
125 #define REORDER_BLOCK_VISITED 0x2
126
127 #define REORDER_BLOCK_FLAGS(bb) \
128 ((reorder_block_def) (bb)->aux)->flags
129
130 #define REORDER_BLOCK_INDEX(bb) \
131 ((reorder_block_def) (bb)->aux)->index
132
133 #define REORDER_BLOCK_ADD_JUMP(bb) \
134 ((reorder_block_def) (bb)->aux)->add_jump
135
136 #define REORDER_BLOCK_SUCC(bb) \
137 ((reorder_block_def) (bb)->aux)->succ
138
139 #define REORDER_BLOCK_EFF_HEAD(bb) \
140 ((reorder_block_def) (bb)->aux)->eff_head
141
142 #define REORDER_BLOCK_EFF_END(bb) \
143 ((reorder_block_def) (bb)->aux)->eff_end
144
145 #define REORDER_BLOCK_SCOPE(bb) \
146 ((reorder_block_def) (bb)->aux)->scope
147
148
149 static int reorder_index;
150 static basic_block reorder_last_visited;
151
152 enum reorder_skip_type {REORDER_SKIP_BEFORE, REORDER_SKIP_AFTER,
153 REORDER_SKIP_BLOCK_END};
154
155
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));
165 #endif
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));
178
179 /* Skip over insns BEFORE or AFTER BB which are typically associated with
180 basic block BB. */
181
182 static rtx
183 skip_insns_between_block (bb, skip_type)
184 basic_block bb;
185 enum reorder_skip_type skip_type;
186 {
187 rtx insn, last_insn;
188
189 if (skip_type == REORDER_SKIP_BEFORE)
190 {
191 if (bb == ENTRY_BLOCK_PTR)
192 return 0;
193
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))
198 {
199 if (NEXT_INSN (insn) != last_insn)
200 break;
201
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)
206 continue;
207
208 break;
209 }
210 }
211 else
212 {
213 last_insn = bb->end;
214
215 if (bb == EXIT_BLOCK_PTR)
216 return 0;
217
218 for (insn = NEXT_INSN (bb->end);
219 insn;
220 last_insn = insn, insn = NEXT_INSN (insn))
221 {
222 if (bb->index + 1 != n_basic_blocks
223 && insn == BASIC_BLOCK (bb->index + 1)->head)
224 break;
225
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)))
231 continue;
232
233 if (GET_CODE (insn) == CODE_LABEL
234 && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
235 && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
236 || GET_CODE (PATTERN
237 (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
238 {
239 insn = NEXT_INSN (insn);
240 continue;
241 }
242
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))
247 continue;
248
249 break;
250 }
251
252 if (skip_type == REORDER_SKIP_BLOCK_END)
253 {
254 int found_block_end = 0;
255
256 for (; insn; last_insn = insn, insn = NEXT_INSN (insn))
257 {
258 if (bb->index + 1 != n_basic_blocks
259 && insn == BASIC_BLOCK (bb->index + 1)->head)
260 break;
261
262 if (GET_CODE (insn) == NOTE
263 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
264 {
265 found_block_end = 1;
266 continue;
267 }
268
269 if (GET_CODE (insn) == NOTE
270 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
271 continue;
272
273 if (GET_CODE (insn) == NOTE
274 && NOTE_LINE_NUMBER (insn) >= 0
275 && NEXT_INSN (insn)
276 && GET_CODE (NEXT_INSN (insn)) == NOTE
277 && (NOTE_LINE_NUMBER (NEXT_INSN (insn))
278 == NOTE_INSN_BLOCK_END))
279 continue;
280 break;
281 }
282
283 if (! found_block_end)
284 last_insn = 0;
285 }
286 }
287
288 return last_insn;
289 }
290
291
292 /* Return common destination for blocks BB0 and BB1. */
293
294 static basic_block
295 get_common_dest (bb0, bb1)
296 basic_block bb0, bb1;
297 {
298 edge e0, e1;
299
300 for (e0 = bb0->succ; e0; e0 = e0->succ_next)
301 {
302 for (e1 = bb1->succ; e1; e1 = e1->succ_next)
303 {
304 if (e0->dest == e1->dest)
305 {
306 return e0->dest;
307 }
308 }
309 }
310 return 0;
311 }
312
313
314 /* Move the destination block for edge E after chain end block CEB
315 Adding jumps and labels is deferred until fixup_reorder_chain. */
316
317 static basic_block
318 chain_reorder_blocks (e, ceb)
319 edge e;
320 basic_block ceb;
321 {
322 basic_block sb = e->src;
323 basic_block db = e->dest;
324 rtx cebe_insn, dbh_insn, dbe_insn;
325 edge ee, last_edge;
326
327 enum cond_types {NO_COND, PREDICT_THEN_WITH_ELSE, PREDICT_ELSE,
328 PREDICT_THEN_NO_ELSE, PREDICT_NOT_THEN_NO_ELSE};
329 enum cond_types cond_type;
330 enum cond_block_types {NO_COND_BLOCK, THEN_BLOCK, ELSE_BLOCK,
331 NO_ELSE_BLOCK};
332 enum cond_block_types cond_block_type;
333
334 if (rtl_dump_file)
335 fprintf (rtl_dump_file,
336 "Edge from basic block %d to basic block %d last visited %d\n",
337 sb->index, db->index, ceb->index);
338 cebe_insn = REORDER_BLOCK_EFF_END (ceb);
339
340 /* Blocks are in original order. */
341 if (sb->index == ceb->index
342 && ceb->index + 1 == db->index && NEXT_INSN (cebe_insn))
343 return db;
344
345 /* Get the type of block and type of condition. */
346 cond_type = NO_COND;
347 cond_block_type = NO_COND_BLOCK;
348 if (GET_CODE (sb->end) == JUMP_INSN && ! simplejump_p (sb->end)
349 && condjump_p (sb->end))
350 {
351 if (e->flags & EDGE_FALLTHRU)
352 cond_block_type = THEN_BLOCK;
353 else if (get_common_dest (sb->succ->dest, sb))
354 cond_block_type = NO_ELSE_BLOCK;
355 else
356 cond_block_type = ELSE_BLOCK;
357
358 if (sb->succ->succ_next
359 && get_common_dest (sb->succ->dest, sb))
360 {
361 if (cond_block_type == THEN_BLOCK)
362 {
363 if (! (REORDER_BLOCK_FLAGS (sb->succ->succ_next->dest)
364 & REORDER_BLOCK_VISITED))
365 cond_type = PREDICT_THEN_NO_ELSE;
366 else
367 cond_type = PREDICT_NOT_THEN_NO_ELSE;
368 }
369 else if (cond_block_type == NO_ELSE_BLOCK)
370 {
371 if (! (REORDER_BLOCK_FLAGS (sb->succ->dest)
372 & REORDER_BLOCK_VISITED))
373 cond_type = PREDICT_NOT_THEN_NO_ELSE;
374 else
375 cond_type = PREDICT_THEN_NO_ELSE;
376 }
377 }
378 else
379 {
380 if (cond_block_type == THEN_BLOCK)
381 {
382 if (! (REORDER_BLOCK_FLAGS (sb->succ->succ_next->dest)
383 & REORDER_BLOCK_VISITED))
384 cond_type = PREDICT_THEN_WITH_ELSE;
385 else
386 cond_type = PREDICT_ELSE;
387 }
388 else if (cond_block_type == ELSE_BLOCK
389 && sb->succ->dest != EXIT_BLOCK_PTR)
390 {
391 if (! (REORDER_BLOCK_FLAGS (sb->succ->dest)
392 & REORDER_BLOCK_VISITED))
393 cond_type = PREDICT_ELSE;
394 else
395 cond_type = PREDICT_THEN_WITH_ELSE;
396 }
397 }
398 }
399
400 if (rtl_dump_file)
401 {
402 static const char * cond_type_str [] = {"not cond jump", "predict then",
403 "predict else",
404 "predict then w/o else",
405 "predict not then w/o else"};
406 static const char * cond_block_type_str [] = {"not then or else block",
407 "then block",
408 "else block",
409 "then w/o else block"};
410
411 fprintf (rtl_dump_file, " %s (looking at %s)\n",
412 cond_type_str[(int)cond_type],
413 cond_block_type_str[(int)cond_block_type]);
414 }
415
416 /* Reflect that then block will move and we'll jump to it. */
417 if (cond_block_type != THEN_BLOCK
418 && (cond_type == PREDICT_ELSE
419 || cond_type == PREDICT_NOT_THEN_NO_ELSE))
420 {
421 if (rtl_dump_file)
422 fprintf (rtl_dump_file,
423 " then jump from block %d to block %d\n",
424 sb->index, sb->succ->dest->index);
425
426 /* Jump to reordered then block. */
427 REORDER_BLOCK_ADD_JUMP (sb) = sb->succ->dest;
428 }
429
430 /* Reflect that then block will jump back when we have no else. */
431 if (cond_block_type != THEN_BLOCK
432 && cond_type == PREDICT_NOT_THEN_NO_ELSE)
433 {
434 for (ee = sb->succ->dest->succ;
435 ee && ! (ee->flags & EDGE_FALLTHRU);
436 ee = ee->succ_next)
437 continue;
438
439 if (ee && ! (GET_CODE (sb->succ->dest->end) == JUMP_INSN
440 && ! simplejump_p (sb->succ->dest->end)))
441 {
442 REORDER_BLOCK_ADD_JUMP (sb->succ->dest) = ee->dest;
443 }
444 }
445
446 /* Reflect that else block will jump back. */
447 if (cond_block_type == ELSE_BLOCK
448 && (cond_type == PREDICT_THEN_WITH_ELSE || cond_type == PREDICT_ELSE))
449 {
450 last_edge=db->succ;
451
452 if (last_edge
453 && last_edge->dest != EXIT_BLOCK_PTR
454 && GET_CODE (last_edge->dest->head) == CODE_LABEL
455 && ! (GET_CODE (db->end) == JUMP_INSN))
456 {
457 if (rtl_dump_file)
458 fprintf (rtl_dump_file,
459 " else jump from block %d to block %d\n",
460 db->index, last_edge->dest->index);
461
462 REORDER_BLOCK_ADD_JUMP (db) = last_edge->dest;
463 }
464 }
465
466 /* This block's successor has already been reordered. This can happen
467 when we reorder a chain starting at a then or else. */
468 for (last_edge = db->succ;
469 last_edge && ! (last_edge->flags & EDGE_FALLTHRU);
470 last_edge = last_edge->succ_next)
471 continue;
472
473 if (last_edge
474 && last_edge->dest != EXIT_BLOCK_PTR
475 && (REORDER_BLOCK_FLAGS (last_edge->dest)
476 & REORDER_BLOCK_VISITED))
477 {
478 if (rtl_dump_file)
479 fprintf (rtl_dump_file,
480 " end of chain jump from block %d to block %d\n",
481 db->index, last_edge->dest->index);
482
483 REORDER_BLOCK_ADD_JUMP (db) = last_edge->dest;
484 }
485
486 dbh_insn = REORDER_BLOCK_EFF_HEAD (db);
487 cebe_insn = REORDER_BLOCK_EFF_END (ceb);
488 dbe_insn = REORDER_BLOCK_EFF_END (db);
489
490 /* Rechain predicted block. */
491 NEXT_INSN (cebe_insn) = dbh_insn;
492 PREV_INSN (dbh_insn) = cebe_insn;
493
494 if (db->index != n_basic_blocks - 1)
495 NEXT_INSN (dbe_insn) = 0;
496
497 return db;
498 }
499
500
501 /* Reorder blocks starting at block BB. */
502
503 static void
504 make_reorder_chain (bb)
505 basic_block bb;
506 {
507 edge e;
508 basic_block visited_edge = NULL;
509 rtx block_end;
510 int probability;
511
512 if (bb == EXIT_BLOCK_PTR)
513 return;
514
515 /* Find the most probable block. */
516 e = bb->succ;
517 block_end = bb->end;
518 if (GET_CODE (block_end) == JUMP_INSN && condjump_p (block_end))
519 {
520 rtx note = find_reg_note (block_end, REG_BR_PROB, 0);
521
522 if (note)
523 probability = INTVAL (XEXP (note, 0));
524 else
525 probability = 0;
526
527 if (probability >= REG_BR_PROB_BASE / 2)
528 e = bb->succ->succ_next;
529 }
530
531 /* Add chosen successor to chain and recurse on it. */
532 if (e && e->dest != EXIT_BLOCK_PTR
533 && e->dest != e->src
534 && (! (REORDER_BLOCK_FLAGS (e->dest) & REORDER_BLOCK_VISITED)
535 || (REORDER_BLOCK_FLAGS (e->dest) == REORDER_BLOCK_HEAD)))
536 {
537 if (! (REORDER_BLOCK_FLAGS (bb) & REORDER_BLOCK_VISITED))
538 {
539 REORDER_BLOCK_FLAGS (bb) |= REORDER_BLOCK_HEAD;
540 REORDER_BLOCK_INDEX (bb) = reorder_index++;
541 REORDER_BLOCK_FLAGS (bb) |= REORDER_BLOCK_VISITED;
542 }
543
544 if (REORDER_BLOCK_FLAGS (e->dest) & REORDER_BLOCK_VISITED)
545 REORDER_BLOCK_FLAGS (e->dest) &= ~REORDER_BLOCK_HEAD;
546
547 REORDER_BLOCK_SUCC (bb) = e;
548
549 visited_edge = e->dest;
550
551 reorder_last_visited = chain_reorder_blocks (e, bb);
552
553 if (e->dest
554 && ! (REORDER_BLOCK_FLAGS (e->dest)
555 & REORDER_BLOCK_VISITED))
556 make_reorder_chain (e->dest);
557 }
558 else
559 {
560 if (! (REORDER_BLOCK_FLAGS (bb) & REORDER_BLOCK_VISITED))
561 {
562 REORDER_BLOCK_INDEX (bb) = reorder_index++;
563 REORDER_BLOCK_FLAGS (bb) |= REORDER_BLOCK_VISITED;
564 }
565 }
566
567 /* Recurse on the successors. */
568 for (e = bb->succ; e; e = e->succ_next)
569 {
570 if (e->dest && e->dest == EXIT_BLOCK_PTR)
571 continue;
572
573 if (e->dest
574 && e->dest != e->src
575 && e->dest != visited_edge
576 && ! (REORDER_BLOCK_FLAGS (e->dest)
577 & REORDER_BLOCK_VISITED))
578 {
579 reorder_last_visited
580 = chain_reorder_blocks (e, reorder_last_visited);
581 make_reorder_chain (e->dest);
582 }
583 }
584 }
585
586
587 /* Fixup jumps and labels after reordering basic blocks. */
588
589 static void
590 fixup_reorder_chain ()
591 {
592 int i, j;
593 rtx insn;
594 int orig_num_blocks = n_basic_blocks;
595
596 /* Set the new last insn. */
597 {
598 int max_val = 0;
599 int max_index = 0;
600 for (j = 0; j < n_basic_blocks; j++)
601 {
602 int val = REORDER_BLOCK_INDEX (BASIC_BLOCK (j));
603 if (val > max_val)
604 {
605 max_val = val;
606 max_index = j;
607 }
608 }
609 insn = REORDER_BLOCK_EFF_END (BASIC_BLOCK (max_index));
610 NEXT_INSN (insn) = NULL_RTX;
611 set_last_insn (insn);
612 }
613
614 /* Add jumps and labels to fixup blocks. */
615 for (i = 0; i < orig_num_blocks; i++)
616 {
617 int need_block = 0;
618 basic_block bbi = BASIC_BLOCK (i);
619 if (REORDER_BLOCK_ADD_JUMP (bbi))
620 {
621 rtx label_insn, jump_insn, barrier_insn;
622
623 if (GET_CODE (REORDER_BLOCK_ADD_JUMP (bbi)->head) == CODE_LABEL)
624 label_insn = REORDER_BLOCK_ADD_JUMP (bbi)->head;
625 else
626 {
627 rtx new_label = gen_label_rtx ();
628 label_insn = emit_label_before (new_label,
629 REORDER_BLOCK_ADD_JUMP (bbi)->head);
630 REORDER_BLOCK_ADD_JUMP (bbi)->head = label_insn;
631 }
632
633 if (GET_CODE (bbi->end) != JUMP_INSN)
634 {
635 jump_insn = emit_jump_insn_after (gen_jump (label_insn),
636 bbi->end);
637 bbi->end = jump_insn;
638 need_block = 0;
639 }
640 else
641 {
642 jump_insn = emit_jump_insn_after (gen_jump (label_insn),
643 REORDER_BLOCK_EFF_END (bbi));
644 need_block = 1;
645 }
646
647 JUMP_LABEL (jump_insn) = label_insn;
648 ++LABEL_NUSES (label_insn);
649 barrier_insn = emit_barrier_after (jump_insn);
650
651 /* Add block for jump. Typically this is when a then is not
652 predicted and we are jumping to the moved then block. */
653 if (need_block)
654 {
655 basic_block nb;
656
657 VARRAY_GROW (basic_block_info, ++n_basic_blocks);
658 create_basic_block (n_basic_blocks - 1, jump_insn,
659 jump_insn, NULL);
660 nb = BASIC_BLOCK (n_basic_blocks - 1);
661 nb->global_live_at_start
662 = OBSTACK_ALLOC_REG_SET (function_obstack);
663 nb->global_live_at_end
664 = OBSTACK_ALLOC_REG_SET (function_obstack);
665
666 COPY_REG_SET (nb->global_live_at_start,
667 bbi->global_live_at_start);
668 COPY_REG_SET (nb->global_live_at_end,
669 bbi->global_live_at_start);
670 BASIC_BLOCK (nb->index)->local_set = 0;
671
672 nb->aux = xcalloc (1, sizeof (struct reorder_block_def));
673 REORDER_BLOCK_INDEX (nb) = REORDER_BLOCK_INDEX (bbi) + 1;
674 /* Relink to new block. */
675 nb->succ = bbi->succ;
676 nb->succ->src = nb;
677
678 make_edge (NULL, bbi, nb, 0);
679 bbi->succ->succ_next
680 = bbi->succ->succ_next->succ_next;
681 nb->succ->succ_next = 0;
682 /* Fix reorder block index to reflect new block. */
683 for (j = 0; j < n_basic_blocks - 1; j++)
684 {
685 basic_block bbj = BASIC_BLOCK (j);
686 if (REORDER_BLOCK_INDEX (bbj)
687 >= REORDER_BLOCK_INDEX (bbi) + 1)
688 REORDER_BLOCK_INDEX (bbj)++;
689 }
690 REORDER_BLOCK_SCOPE (nb) = REORDER_BLOCK_SCOPE (bbi);
691 REORDER_BLOCK_EFF_HEAD (nb) = nb->head;
692 REORDER_BLOCK_EFF_END (nb) = barrier_insn;
693 }
694 else
695 REORDER_BLOCK_EFF_END (bbi) = barrier_insn;
696 }
697 }
698 }
699
700
701 /* Perform sanity checks on the insn chain.
702 1. Check that next/prev pointers are consistent in both the forward and
703 reverse direction.
704 2. Count insns in chain, going both directions, and check if equal.
705 3. Check that get_last_insn () returns the actual end of chain. */
706 #ifdef ENABLE_CHECKING
707 static void
708 verify_insn_chain ()
709 {
710 rtx x,
711 prevx,
712 nextx;
713 int insn_cnt1,
714 insn_cnt2;
715
716 prevx = NULL;
717 insn_cnt1 = 1;
718 for (x = get_insns (); x; x = NEXT_INSN (x))
719 {
720 if (PREV_INSN (x) != prevx)
721 {
722 fprintf (stderr, "Forward traversal: insn chain corrupt.\n");
723 fprintf (stderr, "previous insn:\n");
724 debug_rtx (prevx);
725 fprintf (stderr, "current insn:\n");
726 debug_rtx (x);
727 abort ();
728 }
729 ++insn_cnt1;
730 prevx = x;
731 }
732
733 if (prevx != get_last_insn ())
734 {
735 fprintf (stderr, "last_insn corrupt.\n");
736 abort ();
737 }
738
739 nextx = NULL;
740 insn_cnt2 = 1;
741 for (x = get_last_insn (); x; x = PREV_INSN (x))
742 {
743 if (NEXT_INSN (x) != nextx)
744 {
745 fprintf (stderr, "Reverse traversal: insn chain corrupt.\n");
746 fprintf (stderr, "current insn:\n");
747 debug_rtx (x);
748 fprintf (stderr, "next insn:\n");
749 debug_rtx (nextx);
750 abort ();
751 }
752 ++insn_cnt2;
753 nextx = x;
754 }
755
756 if (insn_cnt1 != insn_cnt2)
757 {
758 fprintf (stderr, "insn_cnt1 (%d) not equal to insn_cnt2 (%d).\n",
759 insn_cnt1, insn_cnt2);
760 abort ();
761 }
762 }
763 #endif
764
765 static rtx
766 get_next_bb_note (x)
767 rtx x;
768 {
769 while (x)
770 {
771 if (GET_CODE (x) == NOTE
772 && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
773 return x;
774 x = NEXT_INSN (x);
775 }
776 return NULL;
777 }
778
779
780 static rtx
781 get_prev_bb_note (x)
782 rtx x;
783 {
784 while (x)
785 {
786 if (GET_CODE (x) == NOTE
787 && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
788 return x;
789 x = PREV_INSN (x);
790 }
791 return NULL;
792 }
793
794
795 /* Determine and record the relationships between basic blocks and
796 scopes in scope tree S. */
797
798 static void
799 relate_bbs_with_scopes (s)
800 scope s;
801 {
802 scope p;
803 int i, bbi1, bbi2, bbs_spanned;
804 rtx bbnote;
805
806 for (p = s->inner; p; p = p->next)
807 relate_bbs_with_scopes (p);
808
809 bbi1 = bbi2 = -1;
810 bbs_spanned = 0;
811
812 /* If the begin and end notes are both inside the same basic block,
813 or if they are both outside of basic blocks, then we know immediately
814 how they are related. Otherwise, we need to poke around to make the
815 determination. */
816 if (s->bb_beg != s->bb_end)
817 {
818 if (s->bb_beg && s->bb_end)
819 {
820 /* Both notes are in different bbs. This implies that all the
821 basic blocks spanned by the pair of notes are contained in
822 this scope. */
823 bbi1 = s->bb_beg->index;
824 bbi2 = s->bb_end->index;
825 bbs_spanned = 1;
826 }
827 else if (! s->bb_beg)
828 {
829 /* First note is outside of a bb. If the scope spans more than
830 one basic block, then they all are contained within this
831 scope. Otherwise, this scope is contained within the basic
832 block. */
833 bbnote = get_next_bb_note (s->note_beg);
834 if (! bbnote)
835 abort ();
836 if (NOTE_BASIC_BLOCK (bbnote) == s->bb_end)
837 {
838 bbs_spanned = 0;
839 s->bb_beg = NOTE_BASIC_BLOCK (bbnote);
840 }
841 else
842 {
843 bbi1 = NOTE_BASIC_BLOCK (bbnote)->index;
844 bbi2 = s->bb_end->index;
845 s->bb_end = NULL;
846 bbs_spanned = 1;
847 }
848 }
849 else /* ! s->bb_end */
850 {
851 /* Second 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
854 block. */
855 bbnote = get_prev_bb_note (s->note_end);
856 if (! bbnote)
857 abort ();
858 if (NOTE_BASIC_BLOCK (bbnote) == s->bb_beg)
859 {
860 bbs_spanned = 0;
861 s->bb_end = NOTE_BASIC_BLOCK (bbnote);
862 }
863 else
864 {
865 bbi1 = s->bb_beg->index;
866 bbi2 = NOTE_BASIC_BLOCK (bbnote)->index;
867 s->bb_beg = NULL;
868 bbs_spanned = 1;
869 }
870 }
871 }
872 else
873 {
874 if (s->bb_beg)
875 /* Both notes are in the same bb, which implies the block
876 contains this scope. */
877 bbs_spanned = 0;
878 else
879 {
880 rtx x1, x2;
881 /* Both notes are outside of any bbs. This implies that all the
882 basic blocks spanned by the pair of notes are contained in
883 this scope.
884 There is a degenerate case to consider. If the notes do not
885 span any basic blocks, then it is an empty scope that can
886 safely be deleted or ignored. Mark these with level = -1. */
887
888 x1 = get_next_bb_note (s->note_beg);
889 x2 = get_prev_bb_note (s->note_end);
890 if (! (x1 && x2))
891 {
892 s->level = -1;
893 bbs_spanned = 0;
894 }
895 else
896 {
897 bbi1 = NOTE_BASIC_BLOCK (x1)->index;
898 bbi2 = NOTE_BASIC_BLOCK (x2)->index;
899 bbs_spanned = 1;
900 }
901 }
902 }
903
904
905 /* If the scope spans one or more basic blocks, we record them. We
906 only record the bbs that are immediately contained within this
907 scope. Note that if a scope is contained within a bb, we can tell
908 by checking that bb_beg = bb_end and that they are non-null. */
909 if (bbs_spanned)
910 {
911 int j = 0;
912
913 s->num_bbs = 0;
914 for (i = bbi1; i <= bbi2; i++)
915 if (! REORDER_BLOCK_SCOPE (BASIC_BLOCK (i)))
916 s->num_bbs++;
917
918 s->bbs = xcalloc (s->num_bbs, sizeof (struct basic_block_def));
919 for (i = bbi1; i <= bbi2; i++)
920 {
921 basic_block curr_bb = BASIC_BLOCK (i);
922 if (! REORDER_BLOCK_SCOPE (curr_bb))
923 {
924 s->bbs[j++] = curr_bb;
925 REORDER_BLOCK_SCOPE (curr_bb) = s;
926 }
927 }
928 }
929 else
930 s->num_bbs = 0;
931 }
932
933
934 /* Allocate and initialize a new scope structure with scope level LEVEL,
935 and record the NOTE beginning the scope. */
936
937 static scope
938 make_new_scope (level, note)
939 int level;
940 rtx note;
941 {
942 scope new_scope = xcalloc (1, sizeof (struct scope_def));
943 new_scope->level = level;
944 new_scope->note_beg = note;
945 new_scope->note_end = NULL;
946 new_scope->bb_beg = NULL;
947 new_scope->bb_end = NULL;
948 new_scope->inner = NULL;
949 new_scope->inner_last = NULL;
950 new_scope->outer = NULL;
951 new_scope->next = NULL;
952 new_scope->num_bbs = 0;
953 new_scope->bbs = NULL;
954 return new_scope;
955 }
956
957
958 /* Build a forest representing the scope structure of the function.
959 Return a pointer to a structure describing the forest. */
960
961 static void
962 build_scope_forest (forest)
963 scope_forest_info *forest;
964 {
965 rtx x;
966 int level, bbi, i;
967 basic_block curr_bb;
968 scope root, curr_scope;
969
970 forest->num_trees = 0;
971 forest->trees = NULL;
972 level = -1;
973 root = NULL;
974 curr_bb = NULL;
975 bbi = 0;
976 for (x = get_insns (); x; x = NEXT_INSN (x))
977 {
978 if (bbi < n_basic_blocks && x == BASIC_BLOCK (bbi)->head)
979 curr_bb = BASIC_BLOCK (bbi);
980
981 if (GET_CODE (x) == NOTE)
982 {
983 if (NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_BEG)
984 {
985 if (root)
986 {
987 scope new_scope;
988 if (! curr_scope)
989 abort();
990 level++;
991 new_scope = make_new_scope (level, x);
992 new_scope->outer = curr_scope;
993 new_scope->next = NULL;
994 if (! curr_scope->inner)
995 {
996 curr_scope->inner = new_scope;
997 curr_scope->inner_last = new_scope;
998 }
999 else
1000 {
1001 curr_scope->inner_last->next = new_scope;
1002 curr_scope->inner_last = new_scope;
1003 }
1004 curr_scope = curr_scope->inner_last;
1005 }
1006 else
1007 {
1008 int ntrees = forest->num_trees;
1009 level++;
1010 curr_scope = make_new_scope (level, x);
1011 root = curr_scope;
1012 if (ntrees == 0)
1013 forest->trees = xcalloc (1, sizeof (scope));
1014 else
1015 forest->trees = xrealloc (forest->trees,
1016 sizeof (scope) * (ntrees + 1));
1017 forest->trees[forest->num_trees++] = root;
1018 }
1019 curr_scope->bb_beg = curr_bb;
1020 }
1021 else if (NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_END)
1022 {
1023 curr_scope->bb_end = curr_bb;
1024 curr_scope->note_end = x;
1025 level--;
1026 curr_scope = curr_scope->outer;
1027 if (level == -1)
1028 root = NULL;
1029 }
1030 } /* if note */
1031
1032 if (curr_bb && curr_bb->end == x)
1033 {
1034 curr_bb = NULL;
1035 bbi++;
1036 }
1037
1038 } /* for */
1039
1040 for (i = 0; i < forest->num_trees; i++)
1041 relate_bbs_with_scopes (forest->trees[i]);
1042 }
1043
1044
1045 /* Remove all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes from
1046 the insn chain. */
1047
1048 static void
1049 remove_scope_notes ()
1050 {
1051 rtx x, next;
1052 basic_block currbb = NULL;
1053
1054 for (x = get_insns (); x; x = next)
1055 {
1056 next = NEXT_INSN (x);
1057 if (GET_CODE (x) == NOTE
1058 && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
1059 currbb = NOTE_BASIC_BLOCK (x);
1060
1061 if (GET_CODE (x) == NOTE
1062 && (NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_BEG
1063 || NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_END))
1064 {
1065 /* Check if the scope note happens to be the end of a bb. */
1066 if (currbb && x == currbb->end)
1067 currbb->end = PREV_INSN (x);
1068 if (currbb && x == currbb->head)
1069 abort ();
1070
1071 if (PREV_INSN (x))
1072 {
1073 NEXT_INSN (PREV_INSN (x)) = next;
1074 PREV_INSN (next) = PREV_INSN (x);
1075
1076 NEXT_INSN (x) = NULL;
1077 PREV_INSN (x) = NULL;
1078 }
1079 else
1080 abort ();
1081 }
1082 }
1083 }
1084
1085
1086 /* Insert scope note pairs for a contained scope tree S after insn IP. */
1087 static void
1088 insert_intra_1 (s, ip)
1089 scope s;
1090 rtx *ip;
1091 {
1092 scope p;
1093
1094 if (NOTE_BLOCK (s->note_beg))
1095 {
1096 *ip = emit_note_after (NOTE_INSN_BLOCK_BEG, *ip);
1097 NOTE_BLOCK (*ip) = NOTE_BLOCK (s->note_beg);
1098 }
1099
1100 for (p = s->inner; p; p = p->next)
1101 insert_intra_1 (p, ip);
1102
1103 if (NOTE_BLOCK (s->note_beg))
1104 {
1105 *ip = emit_note_after (NOTE_INSN_BLOCK_END, *ip);
1106 NOTE_BLOCK (*ip) = NOTE_BLOCK (s->note_end);
1107 }
1108 }
1109
1110
1111 /* Insert NOTE_INSN_BLOCK_END notes and NOTE_INSN_BLOCK_BEG notes for
1112 scopes that are contained within BB. */
1113
1114 static void
1115 insert_intra_bb_scope_notes (bb)
1116 basic_block bb;
1117 {
1118 scope s = REORDER_BLOCK_SCOPE (bb);
1119 scope p;
1120 rtx ip;
1121
1122 if (! s)
1123 return;
1124
1125 ip = bb->head;
1126 if (GET_CODE (ip) == CODE_LABEL)
1127 ip = NEXT_INSN (ip);
1128
1129 for (p = s->inner; p; p = p->next)
1130 {
1131 if (p->bb_beg != NULL && p->bb_beg == p->bb_end && p->bb_beg == bb)
1132 insert_intra_1 (p, &ip);
1133 }
1134 }
1135
1136
1137 /* Given two consecutive basic blocks BB1 and BB2 with different scopes,
1138 insert NOTE_INSN_BLOCK_END notes after BB1 and NOTE_INSN_BLOCK_BEG
1139 notes before BB2 such that the notes are correctly balanced. If BB1 or
1140 BB2 is NULL, we are inserting scope notes for the first and last basic
1141 blocks, respectively. */
1142
1143 static void
1144 insert_inter_bb_scope_notes (bb1, bb2)
1145 basic_block bb1;
1146 basic_block bb2;
1147 {
1148 rtx ip;
1149 scope com;
1150
1151 /* It is possible that a basic block is not contained in any scope.
1152 In that case, we either open or close a scope but not both. */
1153 if (bb1 && bb2)
1154 {
1155 scope s1 = REORDER_BLOCK_SCOPE (bb1);
1156 scope s2 = REORDER_BLOCK_SCOPE (bb2);
1157 if (! s1 && ! s2)
1158 return;
1159 if (! s1)
1160 bb1 = NULL;
1161 else if (! s2)
1162 bb2 = NULL;
1163 }
1164
1165 /* Find common ancestor scope. */
1166 if (bb1 && bb2)
1167 {
1168 scope s1 = REORDER_BLOCK_SCOPE (bb1);
1169 scope s2 = REORDER_BLOCK_SCOPE (bb2);
1170 while (s1 != s2)
1171 {
1172 if (! (s1 && s2))
1173 abort ();
1174 if (s1->level > s2->level)
1175 s1 = s1->outer;
1176 else if (s2->level > s1->level)
1177 s2 = s2->outer;
1178 else
1179 {
1180 s1 = s1->outer;
1181 s2 = s2->outer;
1182 }
1183 }
1184 com = s1;
1185 }
1186 else
1187 com = NULL;
1188
1189 /* Close scopes. */
1190 if (bb1)
1191 {
1192 scope s = REORDER_BLOCK_SCOPE (bb1);
1193 ip = REORDER_BLOCK_EFF_END (bb1);
1194 while (s != com)
1195 {
1196 if (NOTE_BLOCK (s->note_beg))
1197 {
1198 ip = emit_note_after (NOTE_INSN_BLOCK_END, ip);
1199 NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_end);
1200 }
1201 s = s->outer;
1202 }
1203 }
1204
1205 /* Open scopes. */
1206 if (bb2)
1207 {
1208 scope s = REORDER_BLOCK_SCOPE (bb2);
1209 ip = bb2->head;
1210 while (s != com)
1211 {
1212 if (NOTE_BLOCK (s->note_beg))
1213 {
1214 ip = emit_note_before (NOTE_INSN_BLOCK_BEG, ip);
1215 NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_beg);
1216 }
1217 s = s->outer;
1218 }
1219 }
1220 }
1221
1222
1223 /* Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based
1224 on the scope forest and the newly reordered basic blocks. */
1225
1226 static void
1227 rebuild_scope_notes (forest)
1228 scope_forest_info *forest;
1229 {
1230 int i;
1231
1232 if (forest->num_trees == 0)
1233 return;
1234
1235 /* Start by opening the scopes before the first basic block. */
1236 insert_inter_bb_scope_notes (NULL, BASIC_BLOCK (0));
1237
1238 /* Then, open and close scopes as needed between blocks. */
1239 for (i = 0; i < n_basic_blocks - 1; i++)
1240 {
1241 basic_block bb1 = BASIC_BLOCK (i);
1242 basic_block bb2 = BASIC_BLOCK (i + 1);
1243 if (REORDER_BLOCK_SCOPE (bb1) != REORDER_BLOCK_SCOPE (bb2))
1244 insert_inter_bb_scope_notes (bb1, bb2);
1245 insert_intra_bb_scope_notes (bb1);
1246 }
1247
1248 /* Finally, close the scopes after the last basic block. */
1249 insert_inter_bb_scope_notes (BASIC_BLOCK (n_basic_blocks - 1), NULL);
1250 insert_intra_bb_scope_notes (BASIC_BLOCK (n_basic_blocks - 1));
1251 }
1252
1253
1254 /* Free the storage associated with the scope tree at S. */
1255
1256 static void
1257 free_scope_forest_1 (s)
1258 scope s;
1259 {
1260 scope p, next;
1261
1262 for (p = s->inner; p; p = next)
1263 {
1264 next = p->next;
1265 free_scope_forest_1 (p);
1266 }
1267
1268 if (s->bbs)
1269 free (s->bbs);
1270 free (s);
1271 }
1272
1273
1274 /* Free the storage associated with the scope forest. */
1275
1276 static void
1277 free_scope_forest (forest)
1278 scope_forest_info *forest;
1279 {
1280 int i;
1281 for (i = 0; i < forest->num_trees; i++)
1282 free_scope_forest_1 (forest->trees[i]);
1283 }
1284
1285
1286 /* Visualize the scope forest. */
1287
1288 void
1289 dump_scope_forest (forest)
1290 scope_forest_info *forest;
1291 {
1292 if (forest->num_trees == 0)
1293 fprintf (stderr, "\n< Empty scope forest >\n");
1294 else
1295 {
1296 int i;
1297 fprintf (stderr, "\n< Scope forest >\n");
1298 for (i = 0; i < forest->num_trees; i++)
1299 dump_scope_forest_1 (forest->trees[i], 0);
1300 }
1301 }
1302
1303
1304 /* Recursive portion of dump_scope_forest. */
1305
1306 static void
1307 dump_scope_forest_1 (s, indent)
1308 scope s;
1309 int indent;
1310 {
1311 scope p;
1312 int i;
1313
1314 if (s->bb_beg != NULL && s->bb_beg == s->bb_end
1315 && REORDER_BLOCK_SCOPE (s->bb_beg)
1316 && REORDER_BLOCK_SCOPE (s->bb_beg)->level + 1 == s->level)
1317 {
1318 fprintf (stderr, "%*s", indent, "");
1319 fprintf (stderr, "BB%d:\n", s->bb_beg->index);
1320 }
1321
1322 fprintf (stderr, "%*s", indent, "");
1323 fprintf (stderr, "{ level %d (block %p)\n", s->level,
1324 NOTE_BLOCK (s->note_beg));
1325
1326 fprintf (stderr, "%*s%s", indent, "", "bbs:");
1327 for (i = 0; i < s->num_bbs; i++)
1328 fprintf (stderr, " %d", s->bbs[i]->index);
1329 fprintf (stderr, "\n");
1330
1331 for (p = s->inner; p; p = p->next)
1332 dump_scope_forest_1 (p, indent + 2);
1333
1334 fprintf (stderr, "%*s", indent, "");
1335 fprintf (stderr, "}\n");
1336 }
1337
1338
1339 /* Reorder basic blocks. */
1340
1341 void
1342 reorder_basic_blocks ()
1343 {
1344 int i, j;
1345 struct loops loops_info;
1346 int num_loops;
1347 scope_forest_info forest;
1348
1349 if (profile_arc_flag)
1350 return;
1351
1352 if (n_basic_blocks <= 1)
1353 return;
1354
1355 /* Exception edges are not currently handled. */
1356 for (i = 0; i < n_basic_blocks; i++)
1357 {
1358 edge e;
1359
1360 for (e = BASIC_BLOCK (i)->succ; e && ! (e->flags & EDGE_EH);
1361 e = e->succ_next)
1362 continue;
1363
1364 if (e && (e->flags & EDGE_EH))
1365 return;
1366 }
1367
1368 reorder_index = 0;
1369
1370 /* Find natural loops using the CFG. */
1371 num_loops = flow_loops_find (&loops_info);
1372
1373 /* Dump loop information. */
1374 flow_loops_dump (&loops_info, rtl_dump_file, 0);
1375
1376 reorder_last_visited = BASIC_BLOCK (0);
1377
1378 for (i = 0; i < n_basic_blocks; i++)
1379 {
1380 basic_block bbi = BASIC_BLOCK (i);
1381 bbi->aux = xcalloc (1, sizeof (struct reorder_block_def));
1382 *((struct reorder_block_def *)bbi->aux) = rbd_init;
1383 }
1384
1385 build_scope_forest (&forest);
1386 remove_scope_notes ();
1387
1388 for (i = 0; i < n_basic_blocks; i++)
1389 {
1390 basic_block bbi = BASIC_BLOCK (i);
1391 REORDER_BLOCK_EFF_END (bbi)
1392 = skip_insns_between_block (bbi, REORDER_SKIP_AFTER);
1393 if (i == 0)
1394 REORDER_BLOCK_EFF_HEAD (bbi) = get_insns ();
1395 else
1396 {
1397 rtx prev_eff_end = REORDER_BLOCK_EFF_END (BASIC_BLOCK (i - 1));
1398 REORDER_BLOCK_EFF_HEAD (bbi) = NEXT_INSN (prev_eff_end);
1399 }
1400 }
1401
1402 /* If we've not got epilogue in RTL, we must fallthru to the exit.
1403 Force the last block to be at the end. */
1404 /* ??? Some ABIs (e.g. MIPS) require the return insn to be at the
1405 end of the function for stack unwinding purposes. */
1406
1407 #ifndef HAVE_epilogue
1408 #define HAVE_epilogue 0
1409 #endif
1410
1411 if (! HAVE_epilogue)
1412 {
1413 basic_block last = BASIC_BLOCK (n_basic_blocks - 1);
1414 REORDER_BLOCK_INDEX (last) = n_basic_blocks - 1;
1415 REORDER_BLOCK_FLAGS (last) |= REORDER_BLOCK_VISITED;
1416 }
1417
1418 make_reorder_chain (BASIC_BLOCK (0));
1419
1420 fixup_reorder_chain ();
1421
1422 #ifdef ENABLE_CHECKING
1423 verify_insn_chain ();
1424 #endif
1425
1426 /* Put basic_block_info in new order. */
1427 for (i = 0; i < n_basic_blocks - 1; i++)
1428 {
1429 for (j = i; i != REORDER_BLOCK_INDEX (BASIC_BLOCK (j)); j++)
1430 continue;
1431
1432 if (REORDER_BLOCK_INDEX (BASIC_BLOCK (j)) == i
1433 && i != j)
1434 {
1435 basic_block tempbb;
1436 int temprbi;
1437 int rbi = REORDER_BLOCK_INDEX (BASIC_BLOCK (j));
1438
1439 temprbi = BASIC_BLOCK (rbi)->index;
1440 BASIC_BLOCK (rbi)->index = BASIC_BLOCK (j)->index;
1441 BASIC_BLOCK (j)->index = temprbi;
1442 tempbb = BASIC_BLOCK (rbi);
1443 BASIC_BLOCK (rbi) = BASIC_BLOCK (j);
1444 BASIC_BLOCK (j) = tempbb;
1445 }
1446 }
1447
1448 rebuild_scope_notes (&forest);
1449 free_scope_forest (&forest);
1450 reorder_blocks ();
1451
1452 #ifdef ENABLE_CHECKING
1453 verify_flow_info ();
1454 #endif
1455
1456 for (i = 0; i < n_basic_blocks; i++)
1457 free (BASIC_BLOCK (i)->aux);
1458
1459 /* Free loop information. */
1460 flow_loops_free (&loops_info);
1461
1462 }
1463