summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/doloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/doloop.c')
-rw-r--r--contrib/gcc/doloop.c69
1 files changed, 34 insertions, 35 deletions
diff --git a/contrib/gcc/doloop.c b/contrib/gcc/doloop.c
index 25deb503..67b742c 100644
--- a/contrib/gcc/doloop.c
+++ b/contrib/gcc/doloop.c
@@ -140,7 +140,7 @@ doloop_condition_get (pattern)
/* Return an estimate of the maximum number of loop iterations for the
loop specified by LOOP or zero if the loop is not normal.
- MODE is the mode of the iteration count and NONNEG is non-zero if
+ MODE is the mode of the iteration count and NONNEG is nonzero if
the iteration count has been proved to be non-negative. */
static unsigned HOST_WIDE_INT
doloop_iterations_max (loop_info, mode, nonneg)
@@ -249,7 +249,7 @@ doloop_iterations_max (loop_info, mode, nonneg)
}
-/* Return non-zero if the loop specified by LOOP is suitable for
+/* Return nonzero if the loop specified by LOOP is suitable for
the use of special low-overhead looping instructions. */
static int
doloop_valid_p (loop, jump_insn)
@@ -263,7 +263,7 @@ doloop_valid_p (loop, jump_insn)
|| ! onlyjump_p (jump_insn))
{
if (loop_dump_stream)
- fprintf (loop_dump_stream,
+ fprintf (loop_dump_stream,
"Doloop: Invalid jump at loop end.\n");
return 0;
}
@@ -339,6 +339,7 @@ doloop_valid_p (loop, jump_insn)
condition at run-time and have an additional jump around the loop
to ensure an infinite loop. */
if (loop_info->comparison_code == NE
+ && !loop_info->preconditioned
&& INTVAL (loop_info->increment) != -1
&& INTVAL (loop_info->increment) != 1)
{
@@ -361,13 +362,13 @@ doloop_valid_p (loop, jump_insn)
{
/* If the comparison is LEU and the comparison value is UINT_MAX
then the loop will not terminate. Similarly, if the
- comparison code is GEU and the initial value is 0, the loop
- will not terminate.
+ comparison code is GEU and the comparison value is 0, the
+ loop will not terminate.
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)
- Note that with LE and GE, the loop behaviour is undefined
+ Note that with LE and GE, the loop behavior is undefined
(C++ standard section 5 clause 5) if an overflow occurs, say
between INT_MAX and INT_MAX + 1. We thus don't have to worry
about these two cases.
@@ -375,7 +376,7 @@ doloop_valid_p (loop, jump_insn)
??? We could compute these conditions at run-time and have a
additional jump around the loop to ensure an infinite loop.
However, it is very unlikely that this is the intended
- behaviour of the loop and checking for these rare boundary
+ behavior of the loop and checking for these rare boundary
conditions would pessimize all other code.
If the loop is executed only a few times an extra check to
@@ -399,7 +400,7 @@ doloop_valid_p (loop, jump_insn)
number of loop iterations, ITERATIONS_MAX is a CONST_INT specifying
the maximum number of loop iterations, and DOLOOP_INSN is the
low-overhead looping insn to emit at the end of the loop. This
- returns non-zero if it was successful. */
+ returns nonzero if it was successful. */
static int
doloop_modify (loop, iterations, iterations_max,
doloop_seq, start_label, condition)
@@ -490,7 +491,7 @@ doloop_modify (loop, iterations, iterations_max,
/* Insert initialization of the count register into the loop header. */
convert_move (counter_reg, count, 1);
- sequence = gen_sequence ();
+ sequence = get_insns ();
end_sequence ();
emit_insn_before (sequence, loop->start);
@@ -508,7 +509,7 @@ doloop_modify (loop, iterations, iterations_max,
{
start_sequence ();
emit_insn (init);
- sequence = gen_sequence ();
+ sequence = get_insns ();
end_sequence ();
emit_insn_after (sequence, loop->start);
}
@@ -539,7 +540,7 @@ doloop_modify (loop, iterations, iterations_max,
not present, we emit one. The loop to modify is described by LOOP.
ITERATIONS_MAX is a CONST_INT specifying the estimated maximum
number of loop iterations. DOLOOP_INSN is the low-overhead looping
- insn to insert. Returns non-zero if loop successfully modified. */
+ insn to insert. Returns nonzero if loop successfully modified. */
static int
doloop_modify_runtime (loop, iterations_max,
doloop_seq, start_label, mode, condition)
@@ -600,18 +601,17 @@ doloop_modify_runtime (loop, iterations_max,
t1 = abs_inc * unroll_number; increment per loop
n = (abs (final - initial) + abs_inc - 1) / t1; full loops
- n += ((abs (final - initial) + abs_inc - 1) % t1) >= abs_inc;
+ n += (abs (final - initial) + abs_inc - 1) % t1) >= abs_inc;
partial loop
which works out to be equivalent to
n = (abs (final - initial) + t1 - 1) / t1;
- 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.
+ In the case where the loop was preconditioned, a few iterations
+ may have been executed earlier; but 'initial' was adjusted as they
+ were executed, so we don't need anything special for that case here.
+ 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
@@ -686,15 +686,13 @@ doloop_modify_runtime (loop, iterations_max,
if (shift_count < 0)
abort ();
- if (loop_info->preconditioned)
- diff = expand_simple_binop (GET_MODE (diff), PLUS,
- diff, GEN_INT (abs_inc - 1),
- diff, 1, OPTAB_LIB_WIDEN);
- else
- diff = expand_simple_binop (GET_MODE (diff), PLUS,
- diff, GEN_INT (abs_loop_inc - 1),
- diff, 1, OPTAB_LIB_WIDEN);
+ /* (abs (final - initial) + abs_inc * unroll_number - 1) */
+ diff = expand_simple_binop (GET_MODE (diff), PLUS,
+ diff, GEN_INT (abs_loop_inc - 1),
+ diff, 1, OPTAB_LIB_WIDEN);
+ /* (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);
@@ -740,7 +738,7 @@ doloop_modify_runtime (loop, iterations_max,
}
}
- sequence = gen_sequence ();
+ sequence = get_insns ();
end_sequence ();
emit_insn_before (sequence, loop->start);
@@ -755,7 +753,7 @@ doloop_modify_runtime (loop, iterations_max,
suitable. We distinguish between loops with compile-time bounds
and those with run-time bounds. Information from LOOP is used to
compute the number of iterations and to determine whether the loop
- is a candidate for this optimization. Returns non-zero if loop
+ is a candidate for this optimization. Returns nonzero if loop
successfully modified. */
int
doloop_optimize (loop)
@@ -794,7 +792,7 @@ doloop_optimize (loop)
&increment, &mode))
{
if (loop_dump_stream)
- fprintf (loop_dump_stream,
+ fprintf (loop_dump_stream,
"Doloop: Cannot precondition loop.\n");
return 0;
}
@@ -864,18 +862,19 @@ doloop_optimize (loop)
return 0;
}
- /* A raw define_insn may yield a plain pattern. If a sequence
- was involved, the last must be the jump instruction. */
- if (GET_CODE (doloop_seq) == SEQUENCE)
+ /* If multiple instructions were created, the last must be the
+ jump instruction. Also, a raw define_insn may yield a plain
+ pattern. */
+ doloop_pat = doloop_seq;
+ if (INSN_P (doloop_pat))
{
- doloop_pat = XVECEXP (doloop_seq, 0, XVECLEN (doloop_seq, 0) - 1);
+ while (NEXT_INSN (doloop_pat) != NULL_RTX)
+ doloop_pat = NEXT_INSN (doloop_pat);
if (GET_CODE (doloop_pat) == JUMP_INSN)
doloop_pat = PATTERN (doloop_pat);
else
doloop_pat = NULL_RTX;
}
- else
- doloop_pat = doloop_seq;
if (! doloop_pat
|| ! (condition = doloop_condition_get (doloop_pat)))
OpenPOWER on IntegriCloud