This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
codegen differences for increment of a volatile int
- From: "Gary Funck" <gary at intrepid dot com>
- To: "Gcc Mailing List" <gcc at gcc dot gnu dot org>
- Date: Thu, 4 May 2006 14:45:50 -0700
- Subject: codegen differences for increment of a volatile int
I've been looking at how GCC 4.0 handles "volatile" internally,
and may have a question/two on that later, but in the meantime,
I noticed some interesting differences in generated code that I
thought were a bit unusual, and was wondering if someone here
might explain why GCC behaves as it does, and what might be the
recommended behavior?
Beginning with this simple example,
1 int j;
2 volatile int jv;
3 void p()
4 {
5 ++j;
6 ++jv;
7 }
when compiled with "gcc (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)"
the following code results:
incl j
movl jv, %eax
incl %eax
movl %eax, jv
Note that in the case where 'j' is _not_ volatile that a
single 'incl' was generated, but in the case where 'jv'
is volatile, the value was first loaded into a register,
then incremented and stored back into memory.
(asserting -O2 didn't substantially change the
generated code)
Compiling under "gcc (GCC) 4.0.2 20051125 (Red Hat 4.0.2-8)",
the compiler always uses the form where the value is first
loaded from memory into a register:
movl j, %eax
incl %eax
movl %eax, j
movl jv, %eax
incl %eax
movl %eax, jv
However, if -O2 is asserted, then the behavior reverts
back the same behavior as demonstrated in gcc 3.4:
incl j
movl jv, %eax
incl %eax
movl %eax, jv
[both systems are i386-redhat-linux (FC3 and FC4)]
Is there a technical reason that the use of "volatile" would
dictate the second form of increment that first loads the
value from memory into a register? I would think that a
systems programmer might expect the opposite behavior, where
"volatile" would imply the single instruction form of increment
(which is non-interruptible on single processor systems).