summaryrefslogtreecommitdiff
path: root/src/passes/MergeBlocks.cpp
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2020-05-13 17:10:59 -0700
committerGitHub <noreply@github.com>2020-05-13 17:10:59 -0700
commit5db77a72a7c62d045e6650e96974fe1455fa1a1a (patch)
treed4b32705b0c6090d6763063025fc503ba650c8cf /src/passes/MergeBlocks.cpp
parent5930ada5bee7061d8063f2638cdb1cb25dce5292 (diff)
downloadbinaryen-5db77a72a7c62d045e6650e96974fe1455fa1a1a.tar.gz
binaryen-5db77a72a7c62d045e6650e96974fe1455fa1a1a.tar.bz2
binaryen-5db77a72a7c62d045e6650e96974fe1455fa1a1a.zip
Add EH support in MergeBlocks (#2848)
This adds support for `throw`, `rethrow`, and `br_on_exn` in MergeBlocks. While unrelated instructions within blocks can be hoisted as in other instructions, `br_on_exn` requires a special handling in `ProblemFinder`, because unlike `br_if`, its `exnref` argument itself cannot be moved out of `br_on_exn`.
Diffstat (limited to 'src/passes/MergeBlocks.cpp')
-rw-r--r--src/passes/MergeBlocks.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp
index ab368429f..1401cd2f4 100644
--- a/src/passes/MergeBlocks.cpp
+++ b/src/passes/MergeBlocks.cpp
@@ -129,6 +129,11 @@ struct ProblemFinder : public ControlFlowWalker<ProblemFinder> {
}
}
+ void visitBrOnExn(BrOnExn* curr) {
+ // We should not take exnref value out of br_on_exn
+ foundProblem = true;
+ }
+
bool found() {
assert(brIfs >= droppedBrIfs);
return foundProblem || brIfs > droppedBrIfs;
@@ -526,6 +531,7 @@ struct MergeBlocks : public WalkerPass<PostWalker<MergeBlocks>> {
void visitBreak(Break* curr) {
optimize(curr, curr->condition, optimize(curr, curr->value), &curr->value);
}
+
void visitSwitch(Switch* curr) {
optimize(curr, curr->condition, optimize(curr, curr->value), &curr->value);
}
@@ -540,7 +546,6 @@ struct MergeBlocks : public WalkerPass<PostWalker<MergeBlocks>> {
}
outer = optimize(curr, curr->operands[i], outer);
}
- return;
}
void visitCall(Call* curr) { handleCall(curr); }
@@ -561,6 +566,22 @@ struct MergeBlocks : public WalkerPass<PostWalker<MergeBlocks>> {
}
optimize(curr, curr->target, outer);
}
+
+ void visitThrow(Throw* curr) {
+ Block* outer = nullptr;
+ for (Index i = 0; i < curr->operands.size(); i++) {
+ if (EffectAnalyzer(
+ getPassOptions(), getModule()->features, curr->operands[i])
+ .hasSideEffects()) {
+ return;
+ }
+ outer = optimize(curr, curr->operands[i], outer);
+ }
+ }
+
+ void visitRethrow(Rethrow* curr) { optimize(curr, curr->exnref); }
+
+ void visitBrOnExn(BrOnExn* curr) { optimize(curr, curr->exnref); }
};
Pass* createMergeBlocksPass() { return new MergeBlocks(); }