Skip to content

Commit b109a1e

Browse files
authored
[SharedEverything] Add array.atomic.get/set (#7621)
1 parent c9ec43d commit b109a1e

18 files changed

+248
-49
lines changed

scripts/gen-s-parser.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,11 @@
640640
("array.get", "makeArrayGet()"),
641641
("array.get_s", "makeArrayGet(true)"),
642642
("array.get_u", "makeArrayGet(false)"),
643+
("array.atomic.get", "makeAtomicArrayGet()"),
644+
("array.atomic.get_s", "makeAtomicArrayGet(true)"),
645+
("array.atomic.get_u", "makeAtomicArrayGet(false)"),
643646
("array.set", "makeArraySet()"),
647+
("array.atomic.set", "makeAtomicArraySet()"),
644648
("array.len", "makeArrayLen()"),
645649
("array.copy", "makeArrayCopy()"),
646650
("array.fill", "makeArrayFill()"),

src/binaryen-c.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,17 +1822,22 @@ BinaryenExpressionRef BinaryenArrayGet(BinaryenModuleRef module,
18221822
BinaryenExpressionRef index,
18231823
BinaryenType type,
18241824
bool signed_) {
1825-
return static_cast<Expression*>(
1826-
Builder(*(Module*)module)
1827-
.makeArrayGet((Expression*)ref, (Expression*)index, Type(type), signed_));
1825+
return static_cast<Expression*>(Builder(*(Module*)module)
1826+
.makeArrayGet((Expression*)ref,
1827+
(Expression*)index,
1828+
MemoryOrder::Unordered,
1829+
Type(type),
1830+
signed_));
18281831
}
18291832
BinaryenExpressionRef BinaryenArraySet(BinaryenModuleRef module,
18301833
BinaryenExpressionRef ref,
18311834
BinaryenExpressionRef index,
18321835
BinaryenExpressionRef value) {
1833-
return static_cast<Expression*>(
1834-
Builder(*(Module*)module)
1835-
.makeArraySet((Expression*)ref, (Expression*)index, (Expression*)value));
1836+
return static_cast<Expression*>(Builder(*(Module*)module)
1837+
.makeArraySet((Expression*)ref,
1838+
(Expression*)index,
1839+
(Expression*)value,
1840+
MemoryOrder::Unordered));
18361841
}
18371842
BinaryenExpressionRef BinaryenArrayLen(BinaryenModuleRef module,
18381843
BinaryenExpressionRef ref) {

src/gen-s-parser.inc

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,45 @@ switch (buf[0]) {
2222
goto parse_error;
2323
case 'r': {
2424
switch (buf[6]) {
25+
case 'a': {
26+
switch (buf[13]) {
27+
case 'g': {
28+
switch (buf[16]) {
29+
case '\0':
30+
if (op == "array.atomic.get"sv) {
31+
CHECK_ERR(makeAtomicArrayGet(ctx, pos, annotations));
32+
return Ok{};
33+
}
34+
goto parse_error;
35+
case '_': {
36+
switch (buf[17]) {
37+
case 's':
38+
if (op == "array.atomic.get_s"sv) {
39+
CHECK_ERR(makeAtomicArrayGet(ctx, pos, annotations, true));
40+
return Ok{};
41+
}
42+
goto parse_error;
43+
case 'u':
44+
if (op == "array.atomic.get_u"sv) {
45+
CHECK_ERR(makeAtomicArrayGet(ctx, pos, annotations, false));
46+
return Ok{};
47+
}
48+
goto parse_error;
49+
default: goto parse_error;
50+
}
51+
}
52+
default: goto parse_error;
53+
}
54+
}
55+
case 's':
56+
if (op == "array.atomic.set"sv) {
57+
CHECK_ERR(makeAtomicArraySet(ctx, pos, annotations));
58+
return Ok{};
59+
}
60+
goto parse_error;
61+
default: goto parse_error;
62+
}
63+
}
2564
case 'c':
2665
if (op == "array.copy"sv) {
2766
CHECK_ERR(makeArrayCopy(ctx, pos, annotations));

src/ir/possible-contents.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,10 +1059,11 @@ struct InfoCollector
10591059
// part of the main IR, which is potentially confusing during debugging,
10601060
// however, which is a downside.
10611061
Builder builder(*getModule());
1062-
auto* get =
1063-
builder.makeArrayGet(curr->srcRef, curr->srcIndex, curr->srcRef->type);
1062+
auto* get = builder.makeArrayGet(
1063+
curr->srcRef, curr->srcIndex, MemoryOrder::Unordered, curr->srcRef->type);
10641064
visitArrayGet(get);
1065-
auto* set = builder.makeArraySet(curr->destRef, curr->destIndex, get);
1065+
auto* set = builder.makeArraySet(
1066+
curr->destRef, curr->destIndex, get, MemoryOrder::Unordered);
10661067
visitArraySet(set);
10671068
}
10681069
void visitArrayFill(ArrayFill* curr) {
@@ -1071,7 +1072,8 @@ struct InfoCollector
10711072
}
10721073
// See ArrayCopy, above.
10731074
Builder builder(*getModule());
1074-
auto* set = builder.makeArraySet(curr->ref, curr->index, curr->value);
1075+
auto* set = builder.makeArraySet(
1076+
curr->ref, curr->index, curr->value, MemoryOrder::Unordered);
10751077
visitArraySet(set);
10761078
}
10771079
template<typename ArrayInit> void visitArrayInit(ArrayInit* curr) {
@@ -1092,7 +1094,8 @@ struct InfoCollector
10921094
Builder builder(*getModule());
10931095
auto* get = builder.makeLocalGet(-1, valueType);
10941096
addRoot(get);
1095-
auto* set = builder.makeArraySet(curr->ref, curr->index, get);
1097+
auto* set =
1098+
builder.makeArraySet(curr->ref, curr->index, get, MemoryOrder::Unordered);
10961099
visitArraySet(set);
10971100
}
10981101
void visitArrayInitData(ArrayInitData* curr) { visitArrayInit(curr); }

src/parser/contexts.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -815,12 +815,13 @@ struct NullInstrParserCtx {
815815
return Ok{};
816816
}
817817
template<typename HeapTypeT>
818-
Result<>
819-
makeArrayGet(Index, const std::vector<Annotation>&, HeapTypeT, bool) {
818+
Result<> makeArrayGet(
819+
Index, const std::vector<Annotation>&, HeapTypeT, bool, MemoryOrder) {
820820
return Ok{};
821821
}
822822
template<typename HeapTypeT>
823-
Result<> makeArraySet(Index, const std::vector<Annotation>&, HeapTypeT) {
823+
Result<>
824+
makeArraySet(Index, const std::vector<Annotation>&, HeapTypeT, MemoryOrder) {
824825
return Ok{};
825826
}
826827
Result<> makeArrayLen(Index, const std::vector<Annotation>&) { return Ok{}; }
@@ -2693,14 +2694,16 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx {
26932694
Result<> makeArrayGet(Index pos,
26942695
const std::vector<Annotation>& annotations,
26952696
HeapType type,
2696-
bool signed_) {
2697-
return withLoc(pos, irBuilder.makeArrayGet(type, signed_));
2697+
bool signed_,
2698+
MemoryOrder order) {
2699+
return withLoc(pos, irBuilder.makeArrayGet(type, signed_, order));
26982700
}
26992701

27002702
Result<> makeArraySet(Index pos,
27012703
const std::vector<Annotation>& annotations,
2702-
HeapType type) {
2703-
return withLoc(pos, irBuilder.makeArraySet(type));
2704+
HeapType type,
2705+
MemoryOrder order) {
2706+
return withLoc(pos, irBuilder.makeArraySet(type, order));
27042707
}
27052708

27062709
Result<> makeArrayLen(Index pos, const std::vector<Annotation>& annotations) {

src/parser/parsers.h

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,15 @@ template<typename Ctx>
274274
Result<>
275275
makeArrayGet(Ctx&, Index, const std::vector<Annotation>&, bool signed_ = false);
276276
template<typename Ctx>
277+
Result<> makeAtomicArrayGet(Ctx&,
278+
Index,
279+
const std::vector<Annotation>&,
280+
bool signed_ = false);
281+
template<typename Ctx>
277282
Result<> makeArraySet(Ctx&, Index, const std::vector<Annotation>&);
278283
template<typename Ctx>
284+
Result<> makeAtomicArraySet(Ctx&, Index, const std::vector<Annotation>&);
285+
template<typename Ctx>
279286
Result<> makeArrayLen(Ctx&, Index, const std::vector<Annotation>&);
280287
template<typename Ctx>
281288
Result<> makeArrayCopy(Ctx&, Index, const std::vector<Annotation>&);
@@ -2411,15 +2418,39 @@ Result<> makeArrayGet(Ctx& ctx,
24112418
bool signed_) {
24122419
auto type = typeidx(ctx);
24132420
CHECK_ERR(type);
2414-
return ctx.makeArrayGet(pos, annotations, *type, signed_);
2421+
return ctx.makeArrayGet(
2422+
pos, annotations, *type, signed_, MemoryOrder::Unordered);
2423+
}
2424+
2425+
template<typename Ctx>
2426+
Result<> makeAtomicArrayGet(Ctx& ctx,
2427+
Index pos,
2428+
const std::vector<Annotation>& annotations,
2429+
bool signed_) {
2430+
auto order = memorder(ctx);
2431+
CHECK_ERR(order);
2432+
auto type = typeidx(ctx);
2433+
CHECK_ERR(type);
2434+
return ctx.makeArrayGet(pos, annotations, *type, signed_, *order);
24152435
}
24162436

24172437
template<typename Ctx>
24182438
Result<>
24192439
makeArraySet(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) {
24202440
auto type = typeidx(ctx);
24212441
CHECK_ERR(type);
2422-
return ctx.makeArraySet(pos, annotations, *type);
2442+
return ctx.makeArraySet(pos, annotations, *type, MemoryOrder::Unordered);
2443+
}
2444+
2445+
template<typename Ctx>
2446+
Result<> makeAtomicArraySet(Ctx& ctx,
2447+
Index pos,
2448+
const std::vector<Annotation>& annotations) {
2449+
auto order = memorder(ctx);
2450+
CHECK_ERR(order);
2451+
auto type = typeidx(ctx);
2452+
CHECK_ERR(type);
2453+
return ctx.makeArraySet(pos, annotations, *type, *order);
24232454
}
24242455

24252456
template<typename Ctx>

src/passes/Print.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2372,19 +2372,29 @@ struct PrintExpressionContents
23722372
}
23732373
void visitArrayGet(ArrayGet* curr) {
23742374
const auto& element = curr->ref->type.getHeapType().getArray().element;
2375+
printMedium(o, "array");
2376+
if (curr->order != MemoryOrder::Unordered) {
2377+
printMedium(o, ".atomic");
2378+
}
23752379
if (element.type == Type::i32 && element.packedType != Field::not_packed) {
23762380
if (curr->signed_) {
2377-
printMedium(o, "array.get_s ");
2381+
printMedium(o, ".get_s ");
23782382
} else {
2379-
printMedium(o, "array.get_u ");
2383+
printMedium(o, ".get_u ");
23802384
}
23812385
} else {
2382-
printMedium(o, "array.get ");
2386+
printMedium(o, ".get ");
23832387
}
2388+
printMemoryOrder(curr->order);
23842389
printHeapTypeName(curr->ref->type.getHeapType());
23852390
}
23862391
void visitArraySet(ArraySet* curr) {
2387-
printMedium(o, "array.set ");
2392+
if (curr->order == MemoryOrder::Unordered) {
2393+
printMedium(o, "array.set ");
2394+
} else {
2395+
printMedium(o, "array.atomic.set ");
2396+
}
2397+
printMemoryOrder(curr->order);
23882398
printHeapTypeName(curr->ref->type.getHeapType());
23892399
}
23902400
void visitArrayLen(ArrayLen* curr) { printMedium(o, "array.len"); }

src/tools/fuzzing/fuzzing.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5058,14 +5058,16 @@ Expression* TranslateToFuzzReader::makeArrayGet(Type type) {
50585058
// Only rarely emit a plain get which might trap. See related logic in
50595059
// ::makePointer().
50605060
if (allowOOB && oneIn(10)) {
5061-
return builder.makeArrayGet(ref, index, type, signed_);
5061+
return builder.makeArrayGet(
5062+
ref, index, MemoryOrder::Unordered, type, signed_);
50625063
}
50635064
// To avoid a trap, check the length dynamically using this pattern:
50645065
//
50655066
// index < array.len ? array[index] : ..some fallback value..
50665067
//
50675068
auto check = makeArrayBoundsCheck(ref, index, funcContext->func, builder);
5068-
auto* get = builder.makeArrayGet(check.getRef, check.getIndex, type, signed_);
5069+
auto* get = builder.makeArrayGet(
5070+
check.getRef, check.getIndex, MemoryOrder::Unordered, type, signed_);
50695071
auto* fallback = makeTrivial(type);
50705072
return builder.makeIf(check.condition, get, fallback);
50715073
}
@@ -5083,14 +5085,15 @@ Expression* TranslateToFuzzReader::makeArraySet(Type type) {
50835085
// Only rarely emit a plain get which might trap. See related logic in
50845086
// ::makePointer().
50855087
if (allowOOB && oneIn(10)) {
5086-
return builder.makeArraySet(ref, index, value);
5088+
return builder.makeArraySet(ref, index, value, MemoryOrder::Unordered);
50875089
}
50885090
// To avoid a trap, check the length dynamically using this pattern:
50895091
//
50905092
// if (index < array.len) array[index] = value;
50915093
//
50925094
auto check = makeArrayBoundsCheck(ref, index, funcContext->func, builder);
5093-
auto* set = builder.makeArraySet(check.getRef, check.getIndex, value);
5095+
auto* set = builder.makeArraySet(
5096+
check.getRef, check.getIndex, value, MemoryOrder::Unordered);
50945097
return builder.makeIf(check.condition, set);
50955098
}
50965099

src/tools/wasm-ctor-eval.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -960,8 +960,10 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
960960
set =
961961
builder.makeStructSet(index, getGlobal, value, MemoryOrder::Unordered);
962962
} else {
963-
set = builder.makeArraySet(
964-
getGlobal, builder.makeConst(int32_t(index)), value);
963+
set = builder.makeArraySet(getGlobal,
964+
builder.makeConst(int32_t(index)),
965+
value,
966+
MemoryOrder::Unordered);
965967
}
966968

967969
(*startBlock)->list.push_back(set);

src/wasm-binary.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,10 @@ enum ASTNodes {
11971197
StructAtomicRMWXor = 0x64,
11981198
StructAtomicRMWXchg = 0x65,
11991199
StructAtomicRMWCmpxchg = 0x66,
1200+
ArrayAtomicGet = 0x67,
1201+
ArrayAtomicGetS = 0x68,
1202+
ArrayAtomicGetU = 0x69,
1203+
ArrayAtomicSet = 0x6a,
12001204

12011205
// stringref opcodes
12021206

src/wasm-builder.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,22 +1034,27 @@ class Builder {
10341034
}
10351035
ArrayGet* makeArrayGet(Expression* ref,
10361036
Expression* index,
1037+
MemoryOrder order,
10371038
Type type,
10381039
bool signed_ = false) {
10391040
auto* ret = wasm.allocator.alloc<ArrayGet>();
10401041
ret->ref = ref;
10411042
ret->index = index;
10421043
ret->type = type;
10431044
ret->signed_ = signed_;
1045+
ret->order = order;
10441046
ret->finalize();
10451047
return ret;
10461048
}
1047-
ArraySet*
1048-
makeArraySet(Expression* ref, Expression* index, Expression* value) {
1049+
ArraySet* makeArraySet(Expression* ref,
1050+
Expression* index,
1051+
Expression* value,
1052+
MemoryOrder order) {
10491053
auto* ret = wasm.allocator.alloc<ArraySet>();
10501054
ret->ref = ref;
10511055
ret->index = index;
10521056
ret->value = value;
1057+
ret->order = order;
10531058
ret->finalize();
10541059
return ret;
10551060
}

src/wasm-delegations-fields.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,12 +703,14 @@ DELEGATE_FIELD_CASE_START(ArrayGet)
703703
DELEGATE_FIELD_CHILD(ArrayGet, index)
704704
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ArrayGet, ref)
705705
DELEGATE_FIELD_INT(ArrayGet, signed_)
706+
DELEGATE_FIELD_INT(ArraySet, order)
706707
DELEGATE_FIELD_CASE_END(ArrayGet)
707708

708709
DELEGATE_FIELD_CASE_START(ArraySet)
709710
DELEGATE_FIELD_CHILD(ArraySet, value)
710711
DELEGATE_FIELD_CHILD(ArraySet, index)
711712
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ArraySet, ref)
713+
DELEGATE_FIELD_INT(ArraySet, order)
712714
DELEGATE_FIELD_CASE_END(ArraySet)
713715

714716
DELEGATE_FIELD_CASE_START(ArrayLen)

src/wasm-ir-builder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,8 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
228228
Result<> makeArrayNewData(HeapType type, Name data);
229229
Result<> makeArrayNewElem(HeapType type, Name elem);
230230
Result<> makeArrayNewFixed(HeapType type, uint32_t arity);
231-
Result<> makeArrayGet(HeapType type, bool signed_);
232-
Result<> makeArraySet(HeapType type);
231+
Result<> makeArrayGet(HeapType type, bool signed_, MemoryOrder order);
232+
Result<> makeArraySet(HeapType type, MemoryOrder order);
233233
Result<> makeArrayLen();
234234
Result<> makeArrayCopy(HeapType destType, HeapType srcType);
235235
Result<> makeArrayFill(HeapType type);

src/wasm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,6 +1778,7 @@ class ArrayGet : public SpecificExpression<Expression::ArrayGetId> {
17781778
Expression* index;
17791779
// Packed fields have a sign.
17801780
bool signed_ = false;
1781+
MemoryOrder order = MemoryOrder::Unordered;
17811782

17821783
void finalize();
17831784
};
@@ -1790,6 +1791,7 @@ class ArraySet : public SpecificExpression<Expression::ArraySetId> {
17901791
Expression* ref;
17911792
Expression* index;
17921793
Expression* value;
1794+
MemoryOrder order = MemoryOrder::Unordered;
17931795

17941796
void finalize();
17951797
};

0 commit comments

Comments
 (0)