aboutsummaryrefslogtreecommitdiff
path: root/gcc/flow.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>2000-01-28 14:22:50 -0800
committerRichard Henderson <rth@gcc.gnu.org>2000-01-28 14:22:50 -0800
commit19d3c25c9a4da9526a2012b47d14bc731fd0422e (patch)
tree838b5c749cb462341ad1b64dc6cc0bd1daa6820f /gcc/flow.c
parent47e6ea667d23d2fd20ad3664e39654cc8a44502f (diff)
downloadgcc-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.c77
1 files changed, 52 insertions, 25 deletions
diff --git a/gcc/flow.c b/gcc/flow.c
index 008f0c2..0578bef 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -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)