summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-03-18 15:10:11 -0700
committerGitHub <noreply@github.com>2021-03-18 15:10:11 -0700
commite5aaa07844687493e0155dacb6b79bf856a4dd81 (patch)
tree53ebe40500b65a3b5e698400a6a63d6fc3548c02 /src
parent647ef50fc4de9b5c49ffad1aec4271e79b171785 (diff)
downloadbinaryen-e5aaa07844687493e0155dacb6b79bf856a4dd81.tar.gz
binaryen-e5aaa07844687493e0155dacb6b79bf856a4dd81.tar.bz2
binaryen-e5aaa07844687493e0155dacb6b79bf856a4dd81.zip
[Wasm GC] Fix MergeBlocks on BrOn (#3702)
The pass was only aware of Break and Switch. Refactor it to use the generic code, so that we can first handle Break, and then if anything remains, note a problem was found. The same path can handle a Switch which we handled before and also a BrOn etc. git diff is not that useful after the refactoring sadly, but basically this just moves the Break code and the Drop code, then adds the BranchUtils::operateOn stuff after them (and we switch to a unified visitor so that we get called for all expressions).
Diffstat (limited to 'src')
-rw-r--r--src/passes/MergeBlocks.cpp50
1 files changed, 25 insertions, 25 deletions
diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp
index ef0ead133..7e8819309 100644
--- a/src/passes/MergeBlocks.cpp
+++ b/src/passes/MergeBlocks.cpp
@@ -84,7 +84,9 @@ namespace wasm {
// Looks for reasons we can't remove the values from breaks to an origin
// For example, if there is a switch targeting us, we can't do it - we can't
// remove the value from other targets
-struct ProblemFinder : public ControlFlowWalker<ProblemFinder> {
+struct ProblemFinder
+ : public ControlFlowWalker<ProblemFinder,
+ UnifiedExpressionVisitor<ProblemFinder>> {
Name origin;
bool foundProblem = false;
// count br_ifs, and dropped br_ifs. if they don't match, then a br_if flow
@@ -95,38 +97,36 @@ struct ProblemFinder : public ControlFlowWalker<ProblemFinder> {
ProblemFinder(PassOptions& passOptions) : passOptions(passOptions) {}
- void visitBreak(Break* curr) {
- if (curr->name == origin) {
- if (curr->condition) {
- brIfs++;
- }
- // if the value has side effects, we can't remove it
- if (EffectAnalyzer(passOptions, getModule()->features, curr->value)
- .hasSideEffects()) {
- foundProblem = true;
+ void visitExpression(Expression* curr) {
+ if (auto* drop = curr->dynCast<Drop>()) {
+ if (auto* br = drop->value->dynCast<Break>()) {
+ if (br->name == origin && br->condition) {
+ droppedBrIfs++;
+ }
}
+ return;
}
- }
- void visitDrop(Drop* curr) {
- if (auto* br = curr->value->dynCast<Break>()) {
- if (br->name == origin && br->condition) {
- droppedBrIfs++;
+ if (auto* br = curr->dynCast<Break>()) {
+ if (br->name == origin) {
+ if (br->condition) {
+ brIfs++;
+ }
+ // if the value has side effects, we can't remove it
+ if (EffectAnalyzer(passOptions, getModule()->features, br->value)
+ .hasSideEffects()) {
+ foundProblem = true;
+ }
}
- }
- }
-
- void visitSwitch(Switch* curr) {
- if (curr->default_ == origin) {
- foundProblem = true;
return;
}
- for (auto& target : curr->targets) {
- if (target == origin) {
+
+ // Any other branch type - switch, br_on, etc. - is not handled yet.
+ BranchUtils::operateOnScopeNameUses(curr, [&](Name& name) {
+ if (name == origin) {
foundProblem = true;
- return;
}
- }
+ });
}
bool found() {