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

Alan Modra amodra@bigpond.net.au
Wed Jun 26 18:23:00 GMT 2002


On Wed, Jun 26, 2002 at 10:54:53AM -0700, Richard Henderson wrote:
> Need to use gen_int_mode here and for the final_value calulation.

Yes, we need the mask when the final val is a const_int, but
loop_info->initial_value may be an expression involving a reg.  So in
that case we still need plus_constant.  I've also tweaked
"INTVAL (increment) == 0" to "increment == const0_rtx".  Were you
suggesting to remove the n_iterations == 2 case?  It's actually useful
in weird loops like

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

and possibly other cases I haven't thought of.  On powerpc, the array
initialisation is unrolled.

OK now?

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 23:44:55 -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,43 @@ loop_iterations (loop)
 	  fprintf (loop_dump_stream, ".\n");
 	}
       return 0;
+    }
+  else if (comparison_code == EQ)
+    {
+      rtx inc_once;
+
+      if (loop_dump_stream)
+	fprintf (loop_dump_stream, "Loop iterations: EQ comparison loop.\n");
+
+      inc_once = gen_int_mode (INTVAL (initial_value) + INTVAL (increment),
+			       GET_MODE (iteration_var));
+
+      if (inc_once == 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 (increment == const0_rtx)
+	    return 0;
+	  loop_info->n_iterations = 2;
+	}
+      else
+	loop_info->n_iterations = 1;
+
+      if (GET_CODE (loop_info->initial_value) == CONST_INT)
+	loop_info->final_value
+	  = gen_int_mode ((INTVAL (loop_info->initial_value)
+			   + loop_info->n_iterations * INTVAL (increment)),
+			  GET_MODE (iteration_var));
+      else
+	loop_info->final_value
+	  = plus_constant (loop_info->initial_value,
+			   loop_info->n_iterations * INTVAL (increment));
+      loop_info->final_equiv_value
+	= gen_int_mode ((INTVAL (initial_value)
+			 + loop_info->n_iterations * INTVAL (increment)),
+			GET_MODE (iteration_var));
+      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



More information about the Gcc-patches mailing list