ado@elsie.UUCP (Arthur David Olson) (10/09/88)
The good news is that strength reduction has arrived in version 1.29 of the
Gnu C compiler. The other news is that compiler still produces differing
assembler for functionally identical C code:
Script started on Sat Oct 8 15:32:48 1988
elsie$ cat try.c
extern int func();
void
a(int moving, int slack)
{
while (moving * moving <= slack) {
slack -= moving * moving;
moving = func();
}
}
void
b(int moving, int slack)
{
for ( ; ; ) {
if (moving * moving > slack)
break;
slack -= moving * moving;
moving = func();
}
}
elsie$
elsie$ gcc -v -S -O -fstrength-reduce try.c
gcc version 1.29
/usr/local/lib/gcc-cpp -v -undef -D__GNU__ -D__GNUC__ -Dvax -Dunix -D__OPTIMIZE__ try.c /tmp/cc014849.cpp
GNU CPP version 1.29
/usr/local/lib/gcc-cc1 /tmp/cc014849.cpp -quiet -dumpbase try.c -fstrength-reduce -O -version -o try.s
GNU C version 1.29 (vax) compiled by GNU C version 1.29.
elsie$ cat try.s
#NO_APP
.text
.align 1
.globl _a
_a:
.word 0x40
movl 4(ap),r1
movl 8(ap),r6
jbr L1
L3:
>>>> mull3 r1,r1,r0
subl2 r0,r6
calls $0,_func
movl r0,r1
L1:
>>>> mull3 r1,r1,r0
cmpl r0,r6
jleq L3
ret
.align 1
.globl _b
_b:
.word 0x40
movl 4(ap),r0
movl 8(ap),r6
L4:
>>>> mull2 r0,r0
cmpl r0,r6
jgtr L5
subl2 r0,r6
calls $0,_func
jbr L4
L5:
ret
elsie$ exit
script done on Sat Oct 8 15:33:11 1988
Functions "a" and "b" above are functionally equivalent, and the typical
programmers would almost surely produce "a" rather than "b". But you end up
with two multiplies each time through the loop generated for function "a"
while you end up with only one multiply each time through the loop for
function "b". (The multiplies are highlighted with ">>>>"'s above.
You also get the same results on a Sun--data not shown.)
If you have ideas for getting the better code generated for function "a", I'd
appreciate hearing from you.
--
ado@ncifcrf.gov ADO is a trademark of Ampex.