This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Sparc optimization problems
- To: gcc-bugs at gcc dot gnu dot org
- Subject: Sparc optimization problems
- From: Keith Refson <Keith dot Refson at earth dot ox dot ac dot uk>
- Date: Tue, 2 May 2000 15:02:47 +0100 (BST)
This is not strictly a bug bug an optimization/performance issue. It
arose when I was investigating why a large floating-point code runs
30% slower on a sparc-sun-solaris2.8 system when compiled using gcc
2.95.2 compares with egcs-2.91.60 19981201.
A look at the assembler output generated by the following snippet
reveals why:
C source code
The output generated by "gcc -O2 -S" looks like
.file "opttricka.c"
gcc2_compiled.:
.section ".text"
.align 4
.global qsincos
.type qsincos,#function
.proc 020
qsincos:
!#PROLOGUE# 0
save %sp, -112, %sp
!#PROLOGUE# 1
ld [%fp+104], %g2
mov %i0, %o7
ld [%fp+92], %i0
cmp %g2, 0
ld [%fp+96], %g4
ble .LL4
ld [%fp+100], %g1
mov %g2, %g3
mov 0, %g2
.LL6:
ldd [%g2+%o7], %f4
addcc %g3, -1, %g3
fmovs %f4, %f2
fmovs %f5, %f3
ldd [%g2+%i2], %f4
fmovs %f4, %f12
fmovs %f5, %f13
ldd [%g2+%i1], %f4
fmovs %f4, %f6
fmovs %f5, %f7
ldd [%g2+%i3], %f4
fmuld %f6, %f12, %f8
fmovs %f4, %f14
fmovs %f5, %f15
ldd [%g2+%i4], %f4
fmuld %f6, %f14, %f6
fmovs %f4, %f16
fmovs %f5, %f17
ldd [%g2+%i5], %f4
fmovs %f4, %f18
fmovs %f5, %f19
ldd [%g2+%i0], %f4
fmovs %f4, %f10
fmovs %f5, %f11
fmuld %f2, %f14, %f4
fmuld %f2, %f12, %f2
faddd %f8, %f4, %f8
fsubd %f2, %f6, %f2
fmuld %f8, %f16, %f4
fmuld %f2, %f18, %f6
fmuld %f8, %f18, %f8
faddd %f4, %f6, %f4
fmuld %f2, %f16, %f2
fmuld %f10, %f4, %f4
fsubd %f2, %f8, %f2
fmuld %f10, %f2, %f10
std %f4, [%g2+%g1]
std %f10, [%g2+%g4]
bne .LL6
add %g2, 8, %g2
.LL4:
ret
restore
.LLfe1:
.size qsincos,.LLfe1-qsincos
.ident "GCC: (GNU) 2.95.2 19991024 (release)"
Note the number of "fmovs" instructions present in the loop.
By comparison the loop code generated by egcs 2.91 is much cleaner
.file "opttricka.c"
gcc2_compiled.:
.section ".text"
.align 4
.global qsincos
.type qsincos,#function
.proc 020
qsincos:
!#PROLOGUE# 0
save %sp,-112,%sp
!#PROLOGUE# 1
ld [%fp+104],%g1
mov %i0,%o7
mov 0,%g3
ld [%fp+92],%o0
cmp %g3,%g1
ld [%fp+96],%i0
bge .LL3
ld [%fp+100],%g4
sll %g3,3,%g2
.LL7:
ldd [%o7+%g2],%f8
add %g3,1,%g3
ldd [%i2+%g2],%f4
cmp %g3,%g1
fmuld %f8,%f4,%f6
ldd [%i1+%g2],%f10
ldd [%i3+%g2],%f2
ldd [%i4+%g2],%f14
fmuld %f10,%f4,%f4
ldd [%i5+%g2],%f16
ldd [%o0+%g2],%f12
fmuld %f8,%f2,%f8
fmuld %f10,%f2,%f10
faddd %f4,%f8,%f4
fsubd %f6,%f10,%f6
fmuld %f4,%f14,%f2
fmuld %f6,%f16,%f8
fmuld %f4,%f16,%f4
faddd %f2,%f8,%f2
fmuld %f6,%f14,%f6
fmuld %f12,%f2,%f2
fsubd %f6,%f4,%f6
fmuld %f12,%f6,%f12
std %f2,[%g4+%g2]
std %f12,[%i0+%g2]
bl .LL7
sll %g3,3,%g2
.LL3:
ret
restore
.LLfe1:
.size qsincos,.LLfe1-qsincos
.ident "GCC: (GNU) egcs-2.91.60 19981201 (egcs-1.1.1 release)"
Adding the option -freduce-all-givs cleans this up a great deal,
resulting in code which is much cleaner and has removed all of the
"fmovs" instructions.
(According to the documentation -O2 should turn on -freduce-all-givs.
This does not appear to be the case. Have I misread the
documentation? In any case I thin there is scope for a table
identifying exactly which options are switched on by -O1 and -O2.)
Hopwever turning on -freduce-all-givs 2.95.2 seems to be missing a
trick and fails to collapse all of the pointer increments into
one indexed update, as 2.91 did.
I hope this is enough information
sincerely
Keith Refson
--
Dr Keith Refson, "Paradigm is a word too often used by those who would
Dept of Earth Sciences like to have a new idea but cannot think of one."
Parks Road, -- Mervyn King, Deputy Governor, Bank of England
Oxford OX1 3PR, UK
Keith.Refson@ Tel: 01865 272026
earth.ox.ac.uk Fax: 01865 272072