Consider this code, where x
and y
are integers:
if (x)
y = 42;
Is the following compiler transformation allowed ?
int tmp = y;
y = 42;
if (!x)
y = tmp;
context:
This is from Bjarne Stroustrup's FAQ:
// start with x==0 and y==0
if (x) y = 1; // Thread 1
if (y) x = 1; // Thread 2
The FAQ states this is data race free; with x
and y
both 0, none of the vars should be written to.
But what if the transformation is allowed ?
Program transformations may be specified as automated procedures that modify compiler data structures (e.g. abstract syntax trees) representing the program text, or may be specified more conveniently using patterns or templates representing parameterized source code fragments.
These transformations attempt to reduce the number of dynamic instances of the operation; they may, in fact, increase the number of static instances. 4. same number of executions – Sometimes, the compiler can improve the code by relocating operations without reducing their execution frequency.
A transform code is an example of a constrained source code. Constrained source codes are, loosely speaking, suboptimal but low in complexity, which arises from the modularization of the encoding process. This approach allows “simple coding” to be used with high efficiency.
The criteria for code improvement transformations: 1. The transformation must preserve the meaning of programs. That is, the optimization must not change the output produced by a program for a given input, or cause an error such as division by zero, that was not present in the original source program.
Unlike I wrote in my incorrect comment, this transformation is actually not allowed if y
is potentially shared between threads and the compiler cannot prove any existing UB in the original code.
The standard explicitly says:
Compiler transformations that introduce assignments to a potentially shared memory location that would not be modified by the abstract machine are generally precluded by this standard, since such an assignment might overwrite another assignment by a different thread in cases in which an abstract machine execution would not have encountered a data race.
[intro.multithread] (1.10/22) in N3337, (1.10/25) in N4141.
So if x
is always 0, the original code would be race-free, while the transformed one wouldn't. Thus the transformation is not legal.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With