Poor code generation for M68k volatile variables
Eric Norum
eric@cls.usask.ca
Thu Jun 15 08:33:00 GMT 2000
Declaring a variable `volatile' makes access to it less efficient on
m68k targets.
Consider the following program:
unsigned long foo;
volatile unsigned long bar;
void bletch (void)
{
foo++;
bar++;
}
void bletchp (void)
{
++foo;
++bar;
}
Compiling with:
eric@pollux 441> m68k-rtems-gcc --version
2.95.2
eric@pollux 442> m68k-rtems-gcc -O9 -fomit-frame-pointer -S a.c
gives the following assembler file:
.file "a.c"
gcc2_compiled.:
.comm foo,4,2
.comm bar,4,2
.text
.globl bletch
.type bletch,@function
bletch:
addq.l #1,foo
move.l bar,%d0
addq.l #1,%d0
move.l %d0,bar
rts
nop
.Lfe1:
.size bletch,.Lfe1-bletch
.globl bletchp
.type bletchp,@function
bletchp:
addq.l #1,foo
move.l bar,%d0
addq.l #1,%d0
move.l %d0,bar
rts
nop
.Lfe2:
.size bletchp,.Lfe2-bletchp
.ident "GCC: (GNU) 2.95.2 19991024 (release)"
Notice how it takes 3 times as many instructions to increment `bar'?
I don't see how doing the increment with a single
addq.l #1,bar
would violate the semantics of volatile. The variable would still be
read, modified, and written as a 32-bit value. The compiler certainly
knows how to increment variables with this instruction as shown above in
the increment of `foo'.
This sort of inefficiency pops up in the worst possible places -- often
where the code is accessing I/O registers and I am trying to squeeze
every bit of performance out of the hardware. It also shows up in a
very heavily used piece of code in the RTEMS (Real-Time Executive for
Multiprocessor Systems) core. I realize that I could work around this,
but I'd rather not have to start adding `asm' statements all over the
place.
--
Eric Norum eric@cls.usask.ca
Canadian Light Source Phone: (306) 966-6308
University of Saskatchewan FAX: (306) 966-6058
Saskatoon, Canada.
More information about the Gcc-bugs
mailing list