Skip to content

QFMA/QFMS instructions #2328

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ Current Trunk
- `i32.wait` / `i64.wait` -> `i32.atomic.wait` / `i64.atomic.wait`
- Binaryen.js: `flags` argument in `setMemory` function is removed.
- `atomic.fence` instruction support is added.
- wasm-emscripten-finalize: Don't realy on name section being present in the
- wasm-emscripten-finalize: Don't rely on name section being present in the
input. Use the exported names for things instead.
- Added `mutable` parameter to BinaryenAddGlobalImport.
- Replace BinaryenSIMDBitselect* with BinaryenSIMDTernary* in the C API and add
qfma/qfms instructions.

v88
---
Expand Down
19 changes: 13 additions & 6 deletions build-js.sh
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ export_function "_BinaryenAtomicFenceId"
export_function "_BinaryenSIMDExtractId"
export_function "_BinaryenSIMDReplaceId"
export_function "_BinaryenSIMDShuffleId"
export_function "_BinaryenSIMDBitselectId"
export_function "_BinaryenSIMDTernaryId"
export_function "_BinaryenSIMDShiftId"
export_function "_BinaryenMemoryInitId"
export_function "_BinaryenDataDropId"
Expand Down Expand Up @@ -522,6 +522,10 @@ export_function "_BinaryenSubVecI64x2"
export_function "_BinaryenAbsVecF32x4"
export_function "_BinaryenNegVecF32x4"
export_function "_BinaryenSqrtVecF32x4"
export_function "_BinaryenQFMAVecF32x4"
export_function "_BinaryenQFMSVecF32x4"
export_function "_BinaryenQFMAVecF32x4"
export_function "_BinaryenQFMSVecF32x4"
export_function "_BinaryenAddVecF32x4"
export_function "_BinaryenSubVecF32x4"
export_function "_BinaryenMulVecF32x4"
Expand All @@ -531,6 +535,8 @@ export_function "_BinaryenMaxVecF32x4"
export_function "_BinaryenAbsVecF64x2"
export_function "_BinaryenNegVecF64x2"
export_function "_BinaryenSqrtVecF64x2"
export_function "_BinaryenQFMAVecF64x2"
export_function "_BinaryenQFMSVecF64x2"
export_function "_BinaryenAddVecF64x2"
export_function "_BinaryenSubVecF64x2"
export_function "_BinaryenMulVecF64x2"
Expand Down Expand Up @@ -582,7 +588,7 @@ export_function "_BinaryenAtomicFence"
export_function "_BinaryenSIMDExtract"
export_function "_BinaryenSIMDReplace"
export_function "_BinaryenSIMDShuffle"
export_function "_BinaryenSIMDBitselect"
export_function "_BinaryenSIMDTernary"
export_function "_BinaryenSIMDShift"
export_function "_BinaryenMemoryInit"
export_function "_BinaryenDataDrop"
Expand Down Expand Up @@ -744,10 +750,11 @@ export_function "_BinaryenSIMDShuffleGetLeft"
export_function "_BinaryenSIMDShuffleGetRight"
export_function "_BinaryenSIMDShuffleGetMask"

# 'SIMDBitselect' expression operations
export_function "_BinaryenSIMDBitselectGetLeft"
export_function "_BinaryenSIMDBitselectGetRight"
export_function "_BinaryenSIMDBitselectGetCond"
# 'SIMDTernary' expression operations
export_function "_BinaryenSIMDTernaryGetOp"
export_function "_BinaryenSIMDTernaryGetA"
export_function "_BinaryenSIMDTernaryGetB"
export_function "_BinaryenSIMDTernaryGetC"

