This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: c/900: `gcc -O2' takes 30x as long to compile certain files


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.  */
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]