summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2018-11-20 09:25:16 -0800
committerGitHub <noreply@github.com>2018-11-20 09:25:16 -0800
commit7ca9e24aa22bc57a4d37d3018cd02cf39cd9957a (patch)
tree4290dc66afe4c20697186216d9911397bfa2e872
parent801ff52bd0e7696ff105efd2a46932fa5f076708 (diff)
downloadbinaryen-7ca9e24aa22bc57a4d37d3018cd02cf39cd9957a.tar.gz
binaryen-7ca9e24aa22bc57a4d37d3018cd02cf39cd9957a.tar.bz2
binaryen-7ca9e24aa22bc57a4d37d3018cd02cf39cd9957a.zip
Switch optimizations in remove-unused-brs (#1753)
* Switch optimizations in remove-unused-brs: thread switch jumps, and turn a switch with all identical targets into a br * refinalize in interm operations in remove-unused-brs, as we can be confused by it
-rw-r--r--src/ir/branch-utils.h34
-rw-r--r--src/passes/Flatten.cpp9
-rw-r--r--src/passes/RemoveUnusedBrs.cpp94
-rw-r--r--src/passes/SimplifyLocals.cpp5
-rw-r--r--test/emcc_hello_world.fromasm30
-rw-r--r--test/emcc_hello_world.fromasm.clamp30
-rw-r--r--test/emcc_hello_world.fromasm.imprecise30
-rw-r--r--test/passes/1.txt7
-rw-r--r--test/passes/remove-unused-brs.txt79
-rw-r--r--test/passes/remove-unused-brs.wast74
-rw-r--r--test/unit.fromasm29
-rw-r--r--test/unit.fromasm.clamp29
-rw-r--r--test/unit.fromasm.imprecise29
13 files changed, 307 insertions, 172 deletions
diff --git a/src/ir/branch-utils.h b/src/ir/branch-utils.h
index 84be9f897..6f9299bf5 100644
--- a/src/ir/branch-utils.h
+++ b/src/ir/branch-utils.h
@@ -45,6 +45,40 @@ inline bool isBranchReachable(Expression* expr) {
WASM_UNREACHABLE();
}
+inline std::set<Name> getUniqueTargets(Switch* sw) {
+ std::set<Name> ret;
+ for (auto target : sw->targets) {
+ ret.insert(target);
+ }
+ ret.insert(sw->default_);
+ return ret;
+}
+
+// If we branch to 'from', change that to 'to' instead.
+inline bool replacePossibleTarget(Expression* branch, Name from, Name to) {
+ bool worked = false;
+ if (auto* br = branch->dynCast<Break>()) {
+ if (br->name == from) {
+ br->name = to;
+ worked = true;
+ }
+ } else if (auto* sw = branch->dynCast<Switch>()) {
+ for (auto& target : sw->targets) {
+ if (target == from) {
+ target = to;
+ worked = true;
+ }
+ }
+ if (sw->default_ == from) {
+ sw->default_ = to;
+ worked = true;
+ }
+ } else {
+ WASM_UNREACHABLE();
+ }
+ return worked;
+}
+
// returns the set of targets to which we branch that are
// outside of a node
inline std::set<Name> getExitingBranches(Expression* ast) {
diff --git a/src/passes/Flatten.cpp b/src/passes/Flatten.cpp
index f4b468098..aa5c1a491 100644
--- a/src/passes/Flatten.cpp
+++ b/src/passes/Flatten.cpp
@@ -53,8 +53,9 @@
#include <wasm.h>
#include <pass.h>
#include <wasm-builder.h>
-#include <ir/utils.h>
+#include <ir/branch-utils.h>
#include <ir/effects.h>
+#include <ir/utils.h>
namespace wasm {
@@ -232,11 +233,7 @@ struct Flatten : public WalkerPass<ExpressionStackWalker<Flatten, UnifiedExpress
Index temp = builder.addVar(getFunction(), type);
ourPreludes.push_back(builder.makeSetLocal(temp, sw->value));
// we don't know which break target will be hit - assign to them all
- std::set<Name> names;
- for (auto target : sw->targets) {
- names.insert(target);
- }
- names.insert(sw->default_);
+ auto names = BranchUtils::getUniqueTargets(sw);
for (auto name : names) {
ourPreludes.push_back(builder.makeSetLocal(
getTempForBreakTarget(name, type),
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index eb81b0a5a..62ecb3ed3 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -435,7 +435,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
}
}
- void sinkBlocks(Function* func) {
+ bool sinkBlocks(Function* func) {
struct Sinker : public PostWalker<Sinker> {
bool worked = false;
@@ -501,13 +501,14 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
sinker.doWalkFunction(func);
if (sinker.worked) {
- anotherCycle = true;
+ ReFinalize().walkFunctionInModule(func, getModule());
+ return true;
}
+ return false;
}
void doWalkFunction(Function* func) {
// multiple cycles may be needed
- bool worked = false;
do {
anotherCycle = false;
super::doWalkFunction(func);
@@ -532,32 +533,39 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
anotherCycle |= optimizeLoop(loop);
}
loops.clear();
+ if (anotherCycle) {
+ ReFinalize().walkFunctionInModule(func, getModule());
+ }
// sink blocks
- sinkBlocks(func);
- if (anotherCycle) worked = true;
+ if (sinkBlocks(func)) {
+ anotherCycle = true;
+ }
} while (anotherCycle);
- if (worked) {
- // Our work may alter block and if types, they may now return values that we made flow through them
- ReFinalize().walkFunctionInModule(func, getModule());
- }
-
// thread trivial jumps
struct JumpThreader : public ControlFlowWalker<JumpThreader> {
- // map of all value-less breaks going to a block (and not a loop)
- std::map<Block*, std::vector<Break*>> breaksToBlock;
+ // map of all value-less breaks and switches going to a block (and not a loop)
+ std::map<Block*, std::vector<Expression*>> branchesToBlock;
- // the names to update
- std::map<Break*, Name> newNames;
+ bool worked = false;
void visitBreak(Break* curr) {
if (!curr->value) {
if (auto* target = findBreakTarget(curr->name)->dynCast<Block>()) {
- breaksToBlock[target].push_back(curr);
+ branchesToBlock[target].push_back(curr);
+ }
+ }
+ }
+ void visitSwitch(Switch* curr) {
+ if (!curr->value) {
+ auto names = BranchUtils::getUniqueTargets(curr);
+ for (auto name : names) {
+ if (auto* target = findBreakTarget(name)->dynCast<Block>()) {
+ branchesToBlock[target].push_back(curr);
+ }
}
}
}
- // TODO: Switch?
void visitBlock(Block* curr) {
auto& list = curr->list;
if (list.size() == 1 && curr->name.is()) {
@@ -566,12 +574,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
// the two blocks must have the same type for us to update the branch, as otherwise
// one block may be unreachable and the other concrete, so one might lack a value
if (child->name.is() && child->name != curr->name && child->type == curr->type) {
- auto& breaks = breaksToBlock[child];
- for (auto* br : breaks) {
- newNames[br] = curr->name;
- breaksToBlock[curr].push_back(br); // update the list - we may push it even more later
- }
- breaksToBlock.erase(child);
+ redirectBranches(child, curr->name);
}
}
} else if (list.size() == 2) {
@@ -579,28 +582,28 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
auto* child = list[0]->dynCast<Block>();
auto* jump = list[1]->dynCast<Break>();
if (child && child->name.is() && jump && ExpressionAnalyzer::isSimple(jump)) {
- auto& breaks = breaksToBlock[child];
- for (auto* br : breaks) {
- newNames[br] = jump->name;
- }
- // if the jump is to another block then we can update the list, and maybe push it even more later
- if (auto* newTarget = findBreakTarget(jump->name)->dynCast<Block>()) {
- for (auto* br : breaks) {
- breaksToBlock[newTarget].push_back(br);
- }
- }
- breaksToBlock.erase(child);
+ redirectBranches(child, jump->name);
}
}
}
- void finish(Function* func) {
- for (auto& iter : newNames) {
- auto* br = iter.first;
- auto name = iter.second;
- br->name = name;
+ void redirectBranches(Block* from, Name to) {
+ auto& branches = branchesToBlock[from];
+ for (auto* branch : branches) {
+ if (BranchUtils::replacePossibleTarget(branch, from->name, to)) {
+ worked = true;
+ }
+ }
+ // if the jump is to another block then we can update the list, and maybe push it even more later
+ if (auto* newTarget = findBreakTarget(to)->dynCast<Block>()) {
+ for (auto* branch : branches) {
+ branchesToBlock[newTarget].push_back(branch);
+ }
}
- if (newNames.size() > 0) {
+ }
+
+ void finish(Function* func) {
+ if (worked) {
// by changing where brs go, we may change block types etc.
ReFinalize().walkFunctionInModule(func, getModule());
}
@@ -686,6 +689,19 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
}
}
+ void visitSwitch(Switch* curr) {
+ if (BranchUtils::getUniqueTargets(curr).size() == 1) {
+ // This switch has just one target no matter what; replace with a br.
+ Builder builder(*getModule());
+ replaceCurrent(
+ builder.makeSequence(
+ builder.makeDrop(curr->condition), // might have side effects
+ builder.makeBreak(curr->default_, curr->value)
+ )
+ );
+ }
+ }
+
// Restructuring of ifs: if we have
// (block $x
// (br_if $x (cond))
diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp
index aadf766ac..bf4eed24e 100644
--- a/src/passes/SimplifyLocals.cpp
+++ b/src/passes/SimplifyLocals.cpp
@@ -50,6 +50,7 @@
#include <wasm-builder.h>
#include <wasm-traversal.h>
#include <pass.h>
+#include <ir/branch-utils.h>
#include <ir/count.h>
#include <ir/effects.h>
#include "ir/equivalent_sets.h"
@@ -128,10 +129,10 @@ struct SimplifyLocals : public WalkerPass<LinearExecutionWalker<SimplifyLocals<a
assert(!curr->cast<If>()->ifFalse); // if-elses are handled by doNoteIfElse* methods
} else if (curr->is<Switch>()) {
auto* sw = curr->cast<Switch>();
- for (auto target : sw->targets) {
+ auto targets = BranchUtils::getUniqueTargets(sw);
+ for (auto target : targets) {
self->unoptimizableBlocks.insert(target);
}
- self->unoptimizableBlocks.insert(sw->default_);
// TODO: we could use this info to stop gathering data on these blocks
}
self->sinkables.clear();
diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm
index cb9b99b74..e70998db0 100644
--- a/test/emcc_hello_world.fromasm
+++ b/test/emcc_hello_world.fromasm
@@ -3309,19 +3309,19 @@
(block $__rjti$4
(block $__rjti$3
(block $switch-default120
- (block $switch-case42
+ (block $switch-case119
(block $switch-case41
(block $switch-case40
(block $switch-case39
(block $switch-case38
(block $switch-case37
(block $switch-case36
- (block $switch-case34
+ (block $switch-case35
(block $switch-case33
- (block $switch-case29
+ (block $switch-case30
(block $switch-case28
(block $switch-case27
- (br_table $switch-case42 $switch-default120 $switch-case40 $switch-default120 $switch-case42 $switch-case42 $switch-case42 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case41 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case29 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case42 $switch-default120 $switch-case37 $switch-case34 $switch-case42 $switch-case42 $switch-case42 $switch-default120 $switch-case34 $switch-default120 $switch-default120 $switch-default120 $switch-case38 $switch-case27 $switch-case33 $switch-case28 $switch-default120 $switch-default120 $switch-case39 $switch-default120 $switch-case36 $switch-default120 $switch-default120 $switch-case29 $switch-default120
+ (br_table $switch-case119 $switch-default120 $switch-case40 $switch-default120 $switch-case119 $switch-case119 $switch-case119 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case41 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case30 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case119 $switch-default120 $switch-case37 $switch-case35 $switch-case119 $switch-case119 $switch-case119 $switch-default120 $switch-case35 $switch-default120 $switch-default120 $switch-default120 $switch-case38 $switch-case27 $switch-case33 $switch-case28 $switch-default120 $switch-default120 $switch-case39 $switch-default120 $switch-case36 $switch-default120 $switch-default120 $switch-case30 $switch-default120
(i32.sub
(tee_local $19
(select
@@ -6915,7 +6915,7 @@
(get_local $1)
(i32.const 20)
)
- (block $switch-default
+ (block $label$break$L1
(block $switch-case9
(block $switch-case8
(block $switch-case7
@@ -6926,7 +6926,7 @@
(block $switch-case2
(block $switch-case1
(block $switch-case
- (br_table $switch-case $switch-case1 $switch-case2 $switch-case3 $switch-case4 $switch-case5 $switch-case6 $switch-case7 $switch-case8 $switch-case9 $switch-default
+ (br_table $switch-case $switch-case1 $switch-case2 $switch-case3 $switch-case4 $switch-case5 $switch-case6 $switch-case7 $switch-case8 $switch-case9 $label$break$L1
(i32.sub
(get_local $1)
(i32.const 9)
@@ -6959,7 +6959,7 @@
(get_local $0)
(get_local $3)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $1
(i32.load
@@ -7000,7 +7000,7 @@
(i32.const 31)
)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7032,7 +7032,7 @@
(get_local $0)
(i32.const 0)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $5
(i32.load
@@ -7071,7 +7071,7 @@
(get_local $0)
(get_local $3)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7123,7 +7123,7 @@
(i32.const 31)
)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7158,7 +7158,7 @@
(get_local $0)
(i32.const 0)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7210,7 +7210,7 @@
(i32.const 31)
)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7245,7 +7245,7 @@
(get_local $0)
(i32.const 0)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $4
(f64.load
@@ -7273,7 +7273,7 @@
(get_local $0)
(get_local $4)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $4
(f64.load
diff --git a/test/emcc_hello_world.fromasm.clamp b/test/emcc_hello_world.fromasm.clamp
index dafa2db7b..244f8adba 100644
--- a/test/emcc_hello_world.fromasm.clamp
+++ b/test/emcc_hello_world.fromasm.clamp
@@ -3359,19 +3359,19 @@
(block $__rjti$4
(block $__rjti$3
(block $switch-default120
- (block $switch-case42
+ (block $switch-case119
(block $switch-case41
(block $switch-case40
(block $switch-case39
(block $switch-case38
(block $switch-case37
(block $switch-case36
- (block $switch-case34
+ (block $switch-case35
(block $switch-case33
- (block $switch-case29
+ (block $switch-case30
(block $switch-case28
(block $switch-case27
- (br_table $switch-case42 $switch-default120 $switch-case40 $switch-default120 $switch-case42 $switch-case42 $switch-case42 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case41 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case29 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case42 $switch-default120 $switch-case37 $switch-case34 $switch-case42 $switch-case42 $switch-case42 $switch-default120 $switch-case34 $switch-default120 $switch-default120 $switch-default120 $switch-case38 $switch-case27 $switch-case33 $switch-case28 $switch-default120 $switch-default120 $switch-case39 $switch-default120 $switch-case36 $switch-default120 $switch-default120 $switch-case29 $switch-default120
+ (br_table $switch-case119 $switch-default120 $switch-case40 $switch-default120 $switch-case119 $switch-case119 $switch-case119 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case41 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case30 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case119 $switch-default120 $switch-case37 $switch-case35 $switch-case119 $switch-case119 $switch-case119 $switch-default120 $switch-case35 $switch-default120 $switch-default120 $switch-default120 $switch-case38 $switch-case27 $switch-case33 $switch-case28 $switch-default120 $switch-default120 $switch-case39 $switch-default120 $switch-case36 $switch-default120 $switch-default120 $switch-case30 $switch-default120
(i32.sub
(tee_local $19
(select
@@ -6965,7 +6965,7 @@
(get_local $1)
(i32.const 20)
)
- (block $switch-default
+ (block $label$break$L1
(block $switch-case9
(block $switch-case8
(block $switch-case7
@@ -6976,7 +6976,7 @@
(block $switch-case2
(block $switch-case1
(block $switch-case
- (br_table $switch-case $switch-case1 $switch-case2 $switch-case3 $switch-case4 $switch-case5 $switch-case6 $switch-case7 $switch-case8 $switch-case9 $switch-default
+ (br_table $switch-case $switch-case1 $switch-case2 $switch-case3 $switch-case4 $switch-case5 $switch-case6 $switch-case7 $switch-case8 $switch-case9 $label$break$L1
(i32.sub
(get_local $1)
(i32.const 9)
@@ -7009,7 +7009,7 @@
(get_local $0)
(get_local $3)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $1
(i32.load
@@ -7050,7 +7050,7 @@
(i32.const 31)
)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7082,7 +7082,7 @@
(get_local $0)
(i32.const 0)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $5
(i32.load
@@ -7121,7 +7121,7 @@
(get_local $0)
(get_local $3)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7173,7 +7173,7 @@
(i32.const 31)
)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7208,7 +7208,7 @@
(get_local $0)
(i32.const 0)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7260,7 +7260,7 @@
(i32.const 31)
)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7295,7 +7295,7 @@
(get_local $0)
(i32.const 0)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $4
(f64.load
@@ -7323,7 +7323,7 @@
(get_local $0)
(get_local $4)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $4
(f64.load
diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise
index ed05f6905..5cfa87fe1 100644
--- a/test/emcc_hello_world.fromasm.imprecise
+++ b/test/emcc_hello_world.fromasm.imprecise
@@ -3249,19 +3249,19 @@
(block $__rjti$4
(block $__rjti$3
(block $switch-default120
- (block $switch-case42
+ (block $switch-case119
(block $switch-case41
(block $switch-case40
(block $switch-case39
(block $switch-case38
(block $switch-case37
(block $switch-case36
- (block $switch-case34
+ (block $switch-case35
(block $switch-case33
- (block $switch-case29
+ (block $switch-case30
(block $switch-case28
(block $switch-case27
- (br_table $switch-case42 $switch-default120 $switch-case40 $switch-default120 $switch-case42 $switch-case42 $switch-case42 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case41 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case29 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case42 $switch-default120 $switch-case37 $switch-case34 $switch-case42 $switch-case42 $switch-case42 $switch-default120 $switch-case34 $switch-default120 $switch-default120 $switch-default120 $switch-case38 $switch-case27 $switch-case33 $switch-case28 $switch-default120 $switch-default120 $switch-case39 $switch-default120 $switch-case36 $switch-default120 $switch-default120 $switch-case29 $switch-default120
+ (br_table $switch-case119 $switch-default120 $switch-case40 $switch-default120 $switch-case119 $switch-case119 $switch-case119 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case41 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case30 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-default120 $switch-case119 $switch-default120 $switch-case37 $switch-case35 $switch-case119 $switch-case119 $switch-case119 $switch-default120 $switch-case35 $switch-default120 $switch-default120 $switch-default120 $switch-case38 $switch-case27 $switch-case33 $switch-case28 $switch-default120 $switch-default120 $switch-case39 $switch-default120 $switch-case36 $switch-default120 $switch-default120 $switch-case30 $switch-default120
(i32.sub
(tee_local $19
(select
@@ -6829,7 +6829,7 @@
(get_local $1)
(i32.const 20)
)
- (block $switch-default
+ (block $label$break$L1
(block $switch-case9
(block $switch-case8
(block $switch-case7
@@ -6840,7 +6840,7 @@
(block $switch-case2
(block $switch-case1
(block $switch-case
- (br_table $switch-case $switch-case1 $switch-case2 $switch-case3 $switch-case4 $switch-case5 $switch-case6 $switch-case7 $switch-case8 $switch-case9 $switch-default
+ (br_table $switch-case $switch-case1 $switch-case2 $switch-case3 $switch-case4 $switch-case5 $switch-case6 $switch-case7 $switch-case8 $switch-case9 $label$break$L1
(i32.sub
(get_local $1)
(i32.const 9)
@@ -6873,7 +6873,7 @@
(get_local $0)
(get_local $3)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $1
(i32.load
@@ -6914,7 +6914,7 @@
(i32.const 31)
)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -6946,7 +6946,7 @@
(get_local $0)
(i32.const 0)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $5
(i32.load
@@ -6985,7 +6985,7 @@
(get_local $0)
(get_local $3)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7037,7 +7037,7 @@
(i32.const 31)
)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7072,7 +7072,7 @@
(get_local $0)
(i32.const 0)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7124,7 +7124,7 @@
(i32.const 31)
)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $3
(i32.load
@@ -7159,7 +7159,7 @@
(get_local $0)
(i32.const 0)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $4
(f64.load
@@ -7187,7 +7187,7 @@
(get_local $0)
(get_local $4)
)
- (br $switch-default)
+ (br $label$break$L1)
)
(set_local $4
(f64.load
diff --git a/test/passes/1.txt b/test/passes/1.txt
index 22b7032fe..cf6a569eb 100644
--- a/test/passes/1.txt
+++ b/test/passes/1.txt
@@ -196,12 +196,9 @@
(i32.const 1)
)
(block $switch$3$default
- (block $switch$3$case$6
- (br_table $switch$3$case$6 $switch$3$case$6 $switch$3$case$6 $switch$3$default
- (get_local $0)
- )
+ (br_table $block$6$break $block$6$break $block$6$break $switch$3$default
+ (get_local $0)
)
- (br $block$6$break)
)
(call $switch
(i32.const 2)
diff --git a/test/passes/remove-unused-brs.txt b/test/passes/remove-unused-brs.txt
index 3f4528a5c..a44a62c20 100644
--- a/test/passes/remove-unused-brs.txt
+++ b/test/passes/remove-unused-brs.txt
@@ -1675,6 +1675,7 @@
)
)
)
+ (call $trim-switch)
)
)
(func $same-target-br_if-and-br (; 67 ;) (type $1)
@@ -2129,4 +2130,82 @@
)
)
)
+ (func $switch-to-br (; 97 ;) (type $1)
+ (block $A
+ (block $y
+ (block
+ (drop
+ (i32.const 0)
+ )
+ (br $A)
+ )
+ )
+ )
+ )
+ (func $switch-to-br-value (; 98 ;) (type $2) (result i32)
+ (block $A (result i32)
+ (block $y (result i32)
+ (block
+ (drop
+ (i32.const 1)
+ )
+ (br $A
+ (i32.const 0)
+ )
+ )
+ )
+ )
+ )
+ (func $switch-threading-multi (; 99 ;) (type $3) (param $x i32) (param $y i32) (result i32)
+ (block $block$5$break
+ (block $block$4$break
+ (loop $shape$1$continue
+ (block $block$3$break
+ (block $switch$2$case$5
+ (block $switch$2$case$4
+ (block $switch$2$default
+ (block $switch$2$case$2
+ (br_table $shape$1$continue $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$5$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$3$break $block$4$break $block$3$break
+ (get_local $x)
+ )
+ )
+ (br $shape$1$continue)
+ )
+ (br $block$3$break)
+ )
+ (br $block$4$break)
+ )
+ (br $block$5$break)
+ )
+ )
+ (unreachable)
+ )
+ (set_local $y
+ (i32.const 1)
+ )
+ (unreachable)
+ )
+ (set_local $y
+ (i32.const 2)
+ )
+ (unreachable)
+ )
+ (func $fuzz-type-changes-in-our-cycles (; 100 ;) (type $2) (result i32)
+ (loop $label$1
+ (if
+ (i32.const 0)
+ (if
+ (i32.const 0)
+ (block $label$3
+ (block $block
+ )
+ )
+ (return
+ (i32.const -8192)
+ )
+ )
+ )
+ (br $label$1)
+ )
+ )
)
diff --git a/test/passes/remove-unused-brs.wast b/test/passes/remove-unused-brs.wast
index ea3e5f320..7a1943c14 100644
--- a/test/passes/remove-unused-brs.wast
+++ b/test/passes/remove-unused-brs.wast
@@ -1355,6 +1355,7 @@
(i32.const 0)
)
)
+ (call $trim-switch)
)
)
(func $same-target-br_if-and-br
@@ -1741,5 +1742,78 @@
)
)
)
+ (func $switch-to-br
+ (block $A
+ (block $y
+ (br_table $y $y $A $A
+ (i32.const 0)
+ )
+ )
+ )
+ )
+ (func $switch-to-br-value (result i32)
+ (block $A (result i32)
+ (block $y (result i32)
+ (br_table $A $A $A
+ (i32.const 0)
+ (i32.const 1)
+ )
+ )
+ )
+ )
+ (func $switch-threading-multi (param $x i32) (param $y i32) (result i32)
+ (block $block$5$break
+ (block $block$4$break
+ (loop $shape$1$continue
+ (block $block$3$break
+ (block $switch$2$case$5
+ (block $switch$2$case$4
+ (block $switch$2$default
+ (block $switch$2$case$2
+ (br_table $switch$2$case$2 $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$case$5 $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$default $switch$2$case$4 $switch$2$default
+ (get_local $x)
+ )
+ )
+ (br $shape$1$continue)
+ )
+ (br $block$3$break)
+ ) ;; switch$2$case$4
+ (br $block$4$break)
+ )
+ (br $block$5$break)
+ )
+ )
+ (unreachable)
+ ) ;; block$4$break
+ (set_local $y
+ (i32.const 1)
+ )
+ (unreachable)
+ )
+ (set_local $y
+ (i32.const 2)
+ )
+ (unreachable)
+ )
+ (func $fuzz-type-changes-in-our-cycles (result i32)
+ (loop $label$1
+ (if
+ (i32.const 0)
+ (block $label$3
+ (if
+ (i32.const 0)
+ (block
+ (nop)
+ (br $label$3)
+ )
+ (return
+ (i32.const -8192)
+ )
+ )
+ )
+ )
+ (br $label$1)
+ )
+ )
)
diff --git a/test/unit.fromasm b/test/unit.fromasm
index 691c65136..3eb75dc5a 100644
--- a/test/unit.fromasm
+++ b/test/unit.fromasm
@@ -182,37 +182,16 @@
(i32.const 51)
)
)
- (block $switch-case4
- (drop
- (i32.add
- (get_local $0)
- (i32.const -5)
- )
- )
- (br $switch-case4)
- )
(loop $label$continue$L1
(block $label$break$L1
(loop $label$continue$L3
(block $label$break$L3
- (block $switch-default
- (block $switch-case13
- (block $switch-case12
- (block $switch-case11
- (br_table $switch-case11 $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-case13 $switch-default $switch-default $switch-default $switch-default $switch-default $switch-case12 $switch-default
- (i32.sub
- (get_local $0)
- (i32.const -1)
- )
- )
- )
- (br $label$break$L1)
- )
- (br $label$continue$L3)
+ (br_table $label$break$L3 $label$break$L1 $label$break$L1 $label$break$L1 $label$break$L1 $label$break$L1 $label$continue$L3 $label$break$L1
+ (i32.add
+ (get_local $0)
+ (i32.const -110)
)
- (br $label$break$L3)
)
- (br $label$break$L1)
)
)
(call $h
diff --git a/test/unit.fromasm.clamp b/test/unit.fromasm.clamp
index 44de1e100..e34bf66e4 100644
--- a/test/unit.fromasm.clamp
+++ b/test/unit.fromasm.clamp
@@ -232,37 +232,16 @@
(i32.const 51)
)
)
- (block $switch-case4
- (drop
- (i32.add
- (get_local $0)
- (i32.const -5)
- )
- )
- (br $switch-case4)
- )
(loop $label$continue$L1
(block $label$break$L1
(loop $label$continue$L3
(block $label$break$L3
- (block $switch-default
- (block $switch-case13
- (block $switch-case12
- (block $switch-case11
- (br_table $switch-case11 $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-case13 $switch-default $switch-default $switch-default $switch-default $switch-default $switch-case12 $switch-default
- (i32.sub
- (get_local $0)
- (i32.const -1)
- )
- )
- )
- (br $label$break$L1)
- )
- (br $label$continue$L3)
+ (br_table $label$break$L3 $label$break$L1 $label$break$L1 $label$break$L1 $label$break$L1 $label$break$L1 $label$continue$L3 $label$break$L1
+ (i32.add
+ (get_local $0)
+ (i32.const -110)
)
- (br $label$break$L3)
)
- (br $label$break$L1)
)
)
(call $h
diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise
index d9cd05f28..04794f28f 100644
--- a/test/unit.fromasm.imprecise
+++ b/test/unit.fromasm.imprecise
@@ -178,37 +178,16 @@
(i32.const 51)
)
)
- (block $switch-case4
- (drop
- (i32.add
- (get_local $0)
- (i32.const -5)
- )
- )
- (br $switch-case4)
- )
(loop $label$continue$L1
(block $label$break$L1
(loop $label$continue$L3
(block $label$break$L3
- (block $switch-default
- (block $switch-case13
- (block $switch-case12
- (block $switch-case11
- (br_table $switch-case11 $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-default $switch-case13 $switch-default $switch-default $switch-default $switch-default $switch-default $switch-case12 $switch-default
- (i32.sub
- (get_local $0)
- (i32.const -1)
- )
- )
- )
- (br $label$break$L1)
- )
- (br $label$continue$L3)
+ (br_table $label$break$L3 $label$break$L1 $label$break$L1 $label$break$L1 $label$break$L1 $label$break$L1 $label$continue$L3 $label$break$L1
+ (i32.add
+ (get_local $0)
+ (i32.const -110)
)
- (br $label$break$L3)
)
- (br $label$break$L1)
)
)
(call $h