This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Loop unroll fixes
- To: mark at codesourcery dot com (Mark Mitchell)
- Subject: Re: Loop unroll fixes
- From: Zoltan Hidvegi <hzoli at hzoli dot 2y dot net>
- Date: Thu, 25 Oct 2001 23:25:16 -0500 (CDT)
- Cc: hzoli at hzoli dot 2y dot net, wilson at cygnus dot com, gcc-patches at gcc dot gnu dot org,bernds at redhat dot com, Franz dot Sirl-kernel at lauterbach dot com
> If I understand correctly, this reflects a regression in 3.0 relative
> to 2.95.x. Correct?
Correct.
> That's bad; we should try to fix the bug.
>
> Independently of that, does your change make the problem worse, or
> just leave it the same? If the latter, the patch is OK -- but you
> should change the comments to indicate that there is this bug, and
> we know about it.
No, my patch does not affect this, it just leaves it as it is, or in
some cases it can cange the loop to execute 2^word_size times instead
of 2^word_size/increment times (that the case when
final-initial+abs_inc-1 overflows). There is already a comment, even
a check in doloops.c, that if debugging is enabled, prints a message
about possible undetected infinite loop.
The patch below extends the check, and adds some more comment. Even
though this patch changes an if condition, it is still a comment only
patch, since that if condition only controls the printing of a debug
message. This is in doloop_valid_p, where the test is made if the ctr
loop optimization could be applied or not. This can be cahnged to
return 0 to not generate ctr loops here, or as you suggested, add a
new option like -funsafe-loops that would only return 0 if
-funsafe-loops is not enabled.
Zoli
*** doloop.c 2001/10/26 03:27:00 1.4
--- doloop.c 2001/10/26 04:19:47
*************** doloop_valid_p (loop, jump_insn)
*** 350,374 ****
/* Check for loops that may not terminate under special conditions. */
if (! loop_info->n_iterations
&& ((loop_info->comparison_code == LEU
! && INTVAL (loop_info->increment) > 0)
! || (loop_info->comparison_code == GEU
! && INTVAL (loop_info->increment) < 0)))
{
/* If the comparison is LEU and the comparison value is UINT_MAX
then the loop will not terminate. Similarly, if the
comparison code is GEU and the initial value is 0, the loop
will not terminate.
! Note that with LE and GE, the loop behaviour can be
! implementation dependent if an overflow occurs, say between
! INT_MAX and INT_MAX + 1. We thus don't have to worry about
! these two cases.
??? We could compute these conditions at run-time and have a
additional jump around the loop to ensure an infinite loop.
However, it is very unlikely that this is the intended
behaviour of the loop and checking for these rare boundary
! conditions would pessimize all other code. */
if (loop_dump_stream)
fprintf (loop_dump_stream,
"Doloop: Possible infinite iteration case ignored.\n");
--- 350,389 ----
/* Check for loops that may not terminate under special conditions. */
if (! loop_info->n_iterations
&& ((loop_info->comparison_code == LEU
! && INTVAL (loop_info->increment) > 0) ||
! (loop_info->comparison_code == GEU
! && INTVAL (loop_info->increment) < 0) ||
! (loop_info->comparison_code == LTU
! && INTVAL (loop_info->increment) > 1) ||
! (loop_info->comparison_code == GTU
! && INTVAL (loop_info->increment) < 1))
{
/* If the comparison is LEU and the comparison value is UINT_MAX
then the loop will not terminate. Similarly, if the
comparison code is GEU and the initial value is 0, the loop
will not terminate.
! If the absolute increment is not 1, the loop can be infinite
! even with LTU/GTU, e.g. for (i = 3; i > 0; i -= 2)
!
! Note that with LE and GE, the loop behaviour is undefined
! (C++ standard section 5 clause 5) if an overflow occurs, say
! between INT_MAX and INT_MAX + 1. We thus don't have to worry
! about these two cases.
??? We could compute these conditions at run-time and have a
additional jump around the loop to ensure an infinite loop.
However, it is very unlikely that this is the intended
behaviour of the loop and checking for these rare boundary
! conditions would pessimize all other code.
!
! If the loop is executed only a few times an extra check to
! restart the loop could use up most of the benefits of using a
! count register loop. Note however, that normally, this
! restart branch would never execute, so it could be predicted
! well by the CPU. We should generate the pessimistic code by
! default, and have an option, e.g. -funsafe-loops that would
! enable count-register loops in this case. */
if (loop_dump_stream)
fprintf (loop_dump_stream,
"Doloop: Possible infinite iteration case ignored.\n");