Let me try to break this down.<p>This is a wrong transformation:<p><pre><code> void writer(Tuple tuple) {
tuple.nonVolatileF = 5;
tuple.volatileF = 1;
}
void reader(Tuple tuple) {
int regNV = 0;
int cache = tuple.nonVolatileF;
int regV = tuple.volatileF;
if (regV == 1) { regNV = cache; }
// computation that uses both of the above
}
</code></pre>
because `cache` might get assigned before `tuple.nonVolatileF` is set. (The same is true of regV, but I guess the untransformed program had that, so you don't bother). But you said that the JMM guarantees that all reads in C_i - C_(i-1) will see writes in C_(i-1); this means that C_3 which reads `tuple.nonVolatileF` will see the write to that variable in C_2, no? Since you're constructing an execution, why didn't you interleave the execution to make this trivially true? Also, can't you wrap the writer in an atomic block during transformation?
Thanks for posting this, this looks really interesting.<p>one note:
>This blog post tries to show how some re-orderings (that may be done in as part of optimizing a Java program for performance) that intuitively seem <i>illegal</i> are, in fact, <i>illegal</i>, by deriving that <i>illegality</i> from directly the JMM spec.<p>Should the first 'illegal' read legal?