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/function.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/function.c')
-rw-r--r-- | gcc/function.c | 148 |
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 (); |