aboutsummaryrefslogtreecommitdiff
path: root/gcc/unroll.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1995-07-28 09:57:46 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1995-07-28 09:57:46 -0400
commit7edd39eb80b5de5db5add3fa716e09be5dc42e47 (patch)
tree6d9bb870bd6633e92f9f2b6864d11a0933fcfa28 /gcc/unroll.c
parent185496bb2b6bd071b15c42c681b0c3d60390bce0 (diff)
downloadgcc-7edd39eb80b5de5db5add3fa716e09be5dc42e47.zip
gcc-7edd39eb80b5de5db5add3fa716e09be5dc42e47.tar.gz
gcc-7edd39eb80b5de5db5add3fa716e09be5dc42e47.tar.bz2
(unroll_loop): When preconditioning...
(unroll_loop): When preconditioning, output code to execute loop once if initial value is greater than or equal to final value. From-SVN: r10188
Diffstat (limited to 'gcc/unroll.c')
-rw-r--r--gcc/unroll.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/gcc/unroll.c b/gcc/unroll.c
index 4bc72ae..083f0ab 100644
--- a/gcc/unroll.c
+++ b/gcc/unroll.c
@@ -853,6 +853,19 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
for (i = 0; i < unroll_number; i++)
labels[i] = gen_label_rtx ();
+ /* Check for the case where the initial value is greater than or equal
+ to the final value. In that case, we want to execute exactly
+ one loop iteration. The code below will fail for this case. */
+
+ emit_cmp_insn (initial_value, final_value, neg_inc ? LE : GE,
+ NULL_RTX, mode, 0, 0);
+ if (neg_inc)
+ emit_jump_insn (gen_ble (labels[1]));
+ else
+ emit_jump_insn (gen_bge (labels[1]));
+ JUMP_LABEL (get_last_insn ()) = labels[1];
+ LABEL_NUSES (labels[1])++;
+
/* Assuming the unroll_number is 4, and the increment is 2, then
for a negative increment: for a positive increment:
diff = 0,1 precond 0 diff = 0,7 precond 0
@@ -869,18 +882,28 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
for (i = 0; i < unroll_number - 1; i++)
{
int cmp_const;
+ enum rtx_code cmp_code;
/* For negative increments, must invert the constant compared
against, except when comparing against zero. */
if (i == 0)
- cmp_const = 0;
+ {
+ cmp_const = 0;
+ cmp_code = EQ;
+ }
else if (neg_inc)
- cmp_const = unroll_number - i;
+ {
+ cmp_const = unroll_number - i;
+ cmp_code = GE;
+ }
else
- cmp_const = i;
+ {
+ cmp_const = i;
+ cmp_code = LE;
+ }
emit_cmp_insn (diff, GEN_INT (abs_inc * cmp_const),
- EQ, NULL_RTX, mode, 0, 0);
+ cmp_code, NULL_RTX, mode, 0, 0);
if (i == 0)
emit_jump_insn (gen_beq (labels[i]));
@@ -904,13 +927,20 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
if (abs_inc != 1)
{
int cmp_const;
+ enum rtx_code cmp_code;
if (neg_inc)
- cmp_const = abs_inc - 1;
+ {
+ cmp_const = abs_inc - 1;
+ cmp_code = LE;
+ }
else
- cmp_const = abs_inc * (unroll_number - 1) + 1;
+ {
+ cmp_const = abs_inc * (unroll_number - 1) + 1;
+ cmp_code = GE;
+ }
- emit_cmp_insn (diff, GEN_INT (cmp_const), EQ, NULL_RTX,
+ emit_cmp_insn (diff, GEN_INT (cmp_const), cmp_code, NULL_RTX,
mode, 0, 0);
if (neg_inc)