pub fn orderings(func: &mut Func, word: u32)Expand description
Rewrites every ordered access into the plain access this machine already makes ordered, and leaves a barrier where the machine needs one.
This is the one pass here whose reason is a memory model rather than a missing instruction, so
it is worth writing down what the model says. x86-64 is total store order. Every load is an
acquire, every store is a release, and an aligned access no wider than a word is indivisible
whether or not anybody asked for one. So an atomic_load at any ordering is the same mov a
load is, and so is an atomic_store at every ordering except the strongest, and rewriting
them into the plain access is not an approximation: it is the whole of what the machine does.
The one thing total store order does not give is a store followed by a load of a different
address staying in that order, and that is exactly what sequential consistency is missing. So a
sequentially consistent store is the same mov with an mfence behind it, which is the pair
gcc 16.2.0 writes. The fence is left in the IR as a fence rather than written here, because
what a barrier costs is a target question and crate::lower is where the target answers are.
A fence the program wrote is left alone for the same reason. Every ordering below the
strongest is nothing at all on this machine and the strongest is one instruction, and both of
those are decided by name in crate::lower where the instruction lives.
ยงWhy the width is checked
An access is only indivisible if the machine can do it in one go, which here means one, two,
four or eight bytes at an address aligned to its own width. Anything else is a run of accesses
and a run of accesses is not atomic at all, so it is left as the opcode it was and no rule
covers it, which is a compile error naming the instruction. That is the right answer: an
atomic access the machine cannot make atomic has no correct lowering, and a wrong one that
looks right is worse than a refusal. C says the same thing through __atomic_is_lock_free.
word is how many bytes the widest indivisible access carries, which is the same number the
widest move carries and is read from the machine for the reason bulk reads it.
This runs before every other pass here, so that what it produces is an ordinary load or store
that the width legalisation and everything after it get to see. An ordered access at a width the
machine has no register for would otherwise be a shape nothing later understands, since every
pass after this one is written about load and store by name.