diff options
-rw-r--r-- | src/ir/branch-utils.h | 34 | ||||
-rw-r--r-- | src/passes/Flatten.cpp | 9 | ||||
-rw-r--r-- | src/passes/RemoveUnusedBrs.cpp | 94 | ||||
-rw-r--r-- | src/passes/SimplifyLocals.cpp | 5 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm | 30 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm.clamp | 30 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm.imprecise | 30 | ||||
-rw-r--r-- | test/passes/1.txt | 7 | ||||
-rw-r--r-- | test/passes/remove-unused-brs.txt | 79 | ||||
-rw-r--r-- | test/passes/remove-unused-brs.wast | 74 | ||||
-rw-r--r-- | test/unit.fromasm | 29 | ||||
-rw-r--r-- | test/unit.fromasm.clamp | 29 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise | 29 |
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 |