GCC: Inefficient register usage?

Christopher Bahns chris@bahns.com
Fri Aug 25 00:48:00 GMT 2000


Hello again folks,

It seems that GCC is generating unnecessary instructions to perform
rather simple operations. A simple bitwise-or operation generates three
instructions (12 bytes), compared to one instruction (6 bytes, I assume)
generated by the Microtec Research (MRI) compiler. I suspect that this
is at least part of the reason I'm seeing a 17% increase in machine code
output size when going from MRI to GNU/GCC. I also fear that this makes
the code a bit slower. I just don't understand why GCC is doing this in
situations that appear to be obvious opportunities to save some space
(and improve performance as well?).


Here is my environment:
Windows NT 4.0 Workstation (sp6a)
Cygnus Cygwin 1.1.2
binutils-2.10
gcc-2.95.2
newlib-1.8.2
Target: m68k-coff

Here is my C-language function:
_________________________________________________
void MyFunction( void )
{
   *(volatile unsigned char*)(0xfffffffe) |= 0x40;
}
_________________________________________________

Here is the GCC assembly listing (M68000 target):
_________________________________________________
 148                .                   globl MyFunction
 149                                    MyFunction:
 154 008c 1038 FFFE        move.b -2.w,%d0
 155 0090 0000 0040         or.b #64,%d0
 156 0094 11C0 FFFE       move.b %d0,-2.w
 159 0098 4E75                  rts
_________________________________________________

Here is the MRI assembly listing:
_________________________________________________
 XDEF _MyFunction
_MyFunction:
 ori.b #64,-2
 rts
_________________________________________________


I tried various optimizations, including -O2, -Os, -fno-force-mem, and
-fno-force-addr. Mixing these four optimizations in different ways had
no effect on the output (I always used either -O2 or -Os in each case).
Other optimizations (already in use) that I assume are unrelated are
-funsigned-char, -fdefer-pop, and -fomit-frame-pointer.

However, after removing the "volatile" keyword, GCC generates the same
concise output as MRI. But, I already discovered that I *need* to use
the volatile keyword when accessing hardware registers. I really don't
see why the volatile keyword should affect this kind of optimization.

Hmm... I know that I'm using "volatile" to tell the compiler not to
optimize out certain pieces of code. But, it seems like it's avoiding
*all* possible optimizations for that line of code, not just those that
might eliminate it. I'd like to see it include the assignment in the
output (avoiding optimizations that could eliminate it), but allow other
optimizations to apply that might reduce its size or improve efficiency
without removing it entirely.

Well, I cannot just remove "volatile" from all of the places that
"appear" not to need it. I do try only to use it where it makes sense,
but that happens to be in quite a lot of places in our code. I don't
know how much overall it would save, but every little bit counts, and I
hate to see this kind of inefficiency when comparing the MRI output to
that of GNU.

Can someone advise as to why GCC is not able to (or does not want to)
optimize code that uses the "volatile" keyword without actually removing
the code? Are there any command-line options that I'm missing that may
apply to my problem? Can I rebuild the compiler in a different way to
affect its behavior?

Thanks a lot for any info.
Chris


More information about the crossgcc mailing list