home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.gcc.bug
- Path: sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!web.apc.org!colin
- From: colin@web.apc.org (Colin Plumb)
- Subject: Gcc 2.2.2 (Amiga 68000) emitting suboptimal code
- Message-ID: <m0n4p3W-000024C@web.apc.org>
- Sender: gnulists@ai.mit.edu
- Organization: GNUs Not Usenet
- Distribution: gnu
- Date: Thu, 24 Dec 1992 09:40:00 GMT
- Approved: bug-gcc@prep.ai.mit.edu
- Lines: 105
-
- I had an inner loop looking for a non-zero word in an array that
- I thought was perfect for the 68000's DBcc instruction. So I
- coded it up and tried to compile. H'm... no DBcc instruction.
- I progressively wrote code closer and closer to raw assembler and
- eventually ended up with the follwing (excerpt from a larger chunk
- of code):
- unsigned long
- foo(unsigned long *p, unsigned short size)
- {
- unsigned short len;
- unsigned long bits;
-
- len = size-1;
- do {
- bits = *p++;
- } while (!bits && len--); /* STRONG hint to use dbne */
- if (bits)
- return bits;
- return 0;
- }
-
- Now, that last fiddling isn't really necessary; it's obviously equivalent
- to "return bits;", but I wanted to see if Gcc was smart enough not to
- re-test the bits variable after the dbne, and hoping it wouldn't be bright
- enough to optimize that out.
-
- If you read the 68000 data books, the condition on the while is
- precisely what dbne is described as doing, except for comparing
- --len with -1 instead of len-- with 0, but it's the same thing.
- I was hoping to get something like:
-
- .text
- .even
- .globl _foo
- _foo:
- movel sp@(4),a0
- movew sp@(10),d1
- L1:
- movel a0@+,d0
- dbeq d1,L1
- bne L2
- moveq #0,d0
- L2:
- rts
-
- Running gcc, however:
-
- Reading specs from gcc:compilers/amiga/2.2.2/specs
- gcc version 2.2.2
- gcc:compilers/amiga/2.2.2/cpp -lang-c -v -undef -D__GNUC__=2 -Dmc68000 -Damiga -Damigados -DMCH_AMIGA -DAMIGA -D__mc68000__ -D__amiga__ -D__amigados__ -D__MCH_AMIGA__ -D__AMIGA__ -D__mc68000 -D__amiga -D__amigados -D__MCH_AMIGA -D__AMIGA -D__OPTIMIZE__ -Dmc68010 foo.c t:cc059344.i
- GNU CPP version 2.2.2 (68k, MIT syntax)
- gcc:compilers/amiga/2.2.2/cc1 t:cc059344.i -quiet -dumpbase foo.c -O2 -version -o foo.s
- GNU C version 2.2.2 (68k, MIT syntax) compiled by GNU C version 2.2.2.
-
- Produces the following code:
-
- #NO_APP
- gcc2_compiled.:
- .text
- .even
- .globl _foo
- _foo:
- movel d2,sp@-
- movel sp@(8),a0
- movew #65535,d0
- movew d0,d1
- addw sp@(14),d1
- L2:
- movel a0@+,d2
- jne L3
- subqw #1,d1
- cmpw d1,d0
- jne L2
- L3:
- tstl d2
- sne d0
- extw d0
- extl d0
- andl d2,d0
- movel sp@+,d2
- rts
-
- The code between L2 and L3 is quite remarkable in how close to the operation
- of dbne it is. Other then the deficiency of not using dbne, I note the
- following sub-optimalities with the code:
- - L3 should be positioned one instruction later. At the target of
- the jne, (cc0) is already set to correspond to d2, so it is not
- necessary to re-test its value.
- - Instead of "cmpw d1,d0/jne L2" just before L3, perhaps "jcs L2"
- would suffice.
- - d2 could have been spilled into a1 instead of the stack.
-
- In my lavish praise of gcc, I've been saying I report as a bug any instance
- where I could do better by hand without really massive trickery. Thanks
- for a great compiler, but this is such an example.
-
- (BTW, the commercial compiler (Manx Aztec C 5.2) I have produces even
- worse code, so don't think I'm exactly upset.)
-
- Oh, yes, noted other places: gcc still does not do tail-recursion
- optimisation even on calls to functions of no arguments, from functions
- with no stack frames. Sigh. Oh, well.
- --
- -Colin
-
-