Search code examples
c++optimizationvolatile

Optimizing volatile variables


My understanding is that the C++ standard mandates that accesses to volatile objects are evaluated strictly according to the rules of the abstract machine. I am sure that means that the number of loads and stores to a given volatile variable cannot be changed, nor can those accesses be reordered.

But what about reordering with respect to other non-volatile access?

Can a fully redundant volatile access in both arms of an if statement be hoisted or sunk out of that if? E.g. Assuming no data dependencies would be violated can

if (e) {
    = non-volatile-load;
    non-volatile-store =;
    t = volatile-load;
    = non-volatile-load;
    non-volatile-store =;
} else {
    = non-volatile-load;
    non-volatile-store =;
    t = volatile-load;
    = non-volatile-load;
    non-volatile-store =;
}

be optimized to

t = volatile-load;
if (e) {
    = non-volatile-load;
    non-volatile-store =;
    = non-volatile-load;
    non-volatile-store =;
} else {
    = non-volatile-load;
    non-volatile-store =;
    = non-volatile-load;
    non-volatile-store =;
}

or to

if (e) {
    = non-volatile-load;
    non-volatile-store =;
    = non-volatile-load;
    non-volatile-store =;
} else {
    = non-volatile-load;
    non-volatile-store =;
    = non-volatile-load;
    non-volatile-store =;
}
t = volatile-load;

What if the volatile-load were instead a volatile-store?


Solution

  • Under the as-if rule,...

    ... conforming implementations ... are required to emulate (only) the observable behavior of the abstract machine as explained below

    And observable behavior is specified below as (emphasis mine)...

    – Accesses through volatile glvalues are evaluated strictly according to the rules of the abstract machine.

    So yes, the compiler may reorder accesses to non-volatile variables (of course within the boundaries of memory fences in a threaded environment; volatile offers no such semantics, atomic does).