summaryrefslogtreecommitdiff
path: root/gcc/loop-unroll.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/loop-unroll.c')
-rw-r--r--gcc/loop-unroll.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index 7d230fb6f3a..2f6f3ba2ad9 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -899,13 +899,18 @@ decide_unroll_runtime_iterations (struct loop *loop, int flags)
loop->lpt_decision.times);
}
-/* Splits edge E and inserts INSNS on it. */
+/* Splits edge E and inserts the sequence of instructions INSNS on it, and
+ returns the newly created block. If INSNS is NULL_RTX, nothing is changed
+ and NULL is returned instead. */
basic_block
split_edge_and_insert (edge e, rtx insns)
{
- basic_block bb = split_edge (e);
- gcc_assert (insns != NULL_RTX);
+ basic_block bb;
+
+ if (!insns)
+ return NULL;
+ bb = split_edge (e);
emit_insn_after (insns, BB_END (bb));
bb->flags |= BB_SUPERBLOCK;
return bb;
@@ -1069,6 +1074,10 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
block_label (preheader), p,
NULL_RTX);
+ /* We rely on the fact that the compare and jump cannot be optimized out,
+ and hence the cfg we create is correct. */
+ gcc_assert (branch_code != NULL_RTX);
+
swtch = split_edge_and_insert (single_pred_edge (swtch), branch_code);
set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
single_pred_edge (swtch)->probability = REG_BR_PROB_BASE - p;
@@ -1086,6 +1095,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
branch_code = compare_and_jump_seq (copy_rtx (niter), const0_rtx, EQ,
block_label (preheader), p,
NULL_RTX);
+ gcc_assert (branch_code != NULL_RTX);
swtch = split_edge_and_insert (single_succ_edge (swtch), branch_code);
set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);