[PATCH][RFC] Remove volatile from data members in libstdc++

Andreas Krebbel krebbel1@de.ibm.com
Tue Aug 1 20:07:00 GMT 2006


Hello,

> unsigned global;
> 
> unsigned f(void)
> {
>   unsigned local = global;
>   unsigned i, sum = 0;
> 
>   for (i = 0; i < local; ++i) sum += i;
>   ...unrelated code that doesn't touch i, sum, local, or global ...
>   for (i = 0; i < local; ++i) sum -= i;
>   return sum;
> } 
> 
> then f may return a nonzero value since the second reference to local
> may involve an implicit reload of local from global, and hence may not
> get the same value as the first time around.  I claim that doesn't make
> the load from global look very atomic, though it perhaps fails in a way
> that different from what you might have expected.
> 
> This is certainly not something I know how to program around.  And I
> would like to have a way of guaranteeing that this doesn't happen.  I
> believe "volatile" does provide this guarantee.  It may be that gcc also
> provides it for nonvolatiles, but I don't see this written down
> anywhere.  It's certainly not guaranteed by any current language
> standards, or by currently proposed revisions.

on s390 we were actually fighting with such a problem.
See: http://marc.theaimsgroup.com/?l=linux-kernel&m=115401873804867&w=2

In the kernel example as well as in yours the rtl cse pass considers
the register where local may reside equivalent to the content
of the memory location of global. Assuming that the back ends cost
function returns the same costs for REGs as it does for MEMs cse may decide 
to read the memory location again.

The kernel fix was adding a barrier (asm memory clobber) right after 
copying the value from the global variable into local variable. That
way gcc has to assume that global got modified. I think the same fix
would work in your example. This should also be fine when gcc decides
to put local in a stack slot.

Bye,

-Andreas-



More information about the Gcc-patches mailing list