Skip to content

Commit 7bee1a1

Browse files
authored
Implement pause (#7751)
The `pause` instruction is introduced by the shared-everything-threads proposal to make spinlocks more efficient. It has no observable semantics, so it is essentially a fancy nop.
1 parent 9b8259b commit 7bee1a1

29 files changed

+166
-64
lines changed

scripts/gen-s-parser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@
207207
("memory.atomic.wait32", "makeAtomicWait(Type::i32)"),
208208
("memory.atomic.wait64", "makeAtomicWait(Type::i64)"),
209209
("atomic.fence", "makeAtomicFence()"),
210+
("pause", "makePause()"),
210211
("i32.atomic.load8_u", "makeLoad(Type::i32, /*signed=*/false, 1, /*isAtomic=*/true)"),
211212
("i32.atomic.load16_u", "makeLoad(Type::i32, /*signed=*/false, 2, /*isAtomic=*/true)"),
212213
("i32.atomic.load", "makeLoad(Type::i32, /*signed=*/false, 4, /*isAtomic=*/true)"),

src/gen-s-parser.inc

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4859,12 +4859,23 @@ switch (buf[0]) {
48594859
return Ok{};
48604860
}
48614861
goto parse_error;
4862-
case 'p':
4863-
if (op == "pop"sv) {
4864-
CHECK_ERR(makePop(ctx, pos, annotations));
4865-
return Ok{};
4862+
case 'p': {
4863+
switch (buf[1]) {
4864+
case 'a':
4865+
if (op == "pause"sv) {
4866+
CHECK_ERR(makePause(ctx, pos, annotations));
4867+
return Ok{};
4868+
}
4869+
goto parse_error;
4870+
case 'o':
4871+
if (op == "pop"sv) {
4872+
CHECK_ERR(makePop(ctx, pos, annotations));
4873+
return Ok{};
4874+
}
4875+
goto parse_error;
4876+
default: goto parse_error;
48664877
}
4867-
goto parse_error;
4878+
}
48684879
case 'r': {
48694880
switch (buf[2]) {
48704881
case 'f': {

src/interpreter/interpreter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ struct ExpressionInterpreter : OverriddenVisitor<ExpressionInterpreter, Flow> {
7878
Flow visitAtomicWait(AtomicWait* curr) { WASM_UNREACHABLE("TODO"); }
7979
Flow visitAtomicNotify(AtomicNotify* curr) { WASM_UNREACHABLE("TODO"); }
8080
Flow visitAtomicFence(AtomicFence* curr) { WASM_UNREACHABLE("TODO"); }
81+
Flow visitPause(Pause* curr) { WASM_UNREACHABLE("TODO"); }
8182
Flow visitSIMDExtract(SIMDExtract* curr) { WASM_UNREACHABLE("TODO"); }
8283
Flow visitSIMDReplace(SIMDReplace* curr) { WASM_UNREACHABLE("TODO"); }
8384
Flow visitSIMDShuffle(SIMDShuffle* curr) { WASM_UNREACHABLE("TODO"); }

src/ir/ReFinalize.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ void ReFinalize::visitAtomicCmpxchg(AtomicCmpxchg* curr) { curr->finalize(); }
9191
void ReFinalize::visitAtomicWait(AtomicWait* curr) { curr->finalize(); }
9292
void ReFinalize::visitAtomicNotify(AtomicNotify* curr) { curr->finalize(); }
9393
void ReFinalize::visitAtomicFence(AtomicFence* curr) { curr->finalize(); }
94+
void ReFinalize::visitPause(Pause* curr) { curr->finalize(); }
9495
void ReFinalize::visitSIMDExtract(SIMDExtract* curr) { curr->finalize(); }
9596
void ReFinalize::visitSIMDReplace(SIMDReplace* curr) { curr->finalize(); }
9697
void ReFinalize::visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); }

src/ir/child-typer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
244244

245245
void visitAtomicFence(AtomicFence* curr) {}
246246

247+
void visitPause(Pause* curr) {}
248+
247249
void visitSIMDExtract(SIMDExtract* curr) { note(&curr->vec, Type::v128); }
248250

249251
void visitSIMDReplace(SIMDReplace* curr) {

src/ir/cost.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
116116
return AtomicCost + visit(curr->ptr) + visit(curr->notifyCount);
117117
}
118118
CostType visitAtomicFence(AtomicFence* curr) { return AtomicCost; }
119+
CostType visitPause(Pause* curr) {
120+
// When used properly, pause only makes things more efficient, so we do not
121+
// model it as having any cost.
122+
return 0;
123+
}
119124
CostType visitConst(Const* curr) { return 1; }
120125
CostType visitUnary(Unary* curr) {
121126
CostType ret = 0;

src/ir/effects.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,11 @@ class EffectAnalyzer {
643643
parent.writesMemory = true;
644644
parent.isAtomic = true;
645645
}
646+
void visitPause(Pause* curr) {
647+
// It's not much of a problem if pause gets reordered with anything, but
648+
// we don't want it to be removed entirely.
649+
parent.isAtomic = true;
650+
}
646651
void visitSIMDExtract(SIMDExtract* curr) {}
647652
void visitSIMDReplace(SIMDReplace* curr) {}
648653
void visitSIMDShuffle(SIMDShuffle* curr) {}

src/ir/possible-contents.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ struct InfoCollector
593593
void visitAtomicWait(AtomicWait* curr) { addRoot(curr); }
594594
void visitAtomicNotify(AtomicNotify* curr) { addRoot(curr); }
595595
void visitAtomicFence(AtomicFence* curr) {}
596+
void visitPause(Pause* curr) {}
596597
void visitSIMDExtract(SIMDExtract* curr) { addRoot(curr); }
597598
void visitSIMDReplace(SIMDReplace* curr) { addRoot(curr); }
598599
void visitSIMDShuffle(SIMDShuffle* curr) { addRoot(curr); }

src/ir/subtype-exprs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ struct SubtypingDiscoverer : public OverriddenVisitor<SubType> {
188188
void visitAtomicWait(AtomicWait* curr) {}
189189
void visitAtomicNotify(AtomicNotify* curr) {}
190190
void visitAtomicFence(AtomicFence* curr) {}
191+
void visitPause(Pause* curr) {}
191192
void visitSIMDExtract(SIMDExtract* curr) {}
192193
void visitSIMDReplace(SIMDReplace* curr) {}
193194
void visitSIMDShuffle(SIMDShuffle* curr) {}

src/parser/contexts.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ struct NullInstrParserCtx {
593593
Result<> makeAtomicFence(Index, const std::vector<Annotation>&) {
594594
return Ok{};
595595
}
596+
Result<> makePause(Index, const std::vector<Annotation>&) { return Ok{}; }
596597
Result<> makeSIMDExtract(Index,
597598
const std::vector<Annotation>&,
598599
SIMDExtractOp,
@@ -2301,6 +2302,10 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx {
23012302
return withLoc(pos, irBuilder.makeAtomicFence());
23022303
}
23032304

2305+
Result<> makePause(Index pos, const std::vector<Annotation>& annotations) {
2306+
return withLoc(pos, irBuilder.makePause());
2307+
}
2308+
23042309
Result<> makeSIMDExtract(Index pos,
23052310
const std::vector<Annotation>& annotations,
23062311
SIMDExtractOp op,

0 commit comments

Comments
 (0)