Skip to content

Commit 694f7e8

Browse files
authored
Update effects for acquire and release operations (#8399)
One of the primary use cases of `EffectAnalyzer` is to determine whether one expression (or a sequence of expressions) can be reordered before or after another expression (or sequence of expressions). Until now, the check whether effects "invalidate" each other and would prevent reordering has been symmetrical, checking read-write, write-write, and write-read conflicts as well as symmetric conditions that would prevent reordering. But acquire load and release store operations break this symmetry. Consider an expression A containing an acquire load (and no other effects) and an expression B containing a release store (and no other effects), where we know the accesses do not alias. Then if A is before B, it is not valid to reorder the expressions to have B before A because the acquire load cannot move forward past the release store and the release store cannot move back past the acquire load. However, if B is before A, it _is_ valid to reorder them, since memory accesses are generally allowed to move forward past acquire loads and back past release stores. Update `EffectAnalyzer` to take these allowed reorderings into account by tracking the strictest memory orders used to read or write to shared locations in the analyzed expressions. Now that the effect comparison to see whether reordering is prevented is no longer symmetric, rename it from `invalidates` to the more descriptive `orderedBefore`, where `A.orderedBefore(B)` returns true iff `A` ocurring before `B` implies that there is an ordering constraint that would prevent reordering `A` and `B` past each other. To accomodate users trying to move expressions in either direction, also add an `A.orderedAfter(B)` method for the case where `A` occurs after `B`. To avoid having to update all users at once, keep an `invalidates` method that checks for ordering in either direction. This maintains the symmetry many users depend on. For now, update only SimplifyLocals to use the more precise directional methods. Add tests both for all the interesting combinations of atomic effect ordering and for the correct use of directionality in SimplifyLocals.
1 parent 1ed55c3 commit 694f7e8

File tree

6 files changed

+1066
-192
lines changed

6 files changed

+1066
-192
lines changed

src/ir/effects.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ std::ostream& operator<<(std::ostream& o, wasm::EffectAnalyzer& effects) {
4545
if (effects.writesMemory) {
4646
o << "writesMemory\n";
4747
}
48+
if (effects.readsSharedMemory) {
49+
o << "readsSharedMemory\n";
50+
}
51+
if (effects.writesSharedMemory) {
52+
o << "writesSharedMemory\n";
53+
}
4854
if (effects.readsTable) {
4955
o << "readsTable\n";
5056
}
@@ -57,20 +63,35 @@ std::ostream& operator<<(std::ostream& o, wasm::EffectAnalyzer& effects) {
5763
if (effects.writesStruct) {
5864
o << "writesStruct\n";
5965
}
60-
if (effects.readsArray) {
66+
if (effects.readsSharedMutableStruct) {
67+
o << "readsSharedMutableStruct\n";
68+
}
69+
if (effects.writesSharedStruct) {
70+
o << "writesSharedStruct\n";
71+
}
72+
if (effects.readsMutableArray) {
6173
o << "readsArray\n";
6274
}
6375
if (effects.writesArray) {
6476
o << "writesArray\n";
6577
}
78+
if (effects.readsSharedMutableArray) {
79+
o << "readsSharedMutableArray\n";
80+
}
81+
if (effects.writesSharedArray) {
82+
o << "writesSharedArray\n";
83+
}
6684
if (effects.trap) {
6785
o << "trap\n";
6886
}
6987
if (effects.implicitTrap) {
7088
o << "implicitTrap\n";
7189
}
72-
if (effects.isAtomic) {
73-
o << "isAtomic\n";
90+
if (effects.readOrder != wasm::MemoryOrder::Unordered) {
91+
o << "readOrder " << effects.readOrder << "\n";
92+
}
93+
if (effects.writeOrder != wasm::MemoryOrder::Unordered) {
94+
o << "writeOrder " << effects.writeOrder << "\n";
7495
}
7596
if (effects.throws_) {
7697
o << "throws_\n";

0 commit comments

Comments
 (0)