aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.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/function.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/function.c')
-rw-r--r--gcc/function.c148
1 files changed, 32 insertions, 116 deletions
diff --git a/gcc/function.c b/gcc/function.c
index 8339208..960fd1c 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -5867,7 +5867,6 @@ expand_function_start (subr, parms_have_cleanups)
tree subr;
int parms_have_cleanups;
{
- register int i;
tree tem;
rtx last_ptr = NULL_RTX;
@@ -6171,7 +6170,6 @@ expand_function_end (filename, line, end_bindings)
int line;
int end_bindings;
{
- register int i;
tree link;
#ifdef TRAMPOLINE_TEMPLATE
@@ -6546,12 +6544,12 @@ thread_prologue_and_epilogue_insns (f)
rtx f ATTRIBUTE_UNUSED;
{
int insertted = 0;
+ edge e;
+ rtx seq;
#ifdef HAVE_prologue
if (HAVE_prologue)
{
- rtx seq;
-
start_sequence ();
seq = gen_prologue();
emit_insn (seq);
@@ -6581,129 +6579,47 @@ thread_prologue_and_epilogue_insns (f)
}
#endif
+ /* If the exit block has no non-fake predecessors, we don't need
+ an epilogue. */
+ for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
+ if ((e->flags & EDGE_FAKE) == 0)
+ break;
+ if (e == NULL)
+ goto epilogue_done;
+
#ifdef HAVE_epilogue
if (HAVE_epilogue)
{
- edge e;
- basic_block bb = 0;
- rtx tail = get_last_insn ();
-
- /* ??? This is gastly. If function returns were not done via uses,
- but via mark_regs_live_at_end, we could use insert_insn_on_edge
- and all of this uglyness would go away. */
-
- switch (optimize)
- {
- default:
- /* If the exit block has no non-fake predecessors, we don't
- need an epilogue. Furthermore, only pay attention to the
- fallthru predecessors; if (conditional) return insns were
- generated, by definition we do not need to emit epilogue
- insns. */
-
- for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
- if ((e->flags & EDGE_FAKE) == 0
- && (e->flags & EDGE_FALLTHRU) != 0)
- break;
- if (e == NULL)
- break;
-
- /* We can't handle multiple epilogues -- if one is needed,
- we won't be able to place it multiple times.
-
- ??? Fix epilogue expanders to not assume they are the
- last thing done compiling the function. Either that
- or copy_rtx each insn.
-
- ??? Blah, it's not a simple expression to assert that
- we've exactly one fallthru exit edge. */
+ /* Find the edge that falls through to EXIT. Other edges may exist
+ due to RETURN instructions, but those don't need epilogues.
+ There really shouldn't be a mixture -- either all should have
+ been converted or none, however... */
- bb = e->src;
- tail = bb->end;
-
- /* ??? If the last insn of the basic block is a jump, then we
- are creating a new basic block. Wimp out and leave these
- insns outside any block. */
- if (GET_CODE (tail) == JUMP_INSN)
- bb = 0;
-
- /* FALLTHRU */
- case 0:
- {
- rtx prev, seq, first_use;
-
- /* Move the USE insns at the end of a function onto a list. */
- prev = tail;
- if (GET_CODE (prev) == BARRIER
- || GET_CODE (prev) == NOTE)
- prev = prev_nonnote_insn (prev);
-
- first_use = 0;
- if (prev
- && GET_CODE (prev) == INSN
- && GET_CODE (PATTERN (prev)) == USE)
- {
- /* If the end of the block is the use, grab hold of something
- else so that we emit barriers etc in the right place. */
- if (prev == tail)
- {
- do
- tail = PREV_INSN (tail);
- while (GET_CODE (tail) == INSN
- && GET_CODE (PATTERN (tail)) == USE);
- }
-
- do
- {
- rtx use = prev;
- prev = prev_nonnote_insn (prev);
-
- remove_insn (use);
- if (first_use)
- {
- NEXT_INSN (use) = first_use;
- PREV_INSN (first_use) = use;
- }
- else
- NEXT_INSN (use) = NULL_RTX;
- first_use = use;
- }
- while (prev
- && GET_CODE (prev) == INSN
- && GET_CODE (PATTERN (prev)) == USE);
- }
-
- /* The last basic block ends with a NOTE_INSN_EPILOGUE_BEG, the
- epilogue insns, the USE insns at the end of a function,
- the jump insn that returns, and then a BARRIER. */
+ for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
+ if (e->flags & EDGE_FALLTHRU)
+ break;
+ if (e == NULL)
+ goto epilogue_done;
- if (GET_CODE (tail) != BARRIER)
- {
- prev = next_nonnote_insn (tail);
- if (!prev || GET_CODE (prev) != BARRIER)
- emit_barrier_after (tail);
- }
+ start_sequence ();
+ emit_note (NULL, NOTE_INSN_EPILOGUE_BEG);
- seq = gen_epilogue ();
- prev = tail;
- tail = emit_jump_insn_after (seq, tail);
+ seq = gen_epilogue ();
+ emit_jump_insn (seq);
- /* Insert the USE insns immediately before the return insn, which
- must be the last instruction emitted in the sequence. */
- if (first_use)
- emit_insns_before (first_use, tail);
- emit_note_after (NOTE_INSN_EPILOGUE_BEG, prev);
+ /* Retain a map of the epilogue insns. */
+ if (GET_CODE (seq) != SEQUENCE)
+ seq = get_insns ();
+ epilogue = record_insns (seq);
- /* Update the tail of the basic block. */
- if (bb)
- bb->end = tail;
+ seq = gen_sequence ();
+ end_sequence();
- /* Retain a map of the epilogue insns. */
- epilogue = record_insns (GET_CODE (seq) == SEQUENCE ? seq : tail);
- }
- }
+ insert_insn_on_edge (seq, e);
+ insertted = 1;
}
#endif
+epilogue_done:
if (insertted)
commit_edge_insertions ();