optimization/7120: Run once loop should *always* be unrolled
Alan Modra
amodra@bigpond.net.au
Wed Jun 26 04:08:00 GMT 2002
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
More information about the Gcc-bugs
mailing list