diff options
author | Richard Henderson <rth@cygnus.com> | 2000-01-28 14:22:50 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2000-01-28 14:22:50 -0800 |
commit | 19d3c25c9a4da9526a2012b47d14bc731fd0422e (patch) | |
tree | 838b5c749cb462341ad1b64dc6cc0bd1daa6820f /gcc/flow.c | |
parent | 47e6ea667d23d2fd20ad3664e39654cc8a44502f (diff) | |
download | gcc-19d3c25c9a4da9526a2012b47d14bc731fd0422e.zip gcc-19d3c25c9a4da9526a2012b47d14bc731fd0422e.tar.gz gcc-19d3c25c9a4da9526a2012b47d14bc731fd0422e.tar.bz2 |
flow.c (find_basic_blocks): Remove do_cleanup argument.
* flow.c (find_basic_blocks): Remove do_cleanup argument.
Break out that code ...
(cleanup_cfg): ... here.
(commit_one_edge_insertion): Detect a return instruction being
emitted to an edge. Emit a barrier following; clear fallthru.
(commit_edge_insertions): Verify CFG consistency.
* function.c (expand_function_start): Kill unused variable.
(expand_function_end): Likewise.
(thread_prologue_and_epilogue_insns): Use insert_insn_on_edge
to insert the epilogue.
* gcse.c (gcse_main): Adjust for find_basic_blocks change.
(delete_null_pointer_checks): Likewise.
* output.h: Likewise.
* reg-stack.c (reg_to_stack): Likewise.
* toplev.c (rest_of_compilation): Likewise. Run
thread_prologue_and_epilogue_insns after rebuilding the CFG.
From-SVN: r31676
Diffstat (limited to 'gcc/flow.c')
-rw-r--r-- | gcc/flow.c | 77 |
1 files changed, 52 insertions, 25 deletions
@@ -372,11 +372,10 @@ int flow_loop_outside_edge_p PARAMS ((const struct loop *, edge)); numbers in use. */ void -find_basic_blocks (f, nregs, file, do_cleanup) +find_basic_blocks (f, nregs, file) rtx f; int nregs ATTRIBUTE_UNUSED; FILE *file ATTRIBUTE_UNUSED; - int do_cleanup; { int max_uid; @@ -425,23 +424,8 @@ find_basic_blocks (f, nregs, file, do_cleanup) compute_bb_for_insn (max_uid); /* Discover the edges of our cfg. */ - record_active_eh_regions (f); make_edges (label_value_list); - - /* Delete unreachable blocks, then merge blocks when possible. */ - - if (do_cleanup) - { - delete_unreachable_blocks (); - move_stray_eh_region_notes (); - record_active_eh_regions (f); - if (optimize) - try_merge_blocks (); - } - - /* Mark critical edges. */ - mark_critical_edges (); /* Kill the data we won't maintain. */ @@ -740,6 +724,19 @@ find_basic_blocks_1 (f) return label_value_list; } +/* Tidy the CFG by deleting unreachable code and whatnot. */ + +void +cleanup_cfg (f) + rtx f; +{ + delete_unreachable_blocks (); + move_stray_eh_region_notes (); + record_active_eh_regions (f); + try_merge_blocks (); + mark_critical_edges (); +} + /* Create a new basic block consisting of the instructions between HEAD and END inclusive. Reuses the note and basic block struct in BB_NOTE, if any. */ @@ -1552,9 +1549,13 @@ static void commit_one_edge_insertion (e) edge e; { - rtx before = NULL_RTX, after = NULL_RTX, tmp; + rtx before = NULL_RTX, after = NULL_RTX, insns, tmp; basic_block bb; + /* Pull the insns off the edge now since the edge might go away. */ + insns = e->insns; + e->insns = NULL_RTX; + /* Figure out where to put these things. If the destination has one predecessor, insert there. Except for the exit block. */ if (e->dest->pred->pred_next == NULL @@ -1611,28 +1612,50 @@ commit_one_edge_insertion (e) } /* Now that we've found the spot, do the insertion. */ - tmp = e->insns; - e->insns = NULL_RTX; /* Set the new block number for these insns, if structure is allocated. */ if (basic_block_for_insn) { rtx i; - for (i = tmp; i != NULL_RTX; i = NEXT_INSN (i)) + for (i = insns; i != NULL_RTX; i = NEXT_INSN (i)) set_block_for_insn (i, bb); } if (before) { - emit_insns_before (tmp, before); + emit_insns_before (insns, before); if (before == bb->head) - bb->head = tmp; + bb->head = insns; } else { - tmp = emit_insns_after (tmp, after); + rtx last = emit_insns_after (insns, after); if (after == bb->end) - bb->end = tmp; + { + bb->end = last; + + if (GET_CODE (last) == JUMP_INSN) + { + if (returnjump_p (last)) + { + /* ??? Remove all outgoing edges from BB and add one + for EXIT. This is not currently a problem because + this only happens for the (single) epilogue, which + already has a fallthru edge to EXIT. */ + + e = bb->succ; + if (e->dest != EXIT_BLOCK_PTR + || e->succ_next != NULL + || (e->flags & EDGE_FALLTHRU) == 0) + abort (); + e->flags &= ~EDGE_FALLTHRU; + + emit_barrier_after (last); + } + else + abort (); + } + } } } @@ -1644,6 +1667,10 @@ commit_edge_insertions () int i; basic_block bb; +#ifdef ENABLE_CHECKING + verify_flow_info (); +#endif + i = -1; bb = ENTRY_BLOCK_PTR; while (1) |