summaryrefslogtreecommitdiff
path: root/gcc/cfganal.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/cfganal.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/cfganal.c')
-rw-r--r--gcc/cfganal.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/gcc/cfganal.c b/gcc/cfganal.c
index 1a7d280513f..c8675dca6e2 100644
--- a/gcc/cfganal.c
+++ b/gcc/cfganal.c
@@ -103,17 +103,42 @@ bool
can_fallthru (basic_block src, basic_block target)
{
rtx insn = BB_END (src);
- rtx insn2 = target == EXIT_BLOCK_PTR ? NULL : BB_HEAD (target);
+ rtx insn2;
+ edge e;
+ if (target == EXIT_BLOCK_PTR)
+ return true;
if (src->next_bb != target)
return 0;
+ for (e = src->succ; e; e = e->succ_next)
+ if (e->dest == EXIT_BLOCK_PTR
+ && e->flags & EDGE_FALLTHRU)
+ return 0;
+ insn2 = BB_HEAD (target);
if (insn2 && !active_insn_p (insn2))
insn2 = next_active_insn (insn2);
/* ??? Later we may add code to move jump tables offline. */
return next_active_insn (insn) == insn2;
}
+
+/* Return nonzero if we could reach target from src by falling through,
+ if the target was made adjacent. If we already have a fall-through
+ edge to the exit block, we can't do that. */
+bool
+could_fall_through (basic_block src, basic_block target)
+{
+ edge e;
+
+ if (target == EXIT_BLOCK_PTR)
+ return true;
+ for (e = src->succ; e; e = e->succ_next)
+ if (e->dest == EXIT_BLOCK_PTR
+ && e->flags & EDGE_FALLTHRU)
+ return 0;
+ return true;
+}
/* Mark the back edges in DFS traversal.
Return nonzero if a loop (natural or otherwise) is present.