summaryrefslogtreecommitdiff
path: root/gcc/cfganal.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cfganal.c')
-rw-r--r--gcc/cfganal.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/gcc/cfganal.c b/gcc/cfganal.c
index f70c6c7b2fc..a64124cfb79 100644
--- a/gcc/cfganal.c
+++ b/gcc/cfganal.c
@@ -189,6 +189,36 @@ mark_dfs_back_edges ()
return found;
}
+/* Set the flag EDGE_CAN_FALLTHRU for edges that can be fallthru. */
+
+void
+set_edge_can_fallthru_flag ()
+{
+ int i;
+ for (i = 0; i < n_basic_blocks; i++)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+ edge e;
+
+ /* The FALLTHRU edge is also CAN_FALLTHRU edge. */
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->flags & EDGE_FALLTHRU)
+ e->flags |= EDGE_CAN_FALLTHRU;
+
+ /* If the BB ends with an invertable condjump all (2) edges are
+ CAN_FALLTHRU edges. */
+ if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next)
+ continue;
+ if (!any_condjump_p (bb->end))
+ continue;
+ if (!invert_jump (bb->end, JUMP_LABEL (bb->end), 0))
+ continue;
+ invert_jump (bb->end, JUMP_LABEL (bb->end), 0);
+ bb->succ->flags |= EDGE_CAN_FALLTHRU;
+ bb->succ->succ_next->flags |= EDGE_CAN_FALLTHRU;
+ }
+}
+
/* Return true if we need to add fake edge to exit.
Helper function for the flow_call_edges_add. */
@@ -326,9 +356,12 @@ flow_call_edges_add (blocks)
/* Note that the following may create a new basic block
and renumber the existing basic blocks. */
- e = split_block (bb, split_at_insn);
- if (e)
- blocks_split++;
+ if (split_at_insn != bb->end)
+ {
+ e = split_block (bb, split_at_insn);
+ if (e)
+ blocks_split++;
+ }
make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
}