[Bug fortran/42131] New: Weird translation of DO loops
rguenth at gcc dot gnu dot org
gcc-bugzilla@gcc.gnu.org
Sat Nov 21 13:58:00 GMT 2009
Split out from PR42108.
The loop is not unrolled because the frontend presents us with very funny
obfuscated code:
do k=i,nnd,n
temp=temp+(x(k)-x(k+jmini))**2
end do
gets translated to
{
character(kind=4) countm1.6;
integer(kind=4) D.1551;
integer(kind=4) D.1550;
integer(kind=4) D.1549;
D.1549 = i;
D.1550 = *nnd;
D.1551 = *n;
k = D.1549;
if (D.1551 > 0)
{
if (D.1550 < D.1549) goto L.6;, countm1.6 = (character(kind=4)) (D.1550 -
D.1549) / (character(kind=4)) D.1551;;
}
else
{
if (D.1550 > D.1549) goto L.6;, countm1.6 = (character(kind=4)) (D.1549 -
D.1550) / (character(kind=4)) -D.1551;;
}
while (1)
{
{
real(kind=8) D.1556;
real(kind=8) D.1555;
D.1555 = (((*x)[(integer(kind=8)) k + -1] - (*x)[(integer(kind=8)) (k
+ jmini) + -1]));
D.1556 = D.1555 * D.1555;
temp = temp + D.1556;
}
L.5:;
k = k + D.1551;
if (countm1.6 == 0) goto L.6;
countm1.6 = countm1.6 + 4294967295;
}
L.6:;
}
The funny conditional initialization of countm1.6 makes the analysis of
the number of iterations of this loop impossible (not to mention the
conversions to character(kind=4)).
Toon suggests:
The Standard doesn't prescribe the code the Frontend generates - however, to be
sure one follows the Standard, it's most easy to simply implement the steps
given.
To illustrate this with a simple example:
DO I = M1, M2, M3
B(I) = A(I)
ENDDO
would be most easily, and atraightforwardly, implemented as follows:
IF (M3 > 0 .AND. M1 < M2) GOTO 200 ! Loop executed zero times
IF (M3 < 0 .AND. M1 > M2) GOTO 200 ! Ditto
ITEMP = (M2 - M1 + M3) / M3 ! Temporary loop count
I = M1
100 CONTINUE
B(I) = A(I)
ITEMP = ITEMP - 1 ! Adjust internal loop counter
I = I + M3 ! Adjust DO loop variable
IF (ITEMP > 0) GOTO 100
200 CONTINUE
That there are two induction variables in this loop is inconsequential - one of
them should be eliminated by induction variable elimination (at least, that was
the case with g77 and the RTL loop optimization pass).
which I would agree with. I btw cannot see the difference between
if (D.1551 > 0)
{
if (D.1550 < D.1549) goto L.6;, countm1.6 = (character(kind=4)) (D.1550 -
D.1549) / (character(kind=4)) D.1551;;
}
else
{
if (D.1550 > D.1549) goto L.6;, countm1.6 = (character(kind=4)) (D.1549 -
D.1550) / (character(kind=4)) -D.1551;;
}
and
if ((D.1551 > 0 && D.1550 < D.1549) || (D.1551 < 0 && D.1550 > D.1549))
goto L.6;
countm1.6 = (character(kind=4)) (D.1550 - D.1549) / (character(kind=4)) D.1551;
where the unconditional initialization of countm1.6 is the important difference
(I'm sure the zero-trip-count check can be done more efficiently).
--
Summary: Weird translation of DO loops
Product: gcc
Version: 4.5.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: enhancement
Priority: P3
Component: fortran
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: rguenth at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42131
More information about the Gcc-bugs
mailing list