diff options
author | amylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-14 12:09:08 +0000 |
---|---|---|
committer | amylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-14 12:09:08 +0000 |
commit | 9bb8a4af63c2dc43b16aad632a9c8c723235d554 (patch) | |
tree | a37b5ac1c93cff4befd42e4070615ba42213a250 /gcc/function.c | |
parent | 41d51689c2f60e3a0489e31d6ecb5f2a784fc357 (diff) | |
download | gcc-9bb8a4af63c2dc43b16aad632a9c8c723235d554.tar.gz |
* basic-block.h (could_fall_through): Declare.
* cfganal.c (can_fallthru): Succeed if the target is EXIT_BLOCK_PTR.
Fail if the source already has a fallthrough edge to the exit
block pointer.
(could_fall_through): New function.
* cfgbuild.c (make_edges): Check if we already have a fallthrough
edge to the exit block pointer.
* cfglayout.c (fixup_fallthru_exit_predecessor): Check that it is
not called before reload has completed.
Handle special case of first block having a fall-through exit edge.
(cfg_layout_finalize): Don't call it before reload or if we have
rtl epilogues.
(fixup_reorder_chain): A fall through to the exit block does not
require the block to come last. Add sanity checks.
* cfgrtl.c (rtl_split_edge): Add special handling of fall through
edges to the exit block.
* function.c (cfglayout.h): #include.
(thread_prologue_and_epilogue_insns): If we have neither return nor
epilogue, but a fall through to the exit block from mid-function,
force a non-fall-through exit.
* Makefile.in (function.o): Depend on CFGLAYOUT_H.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83089 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/function.c')
-rw-r--r-- | gcc/function.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/gcc/function.c b/gcc/function.c index 00c56e322af..b59da9a4160 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -63,6 +63,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "integrate.h" #include "langhooks.h" #include "target.h" +#include "cfglayout.h" #ifndef LOCAL_ALIGNMENT #define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT @@ -7558,20 +7559,20 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED) } } #endif + /* 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... */ + + for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next) + if (e->flags & EDGE_FALLTHRU) + break; + if (e == NULL) + goto epilogue_done; + #ifdef HAVE_epilogue if (HAVE_epilogue) { - /* 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... */ - - for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next) - if (e->flags & EDGE_FALLTHRU) - break; - if (e == NULL) - goto epilogue_done; - start_sequence (); epilogue_end = emit_note (NOTE_INSN_EPILOGUE_BEG); @@ -7597,7 +7598,26 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED) insert_insn_on_edge (seq, e); inserted = 1; } + else #endif + { + basic_block cur_bb; + + if (! next_active_insn (BB_END (e->src))) + goto epilogue_done; + /* We have a fall-through edge to the exit block, the source is not + at the end of the function, and there will be an assembler epilogue + at the end of the function. + We can't use force_nonfallthru here, because that would try to + use return. Inserting a jump 'by hand' is extremely messy, so + we take advantage of cfg_layout_finalize using + fixup_fallthru_exit_predecessor. */ + cfg_layout_initialize (); + FOR_EACH_BB (cur_bb) + if (cur_bb->index >= 0 && cur_bb->next_bb->index >= 0) + cur_bb->rbi->next = cur_bb->next_bb; + cfg_layout_finalize (); + } epilogue_done: if (inserted) |