While working on the RISC-V backend, we got bug reports from language frontends
that we were emitting instructions for compiler-only barriers: while emittiong
instructions wasn't incorrect in our case, it was inefficient, and contradicted
high-level language documentation which claimed that certain constructs (C++'s
std::atomic_signal_fence, C's atomic_signal_fence, Rust's
compiler_barrier) would not result in assembly instructions.
Many LLVM Target backends implement the same "MEMBARRIER" target-specific ISD
node to represent a compiler-only barrier, which we could have replicated in the
RISC-V backend, but I felt that it is now a reasonable time to have a
target-independent method for achieving the same, which backends can opt-in to
if they don't need to emit instructions.
It's not clear to me that all targets have strong enough memory models that this
should be applied across the board, but I've tried to implement it in a way that
backends can opt-in to using a target-independent barrier.
At the moment, I've modified the following backends to use the
target-independent barrier, to show how other backends could be updated:
- X86
- RISC-V
- Arm
- AArch64
I plan to write a short RFC for llvm-dev about this patch, as it has the
potential to affect many backends, including out-of-tree backends.