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).

Reply via email to