[llvm-commits] patch: CXAGuardElimination pass.

Eli Friedman eli.friedman at gmail.com
Tue May 26 10:07:55 PDT 2009


On Tue, May 26, 2009 at 9:07 AM, Luke Dalessandro
<luked at cs.rochester.edu> wrote:
> I agree that if the cxa_guard routines are meant to have locking
> semantics, then there is no data race on gval2 (given a Java/C++0X-ish
> style synchronization model).
>
> What I was trying to point out was that, if the cxa guards don't have a
> memory model synchronization component, then the transformation is fine,
> and the unexpected result is fine.

The fundamental thing that the guards guarantee is that the variable
is initialized before any of the code after the initialization is
executed.  That by itself seems like it should be enough.

> If the cxa guards to have a synchronization component, then it should be
> modeled as part of the guard call, i.e., the acquire call clobbers
> memory and serves as a compiler fence. Whatever the modeled memory
> behavior of gcc's __sync_lock_test_and_set is probably fine. This should
> suppress the optimization that eliminates the load inside of c() when
> the guarded constructor is inlined (or eliminates the load inside c() by
> hoisting the acquire over the store to gval1). I think this prevents
> guarded constructors that have side effects from becoming side effect
> free -- allowing the guard eliminator to run as coded.

The optimization in question works as follows: gval1 is an internal
variable whose address is never taken with a single store to the
variable.  The store dominates the load inside the inlined
constructor.  Therefore, the store's value can be propagated into the
constructor.  No amount of messing with the memory model changes that.

> I'm still pretty sure that removing guard pairs is likely to require
> leaving behind a compiler+hardware memory fence though, which will
> prevent future optimizations (and the hardware) from doing things they
> shouldn't.

Hmm, possibly.

-Eli



More information about the llvm-commits mailing list