Commit 0228d06b by Alan Modra Committed by Alan Modra

doloop.c (doloop_valid_p): Correct comment.

	* doloop.c (doloop_valid_p): Correct comment.
	(doloop_modify_runtime <abs_inc != 1>): Simplify.
	(doloop_modify_runtime <do-while>): Don't emit code when NE.

From-SVN: r54938
parent 17ba19fe
2002-06-24 Alan Modra <amodra@bigpond.net.au>
* doloop.c (doloop_valid_p): Correct comment.
(doloop_modify_runtime <abs_inc != 1>): Simplify.
(doloop_modify_runtime <do-while>): Don't emit code when NE.
Thu Jun 20 00:26:53 2002 Denis Chertykov <denisc@overta.ru> Thu Jun 20 00:26:53 2002 Denis Chertykov <denisc@overta.ru>
* config.gcc: Add support for ip2k. * config.gcc: Add support for ip2k.
......
...@@ -361,8 +361,8 @@ doloop_valid_p (loop, jump_insn) ...@@ -361,8 +361,8 @@ doloop_valid_p (loop, jump_insn)
{ {
/* If the comparison is LEU and the comparison value is UINT_MAX /* If the comparison is LEU and the comparison value is UINT_MAX
then the loop will not terminate. Similarly, if the then the loop will not terminate. Similarly, if the
comparison code is GEU and the initial value is 0, the loop comparison code is GEU and the comparison value is 0, the
will not terminate. loop will not terminate.
If the absolute increment is not 1, the loop can be infinite If the absolute increment is not 1, the loop can be infinite
even with LTU/GTU, e.g. for (i = 3; i > 0; i -= 2) even with LTU/GTU, e.g. for (i = 3; i > 0; i -= 2)
...@@ -591,6 +591,10 @@ doloop_modify_runtime (loop, iterations_max, ...@@ -591,6 +591,10 @@ doloop_modify_runtime (loop, iterations_max,
n = abs (final - initial) / abs_inc; n = abs (final - initial) / abs_inc;
n += (abs (final - initial) % abs_inc) != 0; n += (abs (final - initial) % abs_inc) != 0;
But when abs_inc is a power of two, the summation won't overflow
except in cases where the loop never terminates. So we don't
need to use this more costly calculation.
If the loop has been unrolled, then the loop body has been If the loop has been unrolled, then the loop body has been
preconditioned to iterate a multiple of unroll_number times. If preconditioned to iterate a multiple of unroll_number times. If
abs_inc is != 1, the full calculation is abs_inc is != 1, the full calculation is
...@@ -666,50 +670,22 @@ doloop_modify_runtime (loop, iterations_max, ...@@ -666,50 +670,22 @@ doloop_modify_runtime (loop, iterations_max,
if (abs_inc * loop_info->unroll_number != 1) if (abs_inc * loop_info->unroll_number != 1)
{ {
int shift_count; int shift_count;
rtx extra;
rtx label;
unsigned HOST_WIDE_INT limit;
shift_count = exact_log2 (abs_inc * loop_info->unroll_number); shift_count = exact_log2 (abs_inc * loop_info->unroll_number);
if (shift_count < 0) if (shift_count < 0)
abort (); abort ();
/* abs (final - initial) / (abs_inc * unroll_number) */
iterations = expand_simple_binop (GET_MODE (diff), LSHIFTRT,
diff, GEN_INT (shift_count),
NULL_RTX, 1,
OPTAB_LIB_WIDEN);
if (abs_inc != 1) if (abs_inc != 1)
{ diff = expand_simple_binop (GET_MODE (diff), PLUS,
/* abs (final - initial) % (abs_inc * unroll_number) */ diff, GEN_INT (abs_inc - 1),
rtx count = GEN_INT (abs_inc * loop_info->unroll_number - 1); diff, 1, OPTAB_LIB_WIDEN);
extra = expand_simple_binop (GET_MODE (iterations), AND,
diff, count, NULL_RTX, 1, /* (abs (final - initial) + abs_inc - 1) / (abs_inc * unroll_number) */
OPTAB_LIB_WIDEN); diff = expand_simple_binop (GET_MODE (diff), LSHIFTRT,
diff, GEN_INT (shift_count),
/* If (abs (final - initial) % (abs_inc * unroll_number) diff, 1, OPTAB_LIB_WIDEN);
<= abs_inc * (unroll - 1)),
jump past following increment instruction. */
label = gen_label_rtx ();
limit = abs_inc * (loop_info->unroll_number - 1);
emit_cmp_and_jump_insns (extra, GEN_INT (limit),
limit == 0 ? EQ : LEU, NULL_RTX,
GET_MODE (extra), 0, label);
JUMP_LABEL (get_last_insn ()) = label;
LABEL_NUSES (label)++;
/* Increment the iteration count by one. */
iterations = expand_simple_binop (GET_MODE (iterations), PLUS,
iterations, GEN_INT (1),
iterations, 1,
OPTAB_LIB_WIDEN);
emit_label (label);
}
} }
else iterations = diff;
iterations = diff;
/* If there is a NOTE_INSN_LOOP_VTOP, we have a `for' or `while' /* If there is a NOTE_INSN_LOOP_VTOP, we have a `for' or `while'
style loop, with a loop exit test at the start. Thus, we can style loop, with a loop exit test at the start. Thus, we can
...@@ -722,17 +698,20 @@ doloop_modify_runtime (loop, iterations_max, ...@@ -722,17 +698,20 @@ doloop_modify_runtime (loop, iterations_max,
iteration count to one if necessary. */ iteration count to one if necessary. */
if (! loop->vtop) if (! loop->vtop)
{ {
rtx label;
if (loop_dump_stream) if (loop_dump_stream)
fprintf (loop_dump_stream, "Doloop: Do-while loop.\n"); fprintf (loop_dump_stream, "Doloop: Do-while loop.\n");
/* A `do-while' loop must iterate at least once. If the /* A `do-while' loop must iterate at least once. For code like
iteration count is bogus, we set the iteration count to 1. i = initial; do { ... } while (++i < final);
we will calculate a bogus iteration count if initial > final.
So detect this and set the iteration count to 1.
Note that if the loop has been unrolled, then the loop body Note that if the loop has been unrolled, then the loop body
is guaranteed to execute at least once. */ is guaranteed to execute at least once. Also, when the
if (loop_info->unroll_number == 1) comparison is NE, our calculated count will be OK. */
if (loop_info->unroll_number == 1 && comparison_code != NE)
{ {
rtx label;
/* Emit insns to test if the loop will immediately /* Emit insns to test if the loop will immediately
terminate and to set the iteration count to 1 if true. */ terminate and to set the iteration count to 1 if true. */
label = gen_label_rtx(); label = gen_label_rtx();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment