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]
Other format: [Raw text]

Re: optimization/7120: Run once loop should *always* be unrolled


On Wed, Jun 26, 2002 at 01:17:00PM +0930, Alan Modra wrote:
> Bah, that's too simplistic.  Patch withdrawn.

This one is better.  Handles horrible loops like:

  extern int *arr;
  int i;
  i = 0;
  do
    {
      arr[i] = 0;
      i++;
    }
  while (i == 1);

I'm also setting loop_info->final_value and
loop_info->final_equiv_value as they were reset to zero earlier.

bootstrapped and regression tested i686-linux.

	* unroll.c (loop_iterations): Handle EQ loops.

Index: gcc/unroll.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/unroll.c,v
retrieving revision 1.168
diff -u -p -r1.168 unroll.c
--- gcc/unroll.c	15 Jun 2002 01:10:49 -0000	1.168
+++ gcc/unroll.c	26 Jun 2002 04:58:40 -0000
@@ -3941,12 +3941,6 @@ loop_iterations (loop)
 	}
       return 0;
     }
-  else if (comparison_code == EQ)
-    {
-      if (loop_dump_stream)
-	fprintf (loop_dump_stream, "Loop iterations: EQ comparison loop.\n");
-      return 0;
-    }
   else if (GET_CODE (final_value) != CONST_INT)
     {
       if (loop_dump_stream)
@@ -3957,6 +3951,34 @@ loop_iterations (loop)
 	  fprintf (loop_dump_stream, ".\n");
 	}
       return 0;
+    }
+  else if (comparison_code == EQ)
+    {
+      if (loop_dump_stream)
+	fprintf (loop_dump_stream, "Loop iterations: EQ comparison loop.\n");
+
+      if (((INTVAL (initial_value) + INTVAL (increment))
+	   & (((unsigned HOST_WIDE_INT) 1
+	       << (GET_MODE_BITSIZE (GET_MODE (iteration_var)) - 1)
+	       << 1) - 1)) == INTVAL (final_value))
+	{
+	  /* The iterator value once through the loop is equal to the
+	     comparision value.  Either we have an infinite loop, or
+	     we'll loop twice.  */
+	  if (INTVAL (increment) == 0)
+	    return 0;
+	  loop_info->n_iterations = 2;
+	}
+      else
+	loop_info->n_iterations = 1;
+
+      loop_info->final_value
+	= plus_constant (loop_info->initial_value,
+			 loop_info->n_iterations * INTVAL (increment));
+      loop_info->final_equiv_value
+	= GEN_INT (INTVAL (initial_value)
+		   + loop_info->n_iterations * INTVAL (increment));
+      return loop_info->n_iterations;
     }
 
   /* Final_larger is 1 if final larger, 0 if they are equal, otherwise -1.  */


-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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