re PR rtl-optimization/7130 (miscompiled code for gcc-3.1 on powerpc-unknown-linux-gnu with -funroll-all-loops)
PR optimization/7130 * loop.h (struct loop_info): Add "preconditioned". * unroll.c (unroll_loop): Set it. * doloop.c (doloop_modify_runtime): Correct count for unrolled loops. From-SVN: r55598
This commit is contained in:
parent
0dc36574af
commit
8b583747ad
4 changed files with 32 additions and 11 deletions
|
@ -1,3 +1,10 @@
|
|||
2002-07-20 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
PR optimization/7130
|
||||
* loop.h (struct loop_info): Add "preconditioned".
|
||||
* unroll.c (unroll_loop): Set it.
|
||||
* doloop.c (doloop_modify_runtime): Correct count for unrolled loops.
|
||||
|
||||
2002-07-19 Zack Weinberg <zack@codesourcery.com>
|
||||
|
||||
* rtl.def (CODE_LABEL): Remove slot 8.
|
||||
|
|
30
gcc/doloop.c
30
gcc/doloop.c
|
@ -552,6 +552,7 @@ doloop_modify_runtime (loop, iterations_max,
|
|||
{
|
||||
const struct loop_info *loop_info = LOOP_INFO (loop);
|
||||
HOST_WIDE_INT abs_inc;
|
||||
HOST_WIDE_INT abs_loop_inc;
|
||||
int neg_inc;
|
||||
rtx diff;
|
||||
rtx sequence;
|
||||
|
@ -595,13 +596,18 @@ doloop_modify_runtime (loop, iterations_max,
|
|||
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
|
||||
preconditioned to iterate a multiple of unroll_number times. If
|
||||
abs_inc is != 1, the full calculation is
|
||||
If the loop has been unrolled, the full calculation is
|
||||
|
||||
t1 = abs_inc * unroll_number;
|
||||
n = abs (final - initial) / t1;
|
||||
n += (abs (final - initial) % t1) > t1 - abs_inc;
|
||||
t1 = abs_inc * unroll_number; increment per loop
|
||||
n = abs (final - initial) / t1; full loops
|
||||
n += (abs (final - initial) % t1) != 0; partial loop
|
||||
|
||||
However, in certain cases the unrolled loop will be preconditioned
|
||||
by emitting copies of the loop body with conditional branches,
|
||||
so that the unrolled loop is always a full loop and thus needs
|
||||
no exit tests. In this case we don't want to add the partial
|
||||
loop count. As above, when t1 is a power of two we don't need to
|
||||
worry about overflow.
|
||||
|
||||
The division and modulo operations can be avoided by requiring
|
||||
that the increment is a power of 2 (precondition_loop_p enforces
|
||||
|
@ -667,20 +673,22 @@ doloop_modify_runtime (loop, iterations_max,
|
|||
}
|
||||
}
|
||||
|
||||
if (abs_inc * loop_info->unroll_number != 1)
|
||||
abs_loop_inc = abs_inc * loop_info->unroll_number;
|
||||
if (abs_loop_inc != 1)
|
||||
{
|
||||
int shift_count;
|
||||
|
||||
shift_count = exact_log2 (abs_inc * loop_info->unroll_number);
|
||||
shift_count = exact_log2 (abs_loop_inc);
|
||||
if (shift_count < 0)
|
||||
abort ();
|
||||
|
||||
if (abs_inc != 1)
|
||||
if (!loop_info->preconditioned)
|
||||
diff = expand_simple_binop (GET_MODE (diff), PLUS,
|
||||
diff, GEN_INT (abs_inc - 1),
|
||||
diff, GEN_INT (abs_loop_inc - 1),
|
||||
diff, 1, OPTAB_LIB_WIDEN);
|
||||
|
||||
/* (abs (final - initial) + abs_inc - 1) / (abs_inc * unroll_number) */
|
||||
/* (abs (final - initial) + abs_inc * unroll_number - 1)
|
||||
/ (abs_inc * unroll_number) */
|
||||
diff = expand_simple_binop (GET_MODE (diff), LSHIFTRT,
|
||||
diff, GEN_INT (shift_count),
|
||||
diff, 1, OPTAB_LIB_WIDEN);
|
||||
|
|
|
@ -316,6 +316,9 @@ struct loop_info
|
|||
int has_multiple_exit_targets;
|
||||
/* Nonzero if there is an indirect jump in the current function. */
|
||||
int has_indirect_jump;
|
||||
/* Whether loop unrolling has emitted copies of the loop body so
|
||||
that the main loop needs no exit tests. */
|
||||
int preconditioned;
|
||||
/* Register or constant initial loop value. */
|
||||
rtx initial_value;
|
||||
/* Register or constant value used for comparison test. */
|
||||
|
|
|
@ -1135,6 +1135,9 @@ unroll_loop (loop, insn_count, strength_reduce_p)
|
|||
/* Keep track of the unroll factor for the loop. */
|
||||
loop_info->unroll_number = unroll_number;
|
||||
|
||||
/* And whether the loop has been preconditioned. */
|
||||
loop_info->preconditioned = loop_preconditioned;
|
||||
|
||||
/* For each biv and giv, determine whether it can be safely split into
|
||||
a different variable for each unrolled copy of the loop body.
|
||||
We precalculate and save this info here, since computing it is
|
||||
|
|
Loading…
Add table
Reference in a new issue