# 'SIMDShift' expression operations
export_function "_BinaryenSIMDShiftGetOp"
Expand Down
6 changes: 5 additions & 1 deletion scripts/gen-s-parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@
("v128.and", "makeBinary(s, BinaryOp::AndVec128)"),
("v128.or", "makeBinary(s, BinaryOp::OrVec128)"),
("v128.xor", "makeBinary(s, BinaryOp::XorVec128)"),
("v128.bitselect", "makeSIMDBitselect(s)"),
("v128.bitselect", "makeSIMDTernary(s, SIMDTernaryOp::Bitselect)"),
("i8x16.neg", "makeUnary(s, UnaryOp::NegVecI8x16)"),
("i8x16.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI8x16)"),
("i8x16.all_true", "makeUnary(s, UnaryOp::AllTrueVecI8x16)"),
Expand Down Expand Up @@ -402,6 +402,8 @@
("f32x4.abs", "makeUnary(s, UnaryOp::AbsVecF32x4)"),
("f32x4.neg", "makeUnary(s, UnaryOp::NegVecF32x4)"),
("f32x4.sqrt", "makeUnary(s, UnaryOp::SqrtVecF32x4)"),
("f32x4.qfma", "makeSIMDTernary(s, SIMDTernaryOp::QFMAF32x4)"),
("f32x4.qfms", "makeSIMDTernary(s, SIMDTernaryOp::QFMSF32x4)"),
("f32x4.add", "makeBinary(s, BinaryOp::AddVecF32x4)"),
("f32x4.sub", "makeBinary(s, BinaryOp::SubVecF32x4)"),
("f32x4.mul", "makeBinary(s, BinaryOp::MulVecF32x4)"),
Expand All @@ -411,6 +413,8 @@
("f64x2.abs", "makeUnary(s, UnaryOp::AbsVecF64x2)"),
("f64x2.neg", "makeUnary(s, UnaryOp::NegVecF64x2)"),
("f64x2.sqrt", "makeUnary(s, UnaryOp::SqrtVecF64x2)"),
("f64x2.qfma", "makeSIMDTernary(s, SIMDTernaryOp::QFMAF64x2)"),
("f64x2.qfms", "makeSIMDTernary(s, SIMDTernaryOp::QFMSF64x2)"),
("f64x2.add", "makeBinary(s, BinaryOp::AddVecF64x2)"),
("f64x2.sub", "makeBinary(s, BinaryOp::SubVecF64x2)"),
("f64x2.mul", "makeBinary(s, BinaryOp::MulVecF64x2)"),
Expand Down
70 changes: 43 additions & 27 deletions src/binaryen-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,8 @@ BinaryenExpressionId BinaryenSIMDReplaceId(void) {
BinaryenExpressionId BinaryenSIMDShuffleId(void) {
return Expression::Id::SIMDShuffleId;
}
BinaryenExpressionId BinaryenSIMDBitselectId(void) {
return Expression::Id::SIMDBitselectId;
BinaryenExpressionId BinaryenSIMDTernaryId(void) {
return Expression::Id::SIMDTernaryId;
}
BinaryenExpressionId BinaryenSIMDShiftId(void) {
return Expression::Id::SIMDShiftId;
Expand Down Expand Up @@ -790,6 +790,7 @@ BinaryenOp BinaryenNotVec128(void) { return NotVec128; }
BinaryenOp BinaryenAndVec128(void) { return AndVec128; }
BinaryenOp BinaryenOrVec128(void) { return OrVec128; }
BinaryenOp BinaryenXorVec128(void) { return XorVec128; }
BinaryenOp BinaryenBitselectVec128(void) { return Bitselect; }
BinaryenOp BinaryenNegVecI8x16(void) { return NegVecI8x16; }
BinaryenOp BinaryenAnyTrueVecI8x16(void) { return AnyTrueVecI8x16; }
BinaryenOp BinaryenAllTrueVecI8x16(void) { return AllTrueVecI8x16; }
Expand Down Expand Up @@ -836,6 +837,8 @@ BinaryenOp BinaryenSubVecI64x2(void) { return SubVecI64x2; }
BinaryenOp BinaryenAbsVecF32x4(void) { return AbsVecF32x4; }
BinaryenOp BinaryenNegVecF32x4(void) { return NegVecF32x4; }
BinaryenOp BinaryenSqrtVecF32x4(void) { return SqrtVecF32x4; }
BinaryenOp BinaryenQFMAVecF32x4(void) { return QFMAF32x4; }
BinaryenOp BinaryenQFMSVecF32x4(void) { return QFMSF32x4; }
BinaryenOp BinaryenAddVecF32x4(void) { return AddVecF32x4; }
BinaryenOp BinaryenSubVecF32x4(void) { return SubVecF32x4; }
BinaryenOp BinaryenMulVecF32x4(void) { return MulVecF32x4; }
Expand All @@ -845,6 +848,8 @@ BinaryenOp BinaryenMaxVecF32x4(void) { return MaxVecF32x4; }
BinaryenOp BinaryenAbsVecF64x2(void) { return AbsVecF64x2; }
BinaryenOp BinaryenNegVecF64x2(void) { return NegVecF64x2; }
BinaryenOp BinaryenSqrtVecF64x2(void) { return SqrtVecF64x2; }
BinaryenOp BinaryenQFMAVecF64x2(void) { return QFMAF64x2; }
BinaryenOp BinaryenQFMSVecF64x2(void) { return QFMSF64x2; }
BinaryenOp BinaryenAddVecF64x2(void) { return AddVecF64x2; }
BinaryenOp BinaryenSubVecF64x2(void) { return SubVecF64x2; }
BinaryenOp BinaryenMulVecF64x2(void) { return MulVecF64x2; }
Expand Down Expand Up @@ -1532,15 +1537,17 @@ BinaryenExpressionRef BinaryenSIMDShuffle(BinaryenModuleRef module,
}
return static_cast<Expression*>(ret);
}
BinaryenExpressionRef BinaryenSIMDBitselect(BinaryenModuleRef module,
BinaryenExpressionRef left,
BinaryenExpressionRef right,
BinaryenExpressionRef cond) {
auto* ret = Builder(*(Module*)module)
.makeSIMDBitselect(
(Expression*)left, (Expression*)right, (Expression*)cond);
BinaryenExpressionRef BinaryenSIMDTernary(BinaryenModuleRef module,
BinaryenOp op,
BinaryenExpressionRef a,
BinaryenExpressionRef b,
BinaryenExpressionRef c) {
auto* ret =
Builder(*(Module*)module)
.makeSIMDTernary(
SIMDTernaryOp(op), (Expression*)a, (Expression*)b, (Expression*)c);
if (tracing) {
traceExpression(ret, "BinaryenSIMDBitselect", left, right, cond);
traceExpression(ret, "BinaryenSIMDTernary", op, a, b, c);
}
return static_cast<Expression*>(ret);
}
Expand Down Expand Up @@ -2652,37 +2659,46 @@ void BinaryenSIMDShuffleGetMask(BinaryenExpressionRef expr, uint8_t* mask) {
assert(expression->is<SIMDShuffle>());
memcpy(mask, static_cast<SIMDShuffle*>(expression)->mask.data(), 16);
}
// SIMDBitselect
BinaryenExpressionRef BinaryenSIMDBitselectGetLeft(BinaryenExpressionRef expr) {
// SIMDTernary
BinaryenOp BinaryenSIMDTernaryGetOp(BinaryenExpressionRef expr) {
if (tracing) {
std::cout << " BinaryenSIMDBitselectGetLeft(expressions["
<< expressions[expr] << "]);\n";
std::cout << " BinaryenSIMDTernaryOp(expressions[" << expressions[expr]
<< "]);\n";
}

auto* expression = (Expression*)expr;
assert(expression->is<SIMDBitselect>());
return static_cast<SIMDBitselect*>(expression)->left;
assert(expression->is<SIMDTernary>());
return static_cast<SIMDTernary*>(expression)->op;
}
BinaryenExpressionRef
BinaryenSIMDBitselectGetRight(BinaryenExpressionRef expr) {
BinaryenExpressionRef BinaryenSIMDTernaryGetA(BinaryenExpressionRef expr) {
if (tracing) {
std::cout << " BinaryenSIMDBitselectGetRight(expressions["
<< expressions[expr] << "]);\n";
std::cout << " BinaryenSIMDTernaryGetA(expressions[" << expressions[expr]
<< "]);\n";
}

auto* expression = (Expression*)expr;
assert(expression->is<SIMDBitselect>());
return static_cast<SIMDBitselect*>(expression)->right;
assert(expression->is<SIMDTernary>());
return static_cast<SIMDTernary*>(expression)->a;
}
BinaryenExpressionRef BinaryenSIMDBitselectGetCond(BinaryenExpressionRef expr) {
BinaryenExpressionRef BinaryenSIMDTernaryGetB(BinaryenExpressionRef expr) {
if (tracing) {
std::cout << " BinaryenSIMDBitselectGetCond(expressions["
<< expressions[expr] << "]);\n";
std::cout << " BinaryenSIMDTernaryGetB(expressions[" << expressions[expr]
<< "]);\n";
}

auto* expression = (Expression*)expr;
assert(expression->is<SIMDTernary>());
return static_cast<SIMDTernary*>(expression)->b;
}
BinaryenExpressionRef BinaryenSIMDTernaryGetC(BinaryenExpressionRef expr) {
if (tracing) {
std::cout << " BinaryenSIMDTernaryGetC(expressions[" << expressions[expr]
<< "]);\n";
}

auto* expression = (Expression*)expr;
assert(expression->is<SIMDBitselect>());
return static_cast<SIMDBitselect*>(expression)->cond;
assert(expression->is<SIMDTernary>());
return static_cast<SIMDTernary*>(expression)->c;
}
// SIMDShift
BinaryenOp BinaryenSIMDShiftGetOp(BinaryenExpressionRef expr) {
Expand Down
22 changes: 14 additions & 8 deletions src/binaryen-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ BinaryenExpressionId BinaryenAtomicFenceId(void);
BinaryenExpressionId BinaryenSIMDExtractId(void);
BinaryenExpressionId BinaryenSIMDReplaceId(void);
BinaryenExpressionId BinaryenSIMDShuffleId(void);
BinaryenExpressionId BinaryenSIMDBitselectId(void);
BinaryenExpressionId BinaryenSIMDTernaryId(void);
BinaryenExpressionId BinaryenSIMDShiftId(void);
BinaryenExpressionId BinaryenMemoryInitId(void);
BinaryenExpressionId BinaryenDataDropId(void);
Expand Down Expand Up @@ -486,6 +486,8 @@ BinaryenOp BinaryenSubVecI64x2(void);
BinaryenOp BinaryenAbsVecF32x4(void);
BinaryenOp BinaryenNegVecF32x4(void);
BinaryenOp BinaryenSqrtVecF32x4(void);
BinaryenOp BinaryenQFMAVecF32x4(void);
BinaryenOp BinaryenQFMSVecF32x4(void);
BinaryenOp BinaryenAddVecF32x4(void);
BinaryenOp BinaryenSubVecF32x4(void);
BinaryenOp BinaryenMulVecF32x4(void);
Expand All @@ -495,6 +497,8 @@ BinaryenOp BinaryenMaxVecF32x4(void);
BinaryenOp BinaryenAbsVecF64x2(void);
BinaryenOp BinaryenNegVecF64x2(void);
BinaryenOp BinaryenSqrtVecF64x2(void);
BinaryenOp BinaryenQFMAVecF64x2(void);
BinaryenOp BinaryenQFMSVecF64x2(void);
BinaryenOp BinaryenAddVecF64x2(void);
BinaryenOp BinaryenSubVecF64x2(void);
BinaryenOp BinaryenMulVecF64x2(void);
Expand Down Expand Up @@ -687,10 +691,11 @@ BinaryenExpressionRef BinaryenSIMDShuffle(BinaryenModuleRef module,
BinaryenExpressionRef left,
BinaryenExpressionRef right,
const uint8_t mask[16]);
BinaryenExpressionRef BinaryenSIMDBitselect(BinaryenModuleRef module,
BinaryenExpressionRef left,
BinaryenExpressionRef right,
BinaryenExpressionRef cond);
BinaryenExpressionRef BinaryenSIMDTernary(BinaryenModuleRef module,
BinaryenOp op,
BinaryenExpressionRef a,
BinaryenExpressionRef b,
BinaryenExpressionRef c);
BinaryenExpressionRef BinaryenSIMDShift(BinaryenModuleRef module,
BinaryenOp op,
BinaryenExpressionRef vec,
Expand Down Expand Up @@ -856,9 +861,10 @@ BinaryenExpressionRef BinaryenSIMDShuffleGetLeft(BinaryenExpressionRef expr);
BinaryenExpressionRef BinaryenSIMDShuffleGetRight(BinaryenExpressionRef expr);
void BinaryenSIMDShuffleGetMask(BinaryenExpressionRef expr, uint8_t* mask);

BinaryenExpressionRef BinaryenSIMDBitselectGetLeft(BinaryenExpressionRef expr);
BinaryenExpressionRef BinaryenSIMDBitselectGetRight(BinaryenExpressionRef expr);
BinaryenExpressionRef BinaryenSIMDBitselectGetCond(BinaryenExpressionRef expr);
BinaryenOp BinaryenSIMDTernaryGetOp(BinaryenExpressionRef expr);
BinaryenExpressionRef BinaryenSIMDTernaryGetA(BinaryenExpressionRef expr);
BinaryenExpressionRef BinaryenSIMDTernaryGetB(BinaryenExpressionRef expr);
BinaryenExpressionRef BinaryenSIMDTernaryGetC(BinaryenExpressionRef expr);

BinaryenOp BinaryenSIMDShiftGetOp(BinaryenExpressionRef expr);
BinaryenExpressionRef BinaryenSIMDShiftGetVec(BinaryenExpressionRef expr);
Expand Down
24 changes: 23 additions & 1 deletion src/gen-s-parser.inc
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,17 @@ switch (op[0]) {
default: goto parse_error;
}
}
case 'q': {
switch (op[9]) {
case 'a':
if (strcmp(op, "f32x4.qfma") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::QFMAF32x4); }
goto parse_error;
case 's':
if (strcmp(op, "f32x4.qfms") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::QFMSF32x4); }
goto parse_error;
default: goto parse_error;
}
}
case 'r':
if (strcmp(op, "f32x4.replace_lane") == 0) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecF32x4, 4); }
goto parse_error;
Expand Down Expand Up @@ -608,6 +619,17 @@ switch (op[0]) {
default: goto parse_error;
}
}
case 'q': {
switch (op[9]) {
case 'a':
if (strcmp(op, "f64x2.qfma") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::QFMAF64x2); }
goto parse_error;
case 's':
if (strcmp(op, "f64x2.qfms") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::QFMSF64x2); }
goto parse_error;
default: goto parse_error;
}
}
case 'r':
if (strcmp(op, "f64x2.replace_lane") == 0) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecF64x2, 2); }
goto parse_error;
Expand Down Expand Up @@ -2315,7 +2337,7 @@ switch (op[0]) {
if (strcmp(op, "v128.and") == 0) { return makeBinary(s, BinaryOp::AndVec128); }
goto parse_error;
case 'b':
if (strcmp(op, "v128.bitselect") == 0) { return makeSIMDBitselect(s); }
if (strcmp(op, "v128.bitselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::Bitselect); }
goto parse_error;
case 'c':
if (strcmp(op, "v128.const") == 0) { return makeConst(s, v128); }
Expand Down
2 changes: 1 addition & 1 deletion src/ir/ExpressionAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ template<typename T> void visitImmediates(Expression* curr, T& visitor) {
visitor.visitInt(x);
}
}
void visitSIMDBitselect(SIMDBitselect* curr) {}
void visitSIMDTernary(SIMDTernary* curr) { visitor.visitInt(curr->op); }
void visitSIMDShift(SIMDShift* curr) { visitor.visitInt(curr->op); }
void visitMemoryInit(MemoryInit* curr) {
visitor.visitIndex(curr->segment);
Expand Down
6 changes: 3 additions & 3 deletions src/ir/ExpressionManipulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@ flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) {
return builder.makeSIMDShuffle(
copy(curr->left), copy(curr->right), curr->mask);
}
Expression* visitSIMDBitselect(SIMDBitselect* curr) {
return builder.makeSIMDBitselect(
copy(curr->left), copy(curr->right), copy(curr->cond));
Expression* visitSIMDTernary(SIMDTernary* curr) {
return builder.makeSIMDTernary(
curr->op, copy(curr->a), copy(curr->b), copy(curr->c));
}
Expression* visitSIMDShift(SIMDShift* curr) {
return builder.makeSIMDShift(
Expand Down
2 changes: 1 addition & 1 deletion src/ir/ReFinalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ void ReFinalize::visitAtomicFence(AtomicFence* curr) { curr->finalize(); }
void ReFinalize::visitSIMDExtract(SIMDExtract* curr) { curr->finalize(); }
void ReFinalize::visitSIMDReplace(SIMDReplace* curr) { curr->finalize(); }
void ReFinalize::visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); }
void ReFinalize::visitSIMDBitselect(SIMDBitselect* curr) { curr->finalize(); }
void ReFinalize::visitSIMDTernary(SIMDTernary* curr) { curr->finalize(); }
void ReFinalize::visitSIMDShift(SIMDShift* curr) { curr->finalize(); }
void ReFinalize::visitMemoryInit(MemoryInit* curr) { curr->finalize(); }
void ReFinalize::visitDataDrop(DataDrop* curr) { curr->finalize(); }
Expand Down
2 changes: 1 addition & 1 deletion src/ir/effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ struct EffectAnalyzer
void visitSIMDExtract(SIMDExtract* curr) {}
void visitSIMDReplace(SIMDReplace* curr) {}
void visitSIMDShuffle(SIMDShuffle* curr) {}
void visitSIMDBitselect(SIMDBitselect* curr) {}
void visitSIMDTernary(SIMDTernary* curr) {}
void visitSIMDShift(SIMDShift* curr) {}
void visitMemoryInit(MemoryInit* curr) {
writesMemory = true;
Expand Down
4 changes: 2 additions & 2 deletions src/ir/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ struct ReFinalize
void visitSIMDExtract(SIMDExtract* curr);
void visitSIMDReplace(SIMDReplace* curr);
void visitSIMDShuffle(SIMDShuffle* curr);
void visitSIMDBitselect(SIMDBitselect* curr);
void visitSIMDTernary(SIMDTernary* curr);
void visitSIMDShift(SIMDShift* curr);
void visitMemoryInit(MemoryInit* curr);
void visitDataDrop(DataDrop* curr);
Expand Down Expand Up @@ -196,7 +196,7 @@ struct ReFinalizeNode : public OverriddenVisitor<ReFinalizeNode> {
void visitSIMDExtract(SIMDExtract* curr) { curr->finalize(); }
void visitSIMDReplace(SIMDReplace* curr) { curr->finalize(); }
void visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); }
void visitSIMDBitselect(SIMDBitselect* curr) { curr->finalize(); }
void visitSIMDTernary(SIMDTernary* curr) { curr->finalize(); }
void visitSIMDShift(SIMDShift* curr) { curr->finalize(); }
void visitMemoryInit(MemoryInit* curr) { curr->finalize(); }
void visitDataDrop(DataDrop* curr) { curr->finalize(); }
Expand Down
Loading