summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/loop-doloop.c6
-rw-r--r--gcc/loop-unroll.c16
3 files changed, 26 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1ed3890c8e4..8666acc058c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
2006-11-22 Zdenek Dvorak <dvorakz@suse.cz>
+ PR rtl-optimization/29924
+ * loop-unroll.c (split_edge_and_insert): Handle the case insns is NULL.
+ (unroll_loop_runtime_iterations): Assert that the argument passed to
+ split_edge_and_insert is not NULL.
+ * loop-doloop.c (add_test): Ditto.
+
+2006-11-22 Zdenek Dvorak <dvorakz@suse.cz>
+
* tree-loop-linear.c (linear_transform_loops): Use single_exit accessor
functions.
* tree-ssa-loop-niter.c (loop_only_exit_p): Ditto.
diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
index afe65cb7d28..004dcfe72f8 100644
--- a/gcc/loop-doloop.c
+++ b/gcc/loop-doloop.c
@@ -248,7 +248,7 @@ add_test (rtx cond, edge *e, basic_block dest)
do_compare_rtx_and_jump (op0, op1, code, 0, mode, NULL_RTX, NULL_RTX, label);
jump = get_last_insn ();
- if (!JUMP_P (jump))
+ if (!jump || !JUMP_P (jump))
{
/* The condition is always false and the jump was optimized out. */
end_sequence ();
@@ -257,6 +257,10 @@ add_test (rtx cond, edge *e, basic_block dest)
seq = get_insns ();
end_sequence ();
+
+ /* There always is at least the jump insn in the sequence. */
+ gcc_assert (seq != NULL_RTX);
+
bb = split_edge_and_insert (*e, seq);
*e = single_succ_edge (bb);
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);