]> gcc.gnu.org Git - gcc.git/blame - gcc/cfglayout.c
2003-7-03 Devang Patel <dpatel@apple.com>
[gcc.git] / gcc / cfglayout.c
CommitLineData
d56a8211 1/* Basic block reordering routines for the GNU compiler.
d329e058 2 Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
d56a8211 3
5f0d2358 4This file is part of GCC.
d56a8211 5
5f0d2358
RK
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 2, or (at your option) any later
9version.
d56a8211 10
5f0d2358
RK
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
d56a8211 15
5f0d2358
RK
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING. If not, write to the Free
18Software Foundation, 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
d56a8211
JH
20
21#include "config.h"
22#include "system.h"
4977bab6
ZW
23#include "coretypes.h"
24#include "tm.h"
d73b1f07 25#include "tree.h"
d56a8211
JH
26#include "rtl.h"
27#include "hard-reg-set.h"
28#include "basic-block.h"
29#include "insn-config.h"
30#include "output.h"
31#include "function.h"
32#include "obstack.h"
33#include "cfglayout.h"
3d436d2a 34#include "cfgloop.h"
0b077eac 35#include "target.h"
0435312e 36#include "ggc.h"
bc35512f 37#include "alloc-pool.h"
d56a8211
JH
38
39/* The contents of the current function definition are allocated
5f0d2358 40 in this obstack, and all are freed at the end of the function. */
d56a8211
JH
41extern struct obstack flow_obstack;
42
bc35512f
JH
43alloc_pool cfg_layout_pool;
44
d56a8211 45/* Holds the interesting trailing notes for the function. */
bc35512f 46rtx cfg_layout_function_footer, cfg_layout_function_header;
d56a8211 47
d329e058
AJ
48static rtx skip_insns_after_block (basic_block);
49static void record_effective_endpoints (void);
50static rtx label_for_bb (basic_block);
51static void fixup_reorder_chain (void);
d56a8211 52
d329e058
AJ
53static void set_block_levels (tree, int);
54static void change_scope (rtx, tree, tree);
d56a8211 55
d329e058 56void verify_insn_chain (void);
d329e058
AJ
57static void fixup_fallthru_exit_predecessor (void);
58static rtx duplicate_insn_chain (rtx, rtx);
59static void break_superblocks (void);
60static tree insn_scope (rtx);
d56a8211 61\f
9ee634e3 62rtx
d329e058 63unlink_insn_chain (rtx first, rtx last)
969d70ca
JH
64{
65 rtx prevfirst = PREV_INSN (first);
66 rtx nextlast = NEXT_INSN (last);
67
68 PREV_INSN (first) = NULL;
69 NEXT_INSN (last) = NULL;
70 if (prevfirst)
71 NEXT_INSN (prevfirst) = nextlast;
72 if (nextlast)
73 PREV_INSN (nextlast) = prevfirst;
74 else
75 set_last_insn (prevfirst);
76 if (!prevfirst)
77 set_first_insn (nextlast);
78 return first;
79}
80\f
d56a8211
JH
81/* Skip over inter-block insns occurring after BB which are typically
82 associated with BB (e.g., barriers). If there are any such insns,
83 we return the last one. Otherwise, we return the end of BB. */
84
85static rtx
d329e058 86skip_insns_after_block (basic_block bb)
d56a8211
JH
87{
88 rtx insn, last_insn, next_head, prev;
89
90 next_head = NULL_RTX;
f6366fc7
ZD
91 if (bb->next_bb != EXIT_BLOCK_PTR)
92 next_head = bb->next_bb->head;
d56a8211 93
5f0d2358 94 for (last_insn = insn = bb->end; (insn = NEXT_INSN (insn)) != 0; )
d56a8211
JH
95 {
96 if (insn == next_head)
97 break;
98
99 switch (GET_CODE (insn))
100 {
101 case BARRIER:
102 last_insn = insn;
103 continue;
104
105 case NOTE:
106 switch (NOTE_LINE_NUMBER (insn))
107 {
108 case NOTE_INSN_LOOP_END:
109 case NOTE_INSN_BLOCK_END:
110 last_insn = insn;
111 continue;
112 case NOTE_INSN_DELETED:
113 case NOTE_INSN_DELETED_LABEL:
114 continue;
115
116 default:
117 continue;
118 break;
119 }
120 break;
121
122 case CODE_LABEL:
123 if (NEXT_INSN (insn)
124 && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
125 && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
126 || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
127 {
128 insn = NEXT_INSN (insn);
129 last_insn = insn;
130 continue;
131 }
f87c27b4 132 break;
d56a8211
JH
133
134 default:
135 break;
136 }
137
138 break;
139 }
5f0d2358
RK
140
141 /* It is possible to hit contradictory sequence. For instance:
f87c27b4 142
d56a8211
JH
143 jump_insn
144 NOTE_INSN_LOOP_BEG
145 barrier
146
5f0d2358
RK
147 Where barrier belongs to jump_insn, but the note does not. This can be
148 created by removing the basic block originally following
149 NOTE_INSN_LOOP_BEG. In such case reorder the notes. */
d56a8211 150
d56a8211
JH
151 for (insn = last_insn; insn != bb->end; insn = prev)
152 {
5f0d2358
RK
153 prev = PREV_INSN (insn);
154 if (GET_CODE (insn) == NOTE)
155 switch (NOTE_LINE_NUMBER (insn))
156 {
f87c27b4
KH
157 case NOTE_INSN_LOOP_END:
158 case NOTE_INSN_BLOCK_END:
159 case NOTE_INSN_DELETED:
160 case NOTE_INSN_DELETED_LABEL:
5f0d2358 161 continue;
f87c27b4 162 default:
5f0d2358 163 reorder_insns (insn, insn, last_insn);
f87c27b4 164 }
d56a8211
JH
165 }
166
167 return last_insn;
168}
169
170/* Locate or create a label for a given basic block. */
171
172static rtx
d329e058 173label_for_bb (basic_block bb)
d56a8211
JH
174{
175 rtx label = bb->head;
176
177 if (GET_CODE (label) != CODE_LABEL)
178 {
179 if (rtl_dump_file)
0b17ab2f 180 fprintf (rtl_dump_file, "Emitting label for block %d\n", bb->index);
d56a8211
JH
181
182 label = block_label (bb);
d56a8211
JH
183 }
184
185 return label;
186}
187
188/* Locate the effective beginning and end of the insn chain for each
189 block, as defined by skip_insns_after_block above. */
190
191static void
d329e058 192record_effective_endpoints (void)
d56a8211 193{
bc35512f 194 rtx next_insn;
e0082a72 195 basic_block bb;
bc35512f
JH
196 rtx insn;
197
198 for (insn = get_insns ();
199 NEXT_INSN (insn) && GET_CODE (insn) == NOTE;
200 insn = NEXT_INSN (insn))
201 {
202 if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK)
203 {
204 insn = NULL;
205 break;
206 }
207 if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
208 break;
209 }
210 if (insn)
211 cfg_layout_function_header = unlink_insn_chain (get_insns (), insn);
212 else
213 cfg_layout_function_header = NULL_RTX;
f87c27b4 214
bc35512f 215 next_insn = get_insns ();
e0082a72 216 FOR_EACH_BB (bb)
d56a8211 217 {
d56a8211
JH
218 rtx end;
219
969d70ca 220 if (PREV_INSN (bb->head) && next_insn != bb->head)
bc35512f 221 bb->rbi->header = unlink_insn_chain (next_insn,
969d70ca 222 PREV_INSN (bb->head));
d56a8211 223 end = skip_insns_after_block (bb);
969d70ca 224 if (NEXT_INSN (bb->end) && bb->end != end)
bc35512f 225 bb->rbi->footer = unlink_insn_chain (NEXT_INSN (bb->end), end);
969d70ca 226 next_insn = NEXT_INSN (bb->end);
d56a8211 227 }
5f0d2358 228
9ee634e3
JH
229 cfg_layout_function_footer = next_insn;
230 if (cfg_layout_function_footer)
231 cfg_layout_function_footer = unlink_insn_chain (cfg_layout_function_footer, get_last_insn ());
d56a8211
JH
232}
233\f
0435312e
JH
234/* Data structures representing mapping of INSN_LOCATOR into scope blocks, line
235 numbers and files. In order to be GGC friendly we need to use separate
236 varrays. This also slightly improve the memory locality in binary search.
237 The _locs array contains locators where the given property change. The
238 block_locators_blocks contains the scope block that is used for all insn
239 locator greater than corresponding block_locators_locs value and smaller
240 than the following one. Similarly for the other properties. */
241static GTY(()) varray_type block_locators_locs;
242static GTY(()) varray_type block_locators_blocks;
243static GTY(()) varray_type line_locators_locs;
244static GTY(()) varray_type line_locators_lines;
245static GTY(()) varray_type file_locators_locs;
246static GTY(()) varray_type file_locators_files;
247int prologue_locator;
248int epilogue_locator;
249
250/* During the RTL expansion the lexical blocks and line numbers are
251 represented via INSN_NOTEs. Replace them by representation using
252 INSN_LOCATORs. */
5f0d2358 253
d73b1f07 254void
d329e058 255insn_locators_initialize (void)
d56a8211 256{
d73b1f07 257 tree block = NULL;
0435312e 258 tree last_block = NULL;
d73b1f07 259 rtx insn, next;
0435312e
JH
260 int loc = 0;
261 int line_number = 0, last_line_number = 0;
262 char *file_name = NULL, *last_file_name = NULL;
263
264 prologue_locator = epilogue_locator = 0;
265
266 VARRAY_INT_INIT (block_locators_locs, 32, "block_locators_locs");
267 VARRAY_TREE_INIT (block_locators_blocks, 32, "block_locators_blocks");
268 VARRAY_INT_INIT (line_locators_locs, 32, "line_locators_locs");
269 VARRAY_INT_INIT (line_locators_lines, 32, "line_locators_lines");
270 VARRAY_INT_INIT (file_locators_locs, 32, "file_locators_locs");
271 VARRAY_CHAR_PTR_INIT (file_locators_files, 32, "file_locators_files");
d56a8211 272
d73b1f07 273 for (insn = get_insns (); insn; insn = next)
d56a8211 274 {
d73b1f07 275 next = NEXT_INSN (insn);
d56a8211 276
0435312e
JH
277 if ((active_insn_p (insn)
278 && GET_CODE (PATTERN (insn)) != ADDR_VEC
279 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
280 || !NEXT_INSN (insn)
281 || (!prologue_locator && file_name))
282 {
283 if (last_block != block)
284 {
285 loc++;
286 VARRAY_PUSH_INT (block_locators_locs, loc);
287 VARRAY_PUSH_TREE (block_locators_blocks, block);
288 last_block = block;
289 }
290 if (last_line_number != line_number)
291 {
292 loc++;
293 VARRAY_PUSH_INT (line_locators_locs, loc);
294 VARRAY_PUSH_INT (line_locators_lines, line_number);
295 last_line_number = line_number;
296 }
297 if (last_file_name != file_name)
298 {
299 loc++;
300 VARRAY_PUSH_INT (file_locators_locs, loc);
301 VARRAY_PUSH_CHAR_PTR (file_locators_files, file_name);
302 last_file_name = file_name;
303 }
304 }
305 if (!prologue_locator && file_name)
306 prologue_locator = loc;
307 if (!NEXT_INSN (insn))
308 epilogue_locator = loc;
309 if (active_insn_p (insn))
310 INSN_LOCATOR (insn) = loc;
d73b1f07 311 else if (GET_CODE (insn) == NOTE)
d56a8211 312 {
d73b1f07 313 switch (NOTE_LINE_NUMBER (insn))
d56a8211 314 {
d73b1f07
RH
315 case NOTE_INSN_BLOCK_BEG:
316 block = NOTE_BLOCK (insn);
317 delete_insn (insn);
318 break;
319 case NOTE_INSN_BLOCK_END:
320 block = BLOCK_SUPERCONTEXT (block);
339a28b9
ZW
321 if (block && TREE_CODE (block) == FUNCTION_DECL)
322 block = 0;
d73b1f07
RH
323 delete_insn (insn);
324 break;
325 default:
0435312e
JH
326 if (NOTE_LINE_NUMBER (insn) > 0)
327 {
328 line_number = NOTE_LINE_NUMBER (insn);
329 file_name = (char *)NOTE_SOURCE_FILE (insn);
330 }
d73b1f07 331 break;
d56a8211 332 }
d56a8211
JH
333 }
334 }
1292ec0c
JH
335
336 /* Tag the blocks with a depth number so that change_scope can find
337 the common parent easily. */
338 set_block_levels (DECL_INITIAL (cfun->decl), 0);
d56a8211 339}
d56a8211 340
d73b1f07
RH
341/* For each lexical block, set BLOCK_NUMBER to the depth at which it is
342 found in the block tree. */
54561457
JJ
343
344static void
d329e058 345set_block_levels (tree block, int level)
d56a8211 346{
d73b1f07 347 while (block)
d56a8211 348 {
d73b1f07
RH
349 BLOCK_NUMBER (block) = level;
350 set_block_levels (BLOCK_SUBBLOCKS (block), level + 1);
351 block = BLOCK_CHAIN (block);
d56a8211
JH
352 }
353}
969d70ca 354\f
1292ec0c
JH
355/* Return sope resulting from combination of S1 and S2. */
356tree
d329e058 357choose_inner_scope (tree s1, tree s2)
1292ec0c
JH
358{
359 if (!s1)
360 return s2;
361 if (!s2)
362 return s1;
363 if (BLOCK_NUMBER (s1) > BLOCK_NUMBER (s2))
364 return s1;
365 return s2;
366}
367\f
d73b1f07 368/* Emit lexical block notes needed to change scope from S1 to S2. */
d56a8211
JH
369
370static void
d329e058 371change_scope (rtx orig_insn, tree s1, tree s2)
d56a8211 372{
d73b1f07
RH
373 rtx insn = orig_insn;
374 tree com = NULL_TREE;
375 tree ts1 = s1, ts2 = s2;
376 tree s;
5f0d2358 377
d73b1f07 378 while (ts1 != ts2)
d56a8211 379 {
d73b1f07
RH
380 if (ts1 == NULL || ts2 == NULL)
381 abort ();
382 if (BLOCK_NUMBER (ts1) > BLOCK_NUMBER (ts2))
383 ts1 = BLOCK_SUPERCONTEXT (ts1);
384 else if (BLOCK_NUMBER (ts1) < BLOCK_NUMBER (ts2))
385 ts2 = BLOCK_SUPERCONTEXT (ts2);
386 else
d56a8211 387 {
d73b1f07
RH
388 ts1 = BLOCK_SUPERCONTEXT (ts1);
389 ts2 = BLOCK_SUPERCONTEXT (ts2);
d56a8211 390 }
d56a8211 391 }
d73b1f07 392 com = ts1;
d56a8211
JH
393
394 /* Close scopes. */
d73b1f07
RH
395 s = s1;
396 while (s != com)
d56a8211 397 {
d73b1f07
RH
398 rtx note = emit_note_before (NOTE_INSN_BLOCK_END, insn);
399 NOTE_BLOCK (note) = s;
400 s = BLOCK_SUPERCONTEXT (s);
d56a8211
JH
401 }
402
403 /* Open scopes. */
d73b1f07
RH
404 s = s2;
405 while (s != com)
d56a8211 406 {
d73b1f07
RH
407 insn = emit_note_before (NOTE_INSN_BLOCK_BEG, insn);
408 NOTE_BLOCK (insn) = s;
409 s = BLOCK_SUPERCONTEXT (s);
d56a8211
JH
410 }
411}
412
0435312e
JH
413/* Return lexical scope block insn belong to. */
414static tree
d329e058 415insn_scope (rtx insn)
0435312e
JH
416{
417 int max = VARRAY_ACTIVE_SIZE (block_locators_locs);
418 int min = 0;
419 int loc = INSN_LOCATOR (insn);
420
421 if (!max || !loc)
422 return NULL;
423 while (1)
424 {
425 int pos = (min + max) / 2;
426 int tmp = VARRAY_INT (block_locators_locs, pos);
427
428 if (tmp <= loc && min != pos)
429 min = pos;
430 else if (tmp > loc && max != pos)
431 max = pos;
432 else
433 {
434 min = pos;
435 break;
436 }
437 }
438 return VARRAY_TREE (block_locators_blocks, min);
439}
440
441/* Return line number of the statement that produced this insn. */
442int
d329e058 443insn_line (rtx insn)
0435312e
JH
444{
445 int max = VARRAY_ACTIVE_SIZE (line_locators_locs);
446 int min = 0;
447 int loc = INSN_LOCATOR (insn);
448
449 if (!max || !loc)
450 return 0;
451 while (1)
452 {
453 int pos = (min + max) / 2;
454 int tmp = VARRAY_INT (line_locators_locs, pos);
455
456 if (tmp <= loc && min != pos)
457 min = pos;
458 else if (tmp > loc && max != pos)
459 max = pos;
460 else
461 {
462 min = pos;
463 break;
464 }
465 }
466 return VARRAY_INT (line_locators_lines, min);
467}
468
469/* Return source file of the statement that produced this insn. */
470const char *
d329e058 471insn_file (rtx insn)
0435312e
JH
472{
473 int max = VARRAY_ACTIVE_SIZE (file_locators_locs);
474 int min = 0;
475 int loc = INSN_LOCATOR (insn);
476
477 if (!max || !loc)
478 return NULL;
479 while (1)
480 {
481 int pos = (min + max) / 2;
482 int tmp = VARRAY_INT (file_locators_locs, pos);
483
484 if (tmp <= loc && min != pos)
485 min = pos;
486 else if (tmp > loc && max != pos)
487 max = pos;
488 else
489 {
490 min = pos;
491 break;
492 }
493 }
494 return VARRAY_CHAR_PTR (file_locators_files, min);
495}
496
d56a8211 497/* Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based
d73b1f07 498 on the scope tree and the newly reordered instructions. */
d56a8211
JH
499
500void
d329e058 501reemit_insn_block_notes (void)
d56a8211 502{
d73b1f07
RH
503 tree cur_block = DECL_INITIAL (cfun->decl);
504 rtx insn, note;
5f0d2358 505
ba4f7968
JH
506 insn = get_insns ();
507 if (!active_insn_p (insn))
508 insn = next_active_insn (insn);
509 for (; insn; insn = next_active_insn (insn))
d73b1f07
RH
510 {
511 tree this_block;
d56a8211 512
0435312e 513 this_block = insn_scope (insn);
1292ec0c 514 /* For sequences compute scope resulting from merging all scopes
4b7e68e7 515 of instructions nested inside. */
1292ec0c
JH
516 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
517 {
518 int i;
519 rtx body = PATTERN (insn);
520
521 this_block = NULL;
522 for (i = 0; i < XVECLEN (body, 0); i++)
523 this_block = choose_inner_scope (this_block,
d329e058 524 insn_scope (XVECEXP (body, 0, i)));
1292ec0c 525 }
d73b1f07
RH
526 if (! this_block)
527 continue;
d56a8211 528
d73b1f07
RH
529 if (this_block != cur_block)
530 {
531 change_scope (insn, cur_block, this_block);
532 cur_block = this_block;
533 }
d56a8211
JH
534 }
535
d73b1f07 536 /* change_scope emits before the insn, not after. */
2e040219 537 note = emit_note (NOTE_INSN_DELETED);
d73b1f07
RH
538 change_scope (note, cur_block, DECL_INITIAL (cfun->decl));
539 delete_insn (note);
d56a8211 540
d73b1f07 541 reorder_blocks ();
d56a8211
JH
542}
543\f
544/* Given a reorder chain, rearrange the code to match. */
545
546static void
d329e058 547fixup_reorder_chain (void)
d56a8211 548{
918ed612 549 basic_block bb, prev_bb;
d56a8211 550 int index;
969d70ca 551 rtx insn = NULL;
d56a8211 552
bc35512f
JH
553 if (cfg_layout_function_header)
554 {
555 set_first_insn (cfg_layout_function_header);
556 insn = cfg_layout_function_header;
557 while (NEXT_INSN (insn))
558 insn = NEXT_INSN (insn);
559 }
560
d56a8211
JH
561 /* First do the bulk reordering -- rechain the blocks without regard to
562 the needed changes to jumps and labels. */
563
f6366fc7 564 for (bb = ENTRY_BLOCK_PTR->next_bb, index = 0;
0b17ab2f 565 bb != 0;
bc35512f 566 bb = bb->rbi->next, index++)
d56a8211 567 {
bc35512f 568 if (bb->rbi->header)
969d70ca
JH
569 {
570 if (insn)
bc35512f 571 NEXT_INSN (insn) = bb->rbi->header;
969d70ca 572 else
bc35512f
JH
573 set_first_insn (bb->rbi->header);
574 PREV_INSN (bb->rbi->header) = insn;
575 insn = bb->rbi->header;
969d70ca
JH
576 while (NEXT_INSN (insn))
577 insn = NEXT_INSN (insn);
578 }
579 if (insn)
580 NEXT_INSN (insn) = bb->head;
581 else
582 set_first_insn (bb->head);
583 PREV_INSN (bb->head) = insn;
584 insn = bb->end;
bc35512f 585 if (bb->rbi->footer)
969d70ca 586 {
bc35512f
JH
587 NEXT_INSN (insn) = bb->rbi->footer;
588 PREV_INSN (bb->rbi->footer) = insn;
969d70ca
JH
589 while (NEXT_INSN (insn))
590 insn = NEXT_INSN (insn);
591 }
d56a8211
JH
592 }
593
0b17ab2f 594 if (index != n_basic_blocks)
d56a8211
JH
595 abort ();
596
9ee634e3
JH
597 NEXT_INSN (insn) = cfg_layout_function_footer;
598 if (cfg_layout_function_footer)
599 PREV_INSN (cfg_layout_function_footer) = insn;
d56a8211
JH
600
601 while (NEXT_INSN (insn))
602 insn = NEXT_INSN (insn);
5f0d2358 603
d56a8211
JH
604 set_last_insn (insn);
605#ifdef ENABLE_CHECKING
606 verify_insn_chain ();
607#endif
608
609 /* Now add jumps and labels as needed to match the blocks new
610 outgoing edges. */
611
bc35512f 612 for (bb = ENTRY_BLOCK_PTR->next_bb; bb ; bb = bb->rbi->next)
d56a8211
JH
613 {
614 edge e_fall, e_taken, e;
615 rtx bb_end_insn;
616 basic_block nb;
617
618 if (bb->succ == NULL)
619 continue;
620
621 /* Find the old fallthru edge, and another non-EH edge for
622 a taken jump. */
623 e_taken = e_fall = NULL;
624 for (e = bb->succ; e ; e = e->succ_next)
625 if (e->flags & EDGE_FALLTHRU)
626 e_fall = e;
627 else if (! (e->flags & EDGE_EH))
628 e_taken = e;
629
630 bb_end_insn = bb->end;
631 if (GET_CODE (bb_end_insn) == JUMP_INSN)
632 {
633 if (any_condjump_p (bb_end_insn))
634 {
635 /* If the old fallthru is still next, nothing to do. */
bc35512f
JH
636 if (bb->rbi->next == e_fall->dest
637 || (!bb->rbi->next
d56a8211
JH
638 && e_fall->dest == EXIT_BLOCK_PTR))
639 continue;
640
cb9a1d9b
JH
641 /* The degenerated case of conditional jump jumping to the next
642 instruction can happen on target having jumps with side
d329e058 643 effects.
cb9a1d9b
JH
644
645 Create temporarily the duplicated edge representing branch.
646 It will get unidentified by force_nonfallthru_and_redirect
647 that would otherwise get confused by fallthru edge not pointing
648 to the next basic block. */
649 if (!e_taken)
650 {
651 rtx note;
652 edge e_fake;
653
654 e_fake = unchecked_make_edge (bb, e_fall->dest, 0);
655
656 if (!redirect_jump (bb->end, block_label (bb), 0))
657 abort ();
658 note = find_reg_note (bb->end, REG_BR_PROB, NULL_RTX);
659 if (note)
660 {
661 int prob = INTVAL (XEXP (note, 0));
662
663 e_fake->probability = prob;
664 e_fake->count = e_fall->count * prob / REG_BR_PROB_BASE;
665 e_fall->probability -= e_fall->probability;
666 e_fall->count -= e_fake->count;
667 if (e_fall->probability < 0)
668 e_fall->probability = 0;
669 if (e_fall->count < 0)
670 e_fall->count = 0;
671 }
672 }
d56a8211
JH
673 /* There is one special case: if *neither* block is next,
674 such as happens at the very end of a function, then we'll
675 need to add a new unconditional jump. Choose the taken
676 edge based on known or assumed probability. */
bc35512f 677 else if (bb->rbi->next != e_taken->dest)
d56a8211
JH
678 {
679 rtx note = find_reg_note (bb_end_insn, REG_BR_PROB, 0);
5f0d2358 680
d56a8211
JH
681 if (note
682 && INTVAL (XEXP (note, 0)) < REG_BR_PROB_BASE / 2
683 && invert_jump (bb_end_insn,
684 label_for_bb (e_fall->dest), 0))
685 {
686 e_fall->flags &= ~EDGE_FALLTHRU;
687 e_taken->flags |= EDGE_FALLTHRU;
b446e5a2 688 update_br_prob_note (bb);
d56a8211
JH
689 e = e_fall, e_fall = e_taken, e_taken = e;
690 }
691 }
692
f87c27b4 693 /* Otherwise we can try to invert the jump. This will
d56a8211
JH
694 basically never fail, however, keep up the pretense. */
695 else if (invert_jump (bb_end_insn,
696 label_for_bb (e_fall->dest), 0))
697 {
698 e_fall->flags &= ~EDGE_FALLTHRU;
699 e_taken->flags |= EDGE_FALLTHRU;
b446e5a2 700 update_br_prob_note (bb);
d56a8211
JH
701 continue;
702 }
703 }
704 else if (returnjump_p (bb_end_insn))
705 continue;
706 else
707 {
708 /* Otherwise we have some switch or computed jump. In the
709 99% case, there should not have been a fallthru edge. */
710 if (! e_fall)
711 continue;
5f0d2358 712
d56a8211
JH
713#ifdef CASE_DROPS_THROUGH
714 /* Except for VAX. Since we didn't have predication for the
715 tablejump, the fallthru block should not have moved. */
bc35512f 716 if (bb->rbi->next == e_fall->dest)
d56a8211
JH
717 continue;
718 bb_end_insn = skip_insns_after_block (bb);
719#else
720 abort ();
721#endif
722 }
723 }
724 else
725 {
726 /* No fallthru implies a noreturn function with EH edges, or
727 something similarly bizarre. In any case, we don't need to
728 do anything. */
729 if (! e_fall)
730 continue;
731
732 /* If the fallthru block is still next, nothing to do. */
bc35512f 733 if (bb->rbi->next == e_fall->dest)
d56a8211
JH
734 continue;
735
5f0d2358 736 /* A fallthru to exit block. */
bc35512f 737 if (!bb->rbi->next && e_fall->dest == EXIT_BLOCK_PTR)
d56a8211
JH
738 continue;
739 }
740
741 /* We got here if we need to add a new jump insn. */
d56a8211 742 nb = force_nonfallthru (e_fall);
d56a8211
JH
743 if (nb)
744 {
bc35512f
JH
745 cfg_layout_initialize_rbi (nb);
746 nb->rbi->visited = 1;
747 nb->rbi->next = bb->rbi->next;
748 bb->rbi->next = nb;
d56a8211
JH
749 /* Don't process this new block. */
750 bb = nb;
751 }
752 }
753
754 /* Put basic_block_info in the new order. */
0b17ab2f 755
d56a8211 756 if (rtl_dump_file)
d56a8211 757 {
969d70ca 758 fprintf (rtl_dump_file, "Reordered sequence:\n");
bc35512f 759 for (bb = ENTRY_BLOCK_PTR->next_bb, index = 0; bb; bb = bb->rbi->next, index ++)
969d70ca
JH
760 {
761 fprintf (rtl_dump_file, " %i ", index);
bc35512f 762 if (bb->rbi->original)
969d70ca 763 fprintf (rtl_dump_file, "duplicate of %i ",
bc35512f 764 bb->rbi->original->index);
969d70ca
JH
765 else if (forwarder_block_p (bb) && GET_CODE (bb->head) != CODE_LABEL)
766 fprintf (rtl_dump_file, "compensation ");
767 else
0b17ab2f 768 fprintf (rtl_dump_file, "bb %i ", bb->index);
969d70ca
JH
769 fprintf (rtl_dump_file, " [%i]\n", bb->frequency);
770 }
771 }
5f0d2358 772
918ed612 773 prev_bb = ENTRY_BLOCK_PTR;
f6366fc7 774 bb = ENTRY_BLOCK_PTR->next_bb;
918ed612
ZD
775 index = 0;
776
bc35512f 777 for (; bb; prev_bb = bb, bb = bb->rbi->next, index ++)
969d70ca 778 {
0b17ab2f 779 bb->index = index;
d56a8211 780 BASIC_BLOCK (index) = bb;
918ed612
ZD
781
782 bb->prev_bb = prev_bb;
783 prev_bb->next_bb = bb;
d56a8211 784 }
918ed612
ZD
785 prev_bb->next_bb = EXIT_BLOCK_PTR;
786 EXIT_BLOCK_PTR->prev_bb = prev_bb;
bc35512f
JH
787
788 /* Anoying special case - jump around dead jumptables left in the code. */
789 FOR_EACH_BB (bb)
790 {
791 edge e;
792 for (e = bb->succ; e && !(e->flags & EDGE_FALLTHRU); e = e->succ_next)
793 continue;
794 if (e && !can_fallthru (e->src, e->dest))
795 force_nonfallthru (e);
796 }
d56a8211
JH
797}
798\f
799/* Perform sanity checks on the insn chain.
800 1. Check that next/prev pointers are consistent in both the forward and
801 reverse direction.
802 2. Count insns in chain, going both directions, and check if equal.
803 3. Check that get_last_insn () returns the actual end of chain. */
804
805void
d329e058 806verify_insn_chain (void)
d56a8211 807{
5f0d2358
RK
808 rtx x, prevx, nextx;
809 int insn_cnt1, insn_cnt2;
d56a8211 810
5f0d2358
RK
811 for (prevx = NULL, insn_cnt1 = 1, x = get_insns ();
812 x != 0;
813 prevx = x, insn_cnt1++, x = NEXT_INSN (x))
814 if (PREV_INSN (x) != prevx)
d56a8211 815 abort ();
d56a8211 816
5f0d2358
RK
817 if (prevx != get_last_insn ())
818 abort ();
d56a8211 819
5f0d2358
RK
820 for (nextx = NULL, insn_cnt2 = 1, x = get_last_insn ();
821 x != 0;
822 nextx = x, insn_cnt2++, x = PREV_INSN (x))
823 if (NEXT_INSN (x) != nextx)
d56a8211 824 abort ();
5f0d2358
RK
825
826 if (insn_cnt1 != insn_cnt2)
827 abort ();
d56a8211 828}
969d70ca
JH
829\f
830/* The block falling through to exit must be the last one in the
831 reordered chain. Ensure that this condition is met. */
d0225025 832static void
d329e058 833fixup_fallthru_exit_predecessor (void)
49778644
JH
834{
835 edge e;
836 basic_block bb = NULL;
837
838 for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
839 if (e->flags & EDGE_FALLTHRU)
840 bb = e->src;
5f0d2358 841
bc35512f 842 if (bb && bb->rbi->next)
49778644 843 {
f6366fc7 844 basic_block c = ENTRY_BLOCK_PTR->next_bb;
5f0d2358 845
bc35512f
JH
846 while (c->rbi->next != bb)
847 c = c->rbi->next;
5f0d2358 848
bc35512f
JH
849 c->rbi->next = bb->rbi->next;
850 while (c->rbi->next)
851 c = c->rbi->next;
5f0d2358 852
bc35512f
JH
853 c->rbi->next = bb;
854 bb->rbi->next = NULL;
49778644
JH
855 }
856}
d56a8211 857\f
969d70ca
JH
858/* Return true in case it is possible to duplicate the basic block BB. */
859
860bool
d329e058 861cfg_layout_can_duplicate_bb_p (basic_block bb)
969d70ca 862{
969d70ca
JH
863 edge s;
864
865 if (bb == EXIT_BLOCK_PTR || bb == ENTRY_BLOCK_PTR)
866 return false;
867
09da1532 868 /* Duplicating fallthru block to exit would require adding a jump
969d70ca
JH
869 and splitting the real last BB. */
870 for (s = bb->succ; s; s = s->succ_next)
871 if (s->dest == EXIT_BLOCK_PTR && s->flags & EDGE_FALLTHRU)
872 return false;
873
874 /* Do not attempt to duplicate tablejumps, as we need to unshare
95bd1dd7 875 the dispatch table. This is difficult to do, as the instructions
969d70ca 876 computing jump destination may be hoisted outside the basic block. */
e1233a7d 877 if (tablejump_p (bb->end, NULL, NULL))
969d70ca 878 return false;
0b077eac
RH
879
880 /* Do not duplicate blocks containing insns that can't be copied. */
881 if (targetm.cannot_copy_insn_p)
882 {
883 rtx insn = bb->head;
884 while (1)
885 {
886 if (INSN_P (insn) && (*targetm.cannot_copy_insn_p) (insn))
887 return false;
888 if (insn == bb->end)
889 break;
890 insn = NEXT_INSN (insn);
891 }
892 }
893
969d70ca
JH
894 return true;
895}
896
897static rtx
d329e058 898duplicate_insn_chain (rtx from, rtx to)
969d70ca
JH
899{
900 rtx insn, last;
901
902 /* Avoid updating of boundaries of previous basic block. The
903 note will get removed from insn stream in fixup. */
2e040219 904 last = emit_note (NOTE_INSN_DELETED);
969d70ca
JH
905
906 /* Create copy at the end of INSN chain. The chain will
907 be reordered later. */
908 for (insn = from; insn != NEXT_INSN (to); insn = NEXT_INSN (insn))
909 {
969d70ca
JH
910 switch (GET_CODE (insn))
911 {
912 case INSN:
913 case CALL_INSN:
914 case JUMP_INSN:
915 /* Avoid copying of dispatch tables. We never duplicate
916 tablejumps, so this can hit only in case the table got
917 moved far from original jump. */
918 if (GET_CODE (PATTERN (insn)) == ADDR_VEC
919 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
920 break;
4977bab6 921 emit_copy_of_insn_after (insn, get_last_insn ());
969d70ca
JH
922 break;
923
924 case CODE_LABEL:
925 break;
926
927 case BARRIER:
928 emit_barrier ();
929 break;
930
931 case NOTE:
932 switch (NOTE_LINE_NUMBER (insn))
933 {
934 /* In case prologue is empty and function contain label
935 in first BB, we may want to copy the block. */
936 case NOTE_INSN_PROLOGUE_END:
937
938 case NOTE_INSN_LOOP_VTOP:
939 case NOTE_INSN_LOOP_CONT:
940 case NOTE_INSN_LOOP_BEG:
941 case NOTE_INSN_LOOP_END:
942 /* Strip down the loop notes - we don't really want to keep
943 them consistent in loop copies. */
944 case NOTE_INSN_DELETED:
945 case NOTE_INSN_DELETED_LABEL:
946 /* No problem to strip these. */
947 case NOTE_INSN_EPILOGUE_BEG:
948 case NOTE_INSN_FUNCTION_END:
949 /* Debug code expect these notes to exist just once.
950 Keep them in the master copy.
951 ??? It probably makes more sense to duplicate them for each
952 epilogue copy. */
953 case NOTE_INSN_FUNCTION_BEG:
954 /* There is always just single entry to function. */
955 case NOTE_INSN_BASIC_BLOCK:
956 break;
957
958 /* There is no purpose to duplicate prologue. */
959 case NOTE_INSN_BLOCK_BEG:
960 case NOTE_INSN_BLOCK_END:
961 /* The BLOCK_BEG/BLOCK_END notes should be eliminated when BB
962 reordering is in the progress. */
963 case NOTE_INSN_EH_REGION_BEG:
964 case NOTE_INSN_EH_REGION_END:
969d70ca
JH
965 /* Should never exist at BB duplication time. */
966 abort ();
967 break;
968 case NOTE_INSN_REPEATED_LINE_NUMBER:
5f2fc772 969 emit_note_copy (insn);
969d70ca
JH
970 break;
971
972 default:
973 if (NOTE_LINE_NUMBER (insn) < 0)
974 abort ();
975 /* It is possible that no_line_number is set and the note
976 won't be emitted. */
5f2fc772 977 emit_note_copy (insn);
969d70ca
JH
978 }
979 break;
980 default:
981 abort ();
982 }
983 }
984 insn = NEXT_INSN (last);
985 delete_insn (last);
986 return insn;
987}
09da1532 988/* Create a duplicate of the basic block BB and redirect edge E into it. */
969d70ca
JH
989
990basic_block
d329e058 991cfg_layout_duplicate_bb (basic_block bb, edge e)
969d70ca
JH
992{
993 rtx insn;
994 edge s, n;
995 basic_block new_bb;
996 gcov_type new_count = e ? e->count : 0;
997
998 if (bb->count < new_count)
999 new_count = bb->count;
1000 if (!bb->pred)
1001 abort ();
1002#ifdef ENABLE_CHECKING
1003 if (!cfg_layout_can_duplicate_bb_p (bb))
1004 abort ();
1005#endif
1006
1007 insn = duplicate_insn_chain (bb->head, bb->end);
918ed612 1008 new_bb = create_basic_block (insn,
f87c27b4 1009 insn ? get_last_insn () : NULL,
918ed612 1010 EXIT_BLOCK_PTR->prev_bb);
969d70ca 1011
bc35512f 1012 if (bb->rbi->header)
969d70ca 1013 {
bc35512f 1014 insn = bb->rbi->header;
969d70ca
JH
1015 while (NEXT_INSN (insn))
1016 insn = NEXT_INSN (insn);
bc35512f 1017 insn = duplicate_insn_chain (bb->rbi->header, insn);
969d70ca 1018 if (insn)
bc35512f 1019 new_bb->rbi->header = unlink_insn_chain (insn, get_last_insn ());
969d70ca
JH
1020 }
1021
bc35512f 1022 if (bb->rbi->footer)
969d70ca 1023 {
bc35512f 1024 insn = bb->rbi->footer;
969d70ca
JH
1025 while (NEXT_INSN (insn))
1026 insn = NEXT_INSN (insn);
bc35512f 1027 insn = duplicate_insn_chain (bb->rbi->footer, insn);
969d70ca 1028 if (insn)
bc35512f 1029 new_bb->rbi->footer = unlink_insn_chain (insn, get_last_insn ());
969d70ca
JH
1030 }
1031
1032 if (bb->global_live_at_start)
1033 {
1034 new_bb->global_live_at_start = OBSTACK_ALLOC_REG_SET (&flow_obstack);
1035 new_bb->global_live_at_end = OBSTACK_ALLOC_REG_SET (&flow_obstack);
1036 COPY_REG_SET (new_bb->global_live_at_start, bb->global_live_at_start);
1037 COPY_REG_SET (new_bb->global_live_at_end, bb->global_live_at_end);
1038 }
1039
1040 new_bb->loop_depth = bb->loop_depth;
1041 new_bb->flags = bb->flags;
1042 for (s = bb->succ; s; s = s->succ_next)
1043 {
e0fd3e7a
MM
1044 /* Since we are creating edges from a new block to successors
1045 of another block (which therefore are known to be disjoint), there
1046 is no need to actually check for duplicated edges. */
1047 n = unchecked_make_edge (new_bb, s->dest, s->flags);
969d70ca
JH
1048 n->probability = s->probability;
1049 if (new_count)
1050 /* Take care for overflows! */
1051 n->count = s->count * (new_count * 10000 / bb->count) / 10000;
1052 else
1053 n->count = 0;
1054 s->count -= n->count;
1055 }
1056
1057 new_bb->count = new_count;
1058 bb->count -= new_count;
1059
1060 if (e)
f87c27b4
KH
1061 {
1062 new_bb->frequency = EDGE_FREQUENCY (e);
1063 bb->frequency -= EDGE_FREQUENCY (e);
969d70ca 1064
9ee634e3 1065 redirect_edge_and_branch_force (e, new_bb);
f87c27b4 1066 }
969d70ca
JH
1067
1068 if (bb->count < 0)
1069 bb->count = 0;
1070 if (bb->frequency < 0)
1071 bb->frequency = 0;
1072
bc35512f
JH
1073 new_bb->rbi->original = bb;
1074 bb->rbi->copy = new_bb;
969d70ca
JH
1075 return new_bb;
1076}
1077\f
bc35512f
JH
1078void
1079cfg_layout_initialize_rbi (bb)
1080 basic_block bb;
1081{
1082 if (bb->rbi)
1083 abort ();
1084 bb->rbi = pool_alloc (cfg_layout_pool);
1085 memset (bb->rbi, 0, sizeof (struct reorder_block_def));
1086}
1087\f
969d70ca
JH
1088/* Main entry point to this module - initialize the datastructures for
1089 CFG layout changes. It keeps LOOPS up-to-date if not null. */
d56a8211
JH
1090
1091void
bc35512f 1092cfg_layout_initialize ()
d56a8211 1093{
bc35512f
JH
1094 basic_block bb;
1095
969d70ca
JH
1096 /* Our algorithm depends on fact that there are now dead jumptables
1097 around the code. */
bc35512f
JH
1098 cfg_layout_pool =
1099 create_alloc_pool ("cfg layout pool", sizeof (struct reorder_block_def),
1100 n_basic_blocks + 2);
1101 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1102 cfg_layout_initialize_rbi (bb);
d56a8211 1103
bc35512f 1104 cfg_layout_rtl_register_cfg_hooks ();
6c81a490 1105
d56a8211 1106 record_effective_endpoints ();
bc35512f
JH
1107
1108 cleanup_cfg (CLEANUP_CFGLAYOUT);
d56a8211
JH
1109}
1110
3d436d2a
ZD
1111/* Splits superblocks. */
1112static void
d329e058 1113break_superblocks (void)
3d436d2a
ZD
1114{
1115 sbitmap superblocks;
1116 int i, need;
1117
1118 superblocks = sbitmap_alloc (n_basic_blocks);
1119 sbitmap_zero (superblocks);
1120
1121 need = 0;
1122
1123 for (i = 0; i < n_basic_blocks; i++)
1124 if (BASIC_BLOCK(i)->flags & BB_SUPERBLOCK)
1125 {
1126 BASIC_BLOCK(i)->flags &= ~BB_SUPERBLOCK;
1127 SET_BIT (superblocks, i);
1128 need = 1;
1129 }
1130
1131 if (need)
1132 {
1133 rebuild_jump_labels (get_insns ());
1134 find_many_sub_basic_blocks (superblocks);
1135 }
1136
1137 free (superblocks);
1138}
1139
5f0d2358
RK
1140/* Finalize the changes: reorder insn list according to the sequence, enter
1141 compensation code, rebuild scope forest. */
d56a8211
JH
1142
1143void
d329e058 1144cfg_layout_finalize (void)
d56a8211 1145{
bc35512f
JH
1146 basic_block bb;
1147
10e9fecc
JH
1148#ifdef ENABLE_CHECKING
1149 verify_flow_info ();
1150#endif
9ee634e3 1151 rtl_register_cfg_hooks ();
d0225025 1152 fixup_fallthru_exit_predecessor ();
d56a8211 1153 fixup_reorder_chain ();
5f0d2358 1154
d56a8211
JH
1155#ifdef ENABLE_CHECKING
1156 verify_insn_chain ();
1157#endif
1158
bc35512f
JH
1159 free_alloc_pool (cfg_layout_pool);
1160 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1161 bb->rbi = NULL;
d56a8211 1162
3d436d2a
ZD
1163 break_superblocks ();
1164
d56a8211
JH
1165#ifdef ENABLE_CHECKING
1166 verify_flow_info ();
1167#endif
1168}
0435312e
JH
1169
1170#include "gt-cfglayout.h"
This page took 0.515978 seconds and 5 git commands to generate.