This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Here is the problem...
IN A FEW WORDS:
I take a simple SPEC95 loop written in Fortran that contains loads
and stores from/to arrays and compile it using the g77 -O3. I obtain an
assembly loop body which reduces the address computation to one instruction
for each memory access (i.e. one add).
Then, I compile the *same* loop, written in C, using gcc -O3. The
assembly program generated now needs two instructions to calculate each
address (i.e., one add + one shift). The execution time difference
is not negligible. (~ 28%)
Why? Isn't the back-end the same for g77 and gcc?
IN DETAILS:
1. SYSTEM
uname -a
SunOS 5.6 Generic_105181-16 sun4u sparc SUNW,Ultra-1
2. COMPILERS
g77 -v
g77 version egcs-2.91.60 19981201 (egcs-1.1.1 release) (from FSF-g77
version 0.5.24-19980804)
Driving: g77 -v -c -xf77-version /dev/null -xnone
Reading specs from /opt/gnu/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.91.60/specs
gcc version egcs-2.91.60 19981201 (egcs-1.1.1 release)
/opt/gnu/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.91.60/cpp
-lang-c -v -undef -D
__GNUC__=2 -D__GNUC_MINOR__=91 -D__sparc__ -D__sun__ -D__unix__
-D__svr4__ -D__S
VR4 -D__sparc -D__sun -D__unix -Asystem(unix) -Asystem(svr4) -D_LANGUAGE_FORTRAN
-traditional -D__GCC_NEW_VARARGS__ -Acpu(sparc) -Amachine(sparc)
/dev/null /dev
/null
GNU CPP version egcs-2.91.60 19981201 (egcs-1.1.1 release) (sparc)
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/opt/gnu/sparc-sun-solaris2.6/include
/opt/gnu/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.91.60/include
/usr/include
End of search list.
/opt/gnu/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.91.60/f771
-fnull-version -qui
et -dumpbase g77-version.f -version -fversion -o /var/tmp/ccxUPtyU.s
/dev/null
GNU F77 version egcs-2.91.60 19981201 (egcs-1.1.1 release) (sparc-sun-solaris2.6
) compiled by GNU C version egcs-2.91.60 19981201 (egcs-1.1.1 release).
GNU Fortran Front End version 0.5.24-19980804
/usr/ccs/bin/as -V -Qy -s -o /var/tmp/ccQEOG0K.o /var/tmp/ccxUPtyU.s
/usr/ccs/bin/as: WorkShop Compilers 4.X dev 18 Sep 1996
/usr/ccs/bin/ld -V -Y P,/usr/ccs/lib:/usr/lib -Qy -o /var/tmp/ccdn5P1C
/var/tmp
/ccQEOG0K.o /opt/gnu/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.91.60/crt1.o
/opt/g
nu/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.91.60/crti.o /usr/ccs/lib/values-Xa.o
/opt/gnu/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.91.60/crtbegin.o
-L/opt/gnu/li
b/gcc-lib/sparc-sun-solaris2.6/egcs-2.91.60 -L/opt/gnu/sparc-sun-solaris2.6/lib
-L/usr/ccs/bin -L/usr/ccs/lib -L/opt/gnu/lib -lg2c -lm -lgcc -lc
-lgcc /opt/gnu/
lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.91.60/crtend.o /opt/gnu/lib/gcc-lib/spar
c-sun-solaris2.6/egcs-2.91.60/crtn.o
ld: Software Generation Utilities - Solaris/ELF (3.0)
/var/tmp/ccdn5P1C
__G77_LIBF77_VERSION__: 0.5.24
@(#)LIBF77 VERSION 19970919
__G77_LIBI77_VERSION__: 0.5.24-19980920
@(#) LIBI77 VERSION pjw,dmg-mods 19980617
__G77_LIBU77_VERSION__: 0.5.24
@(#) LIBU77 VERSION 19980709
gcc -v:
Reading specs from /opt/gnu/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.91.60/specs
gcc version egcs-2.91.60 19981201 (egcs-1.1.1 release)
3. LOOP
3.1 FORTRAN
The following loop is the critical loop of the most called function
(FFTZ2) of 125.turb3d CFP95 SPEC benchmark. It is inside another loop,
all the variables ( except for K and LK) are double floating point.
DO 100 K = 0, LK - 1
X11 = X(I11+K)
X12 = X(I11+K+N)
X21 = X(I12+K)
X22 = X(I12+K+N)
T1 = X11
- X21
T2 = X12
- X22
Y(I21+K)
= X11 + X21
Y(I21+K+N)
= X12 + X22
Y(I22+K)
= U1 * T1 - U2 * T2
Y(I22+K+N)
= U1 * T2 + U2 * T1
100 CONTINUE
g77 generates the following assembly code:
.LL53:
ldd [%o0+%i4],%f10
addcc %l0,-1,%l0
ldd [%o1+%i4],%f12
add %o0,8,%o0
ldd [%o2+%i4],%f6
add %o1,8,%o1
ldd [%o3+%i4],%f8
fsubd %f10,%f6,%f14
add %o3,8,%o3
add %o2,8,%o2
fsubd %f12,%f8,%f2
fmuld %f18,%f14,%f4
faddd %f10,%f6,%f10
fmuld %f20,%f2,%f16
faddd %f12,%f8,%f12
std %f10,[%o4+%i5]
add %o4,8,%o4
fmuld %f18,%f2,%f2
fsubd %f4,%f16,%f4
std %f12,[%o5+%i5]
add %o5,8,%o5
std %f4,[%g2+%i5]
fmuld %f20,%f14,%f14
add %g2,8,%g2
faddd %f2,%f14,%f2
std %f2,[%g3+%i5]
bpos .LL53
add %g3,8,%g3
3.2 C LANGUAGE
Now we translate the Loop in C (using f2c and making the variable
declaration non "static" but "register")
for (k = 0; k <= i__2; ++k) {
x11 = x[i11 + k];
x12 = x[i11 + k + n];
x21 = x[i12 + k];
x22 = x[i12 + k + n];
t1 = x11 - x21;
t2 = x12 - x22;
y[i21 + k] = x11 + x21;
y[i21 + k + n] = x12 + x22;
y[i22 + k] = u1 * t1 - u2 * t2;
y[i22 + k + n] = u1 * t2 + u2 * t1;
/* L100: */
}
The assembly is:
.LL16:
add %i1,%o5,%o0
add %g4,%o5,%o1
sll %o0,3,%o0
sll %o1,3,%o1
ldd [%i4+%o1],%f4
sll %g2,3,%o2
ldd [%i4+%o0],%f10
sll %g3,3,%o3
fsubd %f10,%f4,%f8
ldd [%i4+%o2],%f12
add %i2,%o5,%o4
ldd [%i4+%o3],%f14
sll %o4,3,%o4
fsubd %f12,%f14,%f2
fmuld %f18,%f8,%f6
sll %o7,3,%o2
add %g1,%o5,%o0
sll %o0,3,%o0
faddd %f10,%f4,%f10
sll %l0,3,%o1
add %o5,1,%o5
fmuld %f16,%f8,%f8
add %l0,1,%l0
faddd %f12,%f14,%f12
std %f10,[%i5+%o4]
add %o7,1,%o7
add %g3,1,%g3
fmuld %f16,%f2,%f4
std %f12,[%i5+%o2]
cmp %o5,%l5
fmuld %f18,%f2,%f2
fsubd %f6,%f4,%f6
std %f6,[%i5+%o0]
faddd %f2,%f8,%f2
std %f2,[%i5+%o1]
ble .LL16
add %g2,1,%g2
It is evident that the first program (generated by g77) obtains each load/store address by simply incrementing each offset by 8 (double float type size) at each iteration (e.g., add %o0,8,%o0) while the other (generated by gcc) i) adds the index of the loop (%o5) to the starting offset at each iteration and ii) multiplies the result by 8 (double float type size).i.e.,
add %i1,%o5,%o0
sll %o0,3,%o0
QUESTIONS:
* is it due to the semantic difference between the Fortran
DO and the C for loop constructs? If so, why in detail?
* is it due to a bug of the gcc? (...but do not gcc and g77
share the same back-end?)
* what else?
Thank you
N.Zingirian
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |