http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53957

--- Comment #5 from rguenther at suse dot de <rguenther at suse dot de> 
2012-07-18 13:18:13 UTC ---
On Wed, 18 Jul 2012, burnus at gcc dot gnu.org wrote:

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53957
> 
> Tobias Burnus <burnus at gcc dot gnu.org> changed:
> 
>            What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                  CC|                            |burnus at gcc dot gnu.org
> 
> --- Comment #4 from Tobias Burnus <burnus at gcc dot gnu.org> 2012-07-18 
> 12:46:29 UTC ---
> (In reply to comment #3)
> > It would be better to have this similar to other loops I see,
> >
> >        bool flag = end-value == i;
> >        i = i + 1;
> >        if (flag) goto loop_exit;
> 
> That's not that simple as one might not reach the end value due to the step. 
> If
> "step" is (plus or minus) unity and if one has integers (and not reals, added
> in Fortran 77, deleted in Fortran 90), it is simple.
> 
> But if abs(step) != 1 or if the loop variable is not an integer, one either
> needs to calculate the number of trips beforehand, or has to use ">" or "<"
> rather than "==". The problem with "<" / ">" is that one has to do another
> comparison, unless the sign of "step" is known:
> 
>   if (step > 0 ? dovar > to : dovar < to)
>     goto exit_label;
> 
> I don't see whether that version is better than the current version.
> Suggestions or comments?
> 
> 
> The current code is (comment from trans-stmt.c's gfc_trans_do):
> 
> ------------<cut>-----------------
>    We translate a do loop from:
> 
>    DO dovar = from, to, step
>       body
>    END DO
> 
>    to:
> 
>    [evaluate loop bounds and step]
>    empty = (step > 0 ? to < from : to > from);
>    countm1 = (to - from) / step;
>    dovar = from;
>    if (empty) goto exit_label;
>    for (;;)
>      {
>        body;
> cycle_label:
>        dovar += step
>        if (countm1 ==0) goto exit_label;
>        countm1--;
>      }
> exit_label:
> 
>    countm1 is an unsigned integer.  It is equal to the loop count minus one,
>    because the loop count itself can overflow.  */

If you do

>    [evaluate loop bounds and step]
>    empty = (step > 0 ? to < from : to > from);
>    countm1 = (to - from) / step;
>    dovar = from;
>    if (empty) goto exit_label;
>    for (;;)
>      { 
>        body;
> cycle_label:
>        dovar += step
         exit = countm1 == 0;
         countm1--;
>        if (exit) goto exit_label;
>      }
> exit_label:

it would work for this case.

Reply via email to