aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfglayout.c
diff options
context:
space:
mode:
authorSteven Bosscher <steven@gcc.gnu.org>2007-03-23 23:05:28 +0000
committerSteven Bosscher <steven@gcc.gnu.org>2007-03-23 23:05:28 +0000
commitad21dab7f7977e9741b7bdace4645ae365f45b01 (patch)
treea15eb2e5e903aed64b074a1be1be2b4bb4d71136 /gcc/cfglayout.c
parent1f93ef9228b60d66677a2880c32c4b78b19400e7 (diff)
downloadgcc-ad21dab7f7977e9741b7bdace4645ae365f45b01.zip
gcc-ad21dab7f7977e9741b7bdace4645ae365f45b01.tar.gz
gcc-ad21dab7f7977e9741b7bdace4645ae365f45b01.tar.bz2
tracer.c (tracer): Don't take FLAGS argument.
* tracer.c (tracer): Don't take FLAGS argument. Assert we are in cfglayout mode. Don't go into and out of cfglayout mode. Link the blocks in the order of the constructed traces. (rest_of_handle_tracer): Adjust call to tracer. * loop-init.c (rtl_loop_init): Assert we are in cfglayout mode. Don't go into cfglayout mode. (rtl_loop_done): Don't go out of cfglayout mode. * cfglayout.c (relink_block_chain): New function, split out from... (fixup_reorder_chain): ...here. Remove redundant checking. (cfg_layout_finalize): Don't clear the header, footer, and aux fields here, move the code to do so to relink_block_chain. Likewise for free_original_copy_tables. * rtl.h (tracer): Update prototype. * bb-reorder.c (reorder_basic_blocks): Don't take FLAGS argument. Assert we are in cfglayout mode. Don't go into and out of cfglayout mode. Use relink_block_chain to serialize the CFG according to the new basic block order. Move targetm.cannot_modify_jumps_p check from here... (gate_handle_reorder_blocks): ...to here. (duplicate_computed_gotos): Move targetm.cannot_modify_jumps_p check from here... (gate_duplicate_computed_gotos): ...to here. (rest_of_handle_reorder_blocks): Don't see if anything has changed, something always changes when going into and out of cfglayout mode. Perform an expensive cfg cleanup while going into cfglayout mode. Always update liveness information on HAVE_conditional_execution targets. Reserialize the basic blocks and go out of cfglayout mode. * reg-stack.c: Include cfglayout.h. (rest_of_handle_stack_regs): Go into and out of cfglayout mode around the call to reorder_basic_blocks. * basic-block.h (reorder_basic_blocks): Update prototype. (relink_block_chain): New prototype. * passes.c (pass_outof_cfg_layout_mode): Move after cse2. From-SVN: r123167
Diffstat (limited to 'gcc/cfglayout.c')
-rw-r--r--gcc/cfglayout.c130
1 files changed, 74 insertions, 56 deletions
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index ef085fc..0178431 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -634,13 +634,83 @@ reemit_insn_block_notes (void)
reorder_blocks ();
}
+
+/* Link the basic blocks in the correct order, compacting the basic
+ block queue while at it. This also clears the visited flag on
+ all basic blocks. If STAY_IN_CFGLAYOUT_MODE is false, this function
+ also clears the basic block header and footer fields.
+
+ This function is usually called after a pass (e.g. tracer) finishes
+ some transformations while in cfglayout mode. The required sequence
+ of the basic blocks is in a linked list along the bb->aux field.
+ This functions re-links the basic block prev_bb and next_bb pointers
+ accordingly, and it compacts and renumbers the blocks. */
+
+void
+relink_block_chain (bool stay_in_cfglayout_mode)
+{
+ basic_block bb, prev_bb;
+ int index;
+
+ /* Maybe dump the re-ordered sequence. */
+ if (dump_file)
+ {
+ fprintf (dump_file, "Reordered sequence:\n");
+ for (bb = ENTRY_BLOCK_PTR->next_bb, index = NUM_FIXED_BLOCKS;
+ bb;
+ bb = bb->aux, index++)
+ {
+ fprintf (dump_file, " %i ", index);
+ if (get_bb_original (bb))
+ fprintf (dump_file, "duplicate of %i ",
+ get_bb_original (bb)->index);
+ else if (forwarder_block_p (bb)
+ && !LABEL_P (BB_HEAD (bb)))
+ fprintf (dump_file, "compensation ");
+ else
+ fprintf (dump_file, "bb %i ", bb->index);
+ fprintf (dump_file, " [%i]\n", bb->frequency);
+ }
+ }
+
+ /* Now reorder the blocks. */
+ prev_bb = ENTRY_BLOCK_PTR;
+ bb = ENTRY_BLOCK_PTR->next_bb;
+ for (; bb; prev_bb = bb, bb = bb->aux)
+ {
+ bb->prev_bb = prev_bb;
+ prev_bb->next_bb = bb;
+ }
+ prev_bb->next_bb = EXIT_BLOCK_PTR;
+ EXIT_BLOCK_PTR->prev_bb = prev_bb;
+
+ /* Then, clean up the aux and visited fields. */
+ FOR_ALL_BB (bb)
+ {
+ bb->aux = NULL;
+ bb->il.rtl->visited = 0;
+ if (!stay_in_cfglayout_mode)
+ bb->il.rtl->header = bb->il.rtl->footer = NULL;
+ }
+
+ /* Maybe reset the original copy tables, they are not valid anymore
+ when we renumber the basic blocks in compact_blocks. If we are
+ are going out of cfglayout mode, don't re-allocate the tables. */
+ free_original_copy_tables ();
+ if (stay_in_cfglayout_mode)
+ initialize_original_copy_tables ();
+
+ /* Finally, put basic_block_info in the new order. */
+ compact_blocks ();
+}
+
+
/* Given a reorder chain, rearrange the code to match. */
static void
fixup_reorder_chain (void)
{
- basic_block bb, prev_bb;
- int index;
+ basic_block bb;
rtx insn = NULL;
if (cfg_layout_function_header)
@@ -654,9 +724,7 @@ fixup_reorder_chain (void)
/* First do the bulk reordering -- rechain the blocks without regard to
the needed changes to jumps and labels. */
- for (bb = ENTRY_BLOCK_PTR->next_bb, index = NUM_FIXED_BLOCKS;
- bb != 0;
- bb = bb->aux, index++)
+ for (bb = ENTRY_BLOCK_PTR->next_bb; bb; bb = bb->aux)
{
if (bb->il.rtl->header)
{
@@ -684,8 +752,6 @@ fixup_reorder_chain (void)
}
}
- gcc_assert (index == n_basic_blocks);
-
NEXT_INSN (insn) = cfg_layout_function_footer;
if (cfg_layout_function_footer)
PREV_INSN (cfg_layout_function_footer) = insn;
@@ -837,42 +903,7 @@ fixup_reorder_chain (void)
}
}
- /* Put basic_block_info in the new order. */
-
- if (dump_file)
- {
- fprintf (dump_file, "Reordered sequence:\n");
- for (bb = ENTRY_BLOCK_PTR->next_bb, index = NUM_FIXED_BLOCKS;
- bb;
- bb = bb->aux, index++)
- {
- fprintf (dump_file, " %i ", index);
- if (get_bb_original (bb))
- fprintf (dump_file, "duplicate of %i ",
- get_bb_original (bb)->index);
- else if (forwarder_block_p (bb)
- && !LABEL_P (BB_HEAD (bb)))
- fprintf (dump_file, "compensation ");
- else
- fprintf (dump_file, "bb %i ", bb->index);
- fprintf (dump_file, " [%i]\n", bb->frequency);
- }
- }
-
- prev_bb = ENTRY_BLOCK_PTR;
- bb = ENTRY_BLOCK_PTR->next_bb;
- index = NUM_FIXED_BLOCKS;
-
- for (; bb; prev_bb = bb, bb = bb->aux, index ++)
- {
- bb->index = index;
- SET_BASIC_BLOCK (index, bb);
-
- bb->prev_bb = prev_bb;
- prev_bb->next_bb = bb;
- }
- prev_bb->next_bb = EXIT_BLOCK_PTR;
- EXIT_BLOCK_PTR->prev_bb = prev_bb;
+ relink_block_chain (/*stay_in_cfglayout_mode=*/false);
/* Annoying special case - jump around dead jumptables left in the code. */
FOR_EACH_BB (bb)
@@ -1178,8 +1209,6 @@ break_superblocks (void)
void
cfg_layout_finalize (void)
{
- basic_block bb;
-
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif
@@ -1197,19 +1226,8 @@ cfg_layout_finalize (void)
#ifdef ENABLE_CHECKING
verify_insn_chain ();
-#endif
- FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
- {
- bb->il.rtl->header = bb->il.rtl->footer = NULL;
- bb->aux = NULL;
- bb->il.rtl->visited = 0;
- }
-
-#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif
-
- free_original_copy_tables ();
}
/* Checks whether all N blocks in BBS array can be copied. */