summaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-14 12:09:08 +0000
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-14 12:09:08 +0000
commit9bb8a4af63c2dc43b16aad632a9c8c723235d554 (patch)
treea37b5ac1c93cff4befd42e4070615ba42213a250 /gcc/function.c
parent41d51689c2f60e3a0489e31d6ecb5f2a784fc357 (diff)
downloadgcc-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.c42
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)