aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2002-11-04 20:06:28 +0000
committerDale Johannesen <dalej@gcc.gnu.org>2002-11-04 20:06:28 +0000
commit2aff950822bee20e1398a2a528ad927740f799f8 (patch)
tree757f262de1fc974cf8a0f7aebb26aea20afbf563 /gcc
parente86e721fc7b44cdd46c72f60de48af228d7df4b9 (diff)
downloadgcc-2aff950822bee20e1398a2a528ad927740f799f8.zip
gcc-2aff950822bee20e1398a2a528ad927740f799f8.tar.gz
gcc-2aff950822bee20e1398a2a528ad927740f799f8.tar.bz2
Fix bugs that showed up building Spec on ppc darwin.
From-SVN: r58800
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/doloop.c29
-rw-r--r--gcc/loop.c7
3 files changed, 29 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dfda5de..0b4cc8e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2002-11-04 Dale Johannesen <dalej@apple.com>
+
+ * doloop.c (doloop_modify_runtime): Fix loop count computation
+ for unrolled loops.
+ * loop.c (loop_invariant_p): Support calling from unroller.
+
2002-11-04 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/s390.c (s390_decompose_address): Use arg_pointer_rtx
diff --git a/gcc/doloop.c b/gcc/doloop.c
index 1f7d47a..67b742c 100644
--- a/gcc/doloop.c
+++ b/gcc/doloop.c
@@ -599,16 +599,19 @@ doloop_modify_runtime (loop, iterations_max,
If the loop has been unrolled, the full calculation is
- t1 = abs_inc * unroll_number; increment per loop
- n = abs (final - initial) / t1; full loops
- n += (abs (final - initial) % t1) != 0; partial loop
+ 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;
+ partial loop
+ which works out to be equivalent to
- 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.
+ n = (abs (final - initial) + t1 - 1) / t1;
+
+ 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
@@ -683,10 +686,10 @@ 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_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 --git a/gcc/loop.c b/gcc/loop.c
index 9461530..04f95ab 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -3273,6 +3273,13 @@ loop_invariant_p (loop, x)
&& REGNO (x) < FIRST_PSEUDO_REGISTER && call_used_regs[REGNO (x)])
return 0;
+ /* Out-of-range regs can occur when we are called from unrolling.
+ These have always been created by the unroller and are set in
+ the loop, hence are never invariant. */
+
+ if (REGNO (x) >= regs->num)
+ return 0;
+
if (regs->array[REGNO (x)].set_in_loop < 0)
return 2;