This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: c/900: `gcc -O2' takes 30x as long to compile certain files
- To: meyering at ascend dot com
- Subject: Re: c/900: `gcc -O2' takes 30x as long to compile certain files
- From: Bernd Schmidt <bernds at redhat dot com>
- Date: Mon, 27 Nov 2000 14:49:36 +0000 (GMT)
- cc: gcc-gnats at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org, gcc-bugs at gcc dot gnu dot org, Franz Sirl <Franz dot Sirl-kernel at lauterbach dot com>
On Mon, 27 Nov 2000 meyering@ascend.com wrote:
> >Synopsis: `gcc -O2' takes 30x as long to compile certain files
> FYI, it began taking much longer to compile that file with -O2
> some time between Nov 11, (when it worked fine) and Nov 22.
This is because Franz Sirl reverted his accidental checkin of a loop
optimizer patch by Geoff Keating. I've looked closer at that patch, and
found that it does fix a bug. Not only can the bug lead to much higher
compile times as you noticed, it could also probably cause incorrect code
to be generated.
Basically, when determining whether the destination of a given SET is
a biv, we scan backwards to find sets of the source (if it's a register).
Only the first such set should be considered, but we currently scan past
it and call basic_induction_var recursively each time we see a set of
the source.
For correctness, we need to terminate the search as soon as we find an
insn that sets the register, whether or not it's a biv. It seems to me
that Geoff's patch leaves a small hole open in that code; I've added a
bit of code that tests for a set inside STRICT_LOW_PART/ZERO_EXTRACT/etc.
Bootstrapped on i686-linux & checked in.
Bernd
Based on a patch from Geoff Keating <geoffk@redhat.com>:
* loop.c (basic_induction_var): If a REG is set from something
that is not a biv, then the REG is not a biv. Even if it is
earlier set from something that is a biv.
Index: loop.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/loop.c,v
retrieving revision 1.296
diff -u -p -r1.296 loop.c
--- loop.c 2000/11/21 18:24:42 1.296
+++ loop.c 2000/11/27 14:41:16
@@ -5467,6 +5467,7 @@ basic_induction_var (loop, x, mode, dest
insn = p;
while (1)
{
+ rtx dest;
do
{
insn = PREV_INSN (insn);
@@ -5479,21 +5480,26 @@ basic_induction_var (loop, x, mode, dest
set = single_set (insn);
if (set == 0)
break;
+ dest = SET_DEST (set);
+ if (dest == x
+ || (GET_CODE (dest) == SUBREG
+ && (GET_MODE_SIZE (GET_MODE (dest)) <= UNITS_PER_WORD)
+ && (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
+ && SUBREG_REG (dest) == x))
+ return basic_induction_var (loop, SET_SRC (set),
+ (GET_MODE (SET_SRC (set)) == VOIDmode
+ ? GET_MODE (x)
+ : GET_MODE (SET_SRC (set))),
+ dest_reg, insn,
+ inc_val, mult_val, location);
- if ((SET_DEST (set) == x
- || (GET_CODE (SET_DEST (set)) == SUBREG
- && (GET_MODE_SIZE (GET_MODE (SET_DEST (set)))
- <= UNITS_PER_WORD)
- && (GET_MODE_CLASS (GET_MODE (SET_DEST (set)))
- == MODE_INT)
- && SUBREG_REG (SET_DEST (set)) == x))
- && basic_induction_var (loop, SET_SRC (set),
- (GET_MODE (SET_SRC (set)) == VOIDmode
- ? GET_MODE (x)
- : GET_MODE (SET_SRC (set))),
- dest_reg, insn,
- inc_val, mult_val, location))
- return 1;
+ while (GET_CODE (dest) == SIGN_EXTRACT
+ || GET_CODE (dest) == ZERO_EXTRACT
+ || GET_CODE (dest) == SUBREG
+ || GET_CODE (dest) == STRICT_LOW_PART)
+ dest = XEXP (dest, 0);
+ if (dest == x)
+ break;
}
/* Fall through. */