Description
C++ 11 provides std::atomic_signal_fence
and std::atomic_thread_fence
, and LLVM IR's fence
instruction also takes a syncscope
argument, which can be either "singlethread"
(for a single thread, such as signal handlers) or "<target-scope>"
(for multiple threads). And there are people who use asm volatile(""::: "memory")
with a similar usage to fences. How do we support these fences in wasm? Some discussions have been going on in this CL, but the CL itself was not very much related to the topic.
std::atomic_thread_fence
/ LLVM's fence syncscope("<target-scope>")
Wasm does not have a fence instruction, and currently all atomic memory instructions are sequentially consistent, but we still need something because fences also order non-atomic instructions. I submitted a CL that converts a fence into a sequence of
get_global $__stack_pointer
i32.atomic.rmw.or 0
which is basically an idempotent atomic RMW instruction.
std::atomic_signal_fence
/ LLVM's fence syncscope("singlethread")
Currently the fence CL does not distinguish syncscopes, treating both of them the same way conservatively. But for fences that work only within a thread, we may not need to emit an atomic idempotent RMW instruction; preventing instruction reordering across it during the backend compilation (using a pseudo instruction or something) would be sufficient, and it can eventually be lowered down to 0 instruction. What do you think?
asm volatile(""::: "memory")
We are currently doing nothing for this, but how about treating this as the same way as a signal fence, meaning it will become a pseudo instruction that prevents reordering within the compiler backend but eventually be converted to 0 instruction?