Skip to content

Commit fd2a006

Browse files
committed
Prototype prefetch instructions
As proposed in WebAssembly/simd#352, using the opcodes used in the LLVM and V8 implementations.
1 parent b79661e commit fd2a006

21 files changed

+194
-3
lines changed

scripts/gen-s-parser.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,9 @@
516516
("i16x8.extadd_pairwise_i8x16_u", "makeUnary(s, UnaryOp::ExtAddPairwiseUVecI8x16ToI16x8)"),
517517
("i32x4.extadd_pairwise_i16x8_s", "makeUnary(s, UnaryOp::ExtAddPairwiseSVecI16x8ToI32x4)"),
518518
("i32x4.extadd_pairwise_i16x8_u", "makeUnary(s, UnaryOp::ExtAddPairwiseUVecI16x8ToI32x4)"),
519+
# prefetch instructions
520+
("prefetch.t", "makePrefetch(s, PrefetchOp::PrefetchTemporal)"),
521+
("prefetch.nt", "makePrefetch(s, PrefetchOp::PrefetchNontemporal)"),
519522
# reference types instructions
520523
# TODO Add table instructions
521524
("ref.null", "makeRefNull(s)"),

src/gen-s-parser.inc

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2759,9 +2759,25 @@ switch (op[0]) {
27592759
case 'n':
27602760
if (strcmp(op, "nop") == 0) { return makeNop(); }
27612761
goto parse_error;
2762-
case 'p':
2763-
if (strcmp(op, "pop") == 0) { return makePop(s); }
2764-
goto parse_error;
2762+
case 'p': {
2763+
switch (op[1]) {
2764+
case 'o':
2765+
if (strcmp(op, "pop") == 0) { return makePop(s); }
2766+
goto parse_error;
2767+
case 'r': {
2768+
switch (op[9]) {
2769+
case 'n':
2770+
if (strcmp(op, "prefetch.nt") == 0) { return makePrefetch(s, PrefetchOp::PrefetchNontemporal); }
2771+
goto parse_error;
2772+
case 't':
2773+
if (strcmp(op, "prefetch.t") == 0) { return makePrefetch(s, PrefetchOp::PrefetchTemporal); }
2774+
goto parse_error;
2775+
default: goto parse_error;
2776+
}
2777+
}
2778+
default: goto parse_error;
2779+
}
2780+
}
27652781
case 'r': {
27662782
switch (op[1]) {
27672783
case 'e': {

src/ir/ReFinalize.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ void ReFinalize::visitSIMDLoad(SIMDLoad* curr) { curr->finalize(); }
112112
void ReFinalize::visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
113113
curr->finalize();
114114
}
115+
void ReFinalize::visitPrefetch(Prefetch* curr) { curr->finalize(); }
115116
void ReFinalize::visitMemoryInit(MemoryInit* curr) { curr->finalize(); }
116117
void ReFinalize::visitDataDrop(DataDrop* curr) { curr->finalize(); }
117118
void ReFinalize::visitMemoryCopy(MemoryCopy* curr) { curr->finalize(); }

src/ir/cost.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> {
537537
Index visitSIMDShuffle(SIMDShuffle* curr) {
538538
return 1 + visit(curr->left) + visit(curr->right);
539539
}
540+
Index visitPrefetch(Prefetch* curr) { return 1 + visit(curr->ptr); }
540541
Index visitRefNull(RefNull* curr) { return 1; }
541542
Index visitRefIsNull(RefIsNull* curr) { return 1 + visit(curr->value); }
542543
Index visitRefFunc(RefFunc* curr) { return 1; }

src/ir/effects.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,11 @@ class EffectAnalyzer {
415415
}
416416
parent.implicitTrap = true;
417417
}
418+
void visitPrefetch(Prefetch* curr) {
419+
// Do not reorder with respect to other memory ops
420+
parent.writesMemory = true;
421+
parent.readsMemory = true;
422+
}
418423
void visitMemoryInit(MemoryInit* curr) {
419424
parent.writesMemory = true;
420425
parent.implicitTrap = true;

src/passes/Print.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,24 @@ struct PrintExpressionContents
683683
}
684684
o << " " << int(curr->index);
685685
}
686+
void visitPrefetch(Prefetch* curr) {
687+
prepareColor(o);
688+
switch (curr->op) {
689+
case PrefetchTemporal:
690+
o << "prefetch.t";
691+
break;
692+
case PrefetchNontemporal:
693+
o << "prefetch.nt";
694+
break;
695+
}
696+
restoreNormalColor(o);
697+
if (curr->offset) {
698+
o << " offset=" << curr->offset;
699+
}
700+
if (curr->align != 1) {
701+
o << " align=" << curr->align;
702+
}
703+
}
686704
void visitMemoryInit(MemoryInit* curr) {
687705
prepareColor(o);
688706
o << "memory.init " << curr->segment;
@@ -2212,6 +2230,13 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> {
22122230
printFullLine(curr->vec);
22132231
decIndent();
22142232
}
2233+
void visitPrefetch(Prefetch* curr) {
2234+
o << '(';
2235+
PrintExpressionContents(currFunction, o).visit(curr);
2236+
incIndent();
2237+
printFullLine(curr->ptr);
2238+
decIndent();
2239+
}
22152240
void visitMemoryInit(MemoryInit* curr) {
22162241
o << '(';
22172242
PrintExpressionContents(currFunction, o).visit(curr);

src/wasm-binary.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,11 @@ enum ASTNodes {
973973
I64x2ExtMulLowUI32x4 = 0xd6,
974974
I64x2ExtMulHighUI32x4 = 0xd7,
975975

976+
// prefetch opcodes
977+
978+
PrefetchT = 0xc5,
979+
PrefetchNT = 0xc6,
980+
976981
// bulk memory opcodes
977982

978983
MemoryInit = 0x08,
@@ -1481,6 +1486,7 @@ class WasmBinaryBuilder {
14811486
bool maybeVisitSIMDShift(Expression*& out, uint32_t code);
14821487
bool maybeVisitSIMDLoad(Expression*& out, uint32_t code);
14831488
bool maybeVisitSIMDLoadStoreLane(Expression*& out, uint32_t code);
1489+
bool maybeVisitPrefetch(Expression*& out, uint32_t code);
14841490
bool maybeVisitMemoryInit(Expression*& out, uint32_t code);
14851491
bool maybeVisitDataDrop(Expression*& out, uint32_t code);
14861492
bool maybeVisitMemoryCopy(Expression*& out, uint32_t code);

src/wasm-delegations-fields.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,15 @@ switch (DELEGATE_ID) {
371371
DELEGATE_END(SIMDLoadStoreLane);
372372
break;
373373
}
374+
case Expression::Id::PrefetchId: {
375+
DELEGATE_START(Prefetch);
376+
DELEGATE_FIELD_CHILD(Prefetch, ptr);
377+
DELEGATE_FIELD_INT(Prefetch, op);
378+
DELEGATE_FIELD_ADDRESS(Prefetch, offset);
379+
DELEGATE_FIELD_ADDRESS(Prefetch, align);
380+
DELEGATE_END(Prefetch);
381+
break;
382+
}
374383
case Expression::Id::MemoryInitId: {
375384
DELEGATE_START(MemoryInit);
376385
DELEGATE_FIELD_CHILD(MemoryInit, size);

src/wasm-delegations.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ DELEGATE(SIMDTernary);
4040
DELEGATE(SIMDShift);
4141
DELEGATE(SIMDLoad);
4242
DELEGATE(SIMDLoadStoreLane);
43+
DELEGATE(Prefetch);
4344
DELEGATE(MemoryInit);
4445
DELEGATE(DataDrop);
4546
DELEGATE(MemoryCopy);

src/wasm-interpreter.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,14 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
11671167
NOTE_ENTER("Nop");
11681168
return Flow();
11691169
}
1170+
Flow visitPrefetch(Prefetch* curr) {
1171+
NOTE_ENTER("Prefetch");
1172+
Flow flow = visit(curr->ptr);
1173+
if (flow.breaking()) {
1174+
return flow;
1175+
}
1176+
return Flow();
1177+
}
11701178
Flow visitUnreachable(Unreachable* curr) {
11711179
NOTE_ENTER("Unreachable");
11721180
trap("unreachable");

0 commit comments

Comments
 (0)