summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
authorAshley Nelson <nashley@google.com>2024-02-27 17:09:30 -0800
committerGitHub <noreply@github.com>2024-02-27 17:09:30 -0800
commit1ef95ae7b9e2c765abbbc6af6dff6c29c1fa4d13 (patch)
tree06a51c0fc5d395260a728362373e346bdbf5cc25 /src/wasm
parentc62a0c97168e88f97bca4bd96298a5ffc041844d (diff)
downloadbinaryen-1ef95ae7b9e2c765abbbc6af6dff6c29c1fa4d13.tar.gz
binaryen-1ef95ae7b9e2c765abbbc6af6dff6c29c1fa4d13.tar.bz2
binaryen-1ef95ae7b9e2c765abbbc6af6dff6c29c1fa4d13.zip
[Outlining] Fixes break reconstruction (#6352)
Adds new visitBreakWithType and visitSwitchWithType functions to the IRBuilder API. These functions work around an assumption in IRBuilder that the module is being traversed in the fully nested format, i.e., that the destination scope of a break or switch has been visited before visiting the break or switch. Instead, the type of the destination scope is passed to IRBuilder.
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-ir-builder.cpp46
1 files changed, 43 insertions, 3 deletions
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp
index b1bf8c855..8d87d0f33 100644
--- a/src/wasm/wasm-ir-builder.cpp
+++ b/src/wasm/wasm-ir-builder.cpp
@@ -419,8 +419,14 @@ Result<> IRBuilder::visitArrayNewFixed(ArrayNewFixed* curr) {
return Ok{};
}
-Result<Expression*> IRBuilder::getBranchValue(Name labelName,
+Result<Expression*> IRBuilder::getBranchValue(Expression* curr,
+ Name labelName,
std::optional<Index> label) {
+ // As new branch instructions are added, one of the existing branch visit*
+ // functions is likely to be copied, along with its call to getBranchValue().
+ // This assert serves as a reminder to also add an implementation of
+ // visit*WithType() for new branch instructions.
+ assert(curr->is<Break>() || curr->is<Switch>());
if (!label) {
auto index = getLabelIndex(labelName);
CHECK_ERR(index);
@@ -440,23 +446,57 @@ Result<> IRBuilder::visitBreak(Break* curr, std::optional<Index> label) {
CHECK_ERR(cond);
curr->condition = *cond;
}
- auto value = getBranchValue(curr->name, label);
+ auto value = getBranchValue(curr, curr->name, label);
CHECK_ERR(value);
curr->value = *value;
return Ok{};
}
+Result<> IRBuilder::visitBreakWithType(Break* curr, Type type) {
+ if (curr->condition) {
+ auto cond = pop();
+ CHECK_ERR(cond);
+ curr->condition = *cond;
+ }
+ if (type == Type::none) {
+ curr->value = nullptr;
+ } else {
+ auto value = pop(type.size());
+ CHECK_ERR(value)
+ curr->value = *value;
+ }
+ curr->finalize();
+ push(curr);
+ return Ok{};
+}
+
Result<> IRBuilder::visitSwitch(Switch* curr,
std::optional<Index> defaultLabel) {
auto cond = pop();
CHECK_ERR(cond);
curr->condition = *cond;
- auto value = getBranchValue(curr->default_, defaultLabel);
+ auto value = getBranchValue(curr, curr->default_, defaultLabel);
CHECK_ERR(value);
curr->value = *value;
return Ok{};
}
+Result<> IRBuilder::visitSwitchWithType(Switch* curr, Type type) {
+ auto cond = pop();
+ CHECK_ERR(cond);
+ curr->condition = *cond;
+ if (type == Type::none) {
+ curr->value = nullptr;
+ } else {
+ auto value = pop(type.size());
+ CHECK_ERR(value)
+ curr->value = *value;
+ }
+ curr->finalize();
+ push(curr);
+ return Ok{};
+}
+
Result<> IRBuilder::visitCall(Call* curr) {
auto numArgs = wasm.getFunction(curr->target)->getNumParams();
curr->operands.resize(numArgs);