Skip to content

Commit fa4e1e5

Browse files
authored
wasm2js: optimize switches (#2067)
Don't emit unneeded breaks in switch cases, instead do case X: case Y: .. case W: break .. for each group. Also, the group with the default doesn't need any cases but the default itself.
1 parent 28e01f3 commit fa4e1e5

7 files changed

Lines changed: 34 additions & 73953 deletions

File tree

src/wasm2js.h

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -830,11 +830,30 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m,
830830
Ref theSwitch =
831831
ValueBuilder::makeSwitch(makeAsmCoercion(condition, ASM_INT));
832832
ret[1]->push_back(theSwitch);
833+
// First, group the switch targets.
834+
std::map<Name, std::vector<Index>> targetIndexes;
833835
for (size_t i = 0; i < curr->targets.size(); i++) {
834-
ValueBuilder::appendCaseToSwitch(theSwitch, ValueBuilder::makeNum(i));
835-
ValueBuilder::appendCodeToSwitch(
836-
theSwitch, blockify(makeBreakOrContinue(curr->targets[i])), false);
836+
targetIndexes[curr->targets[i]].push_back(i);
837837
}
838+
// Emit group by group.
839+
for (auto& pair : targetIndexes) {
840+
auto target = pair.first;
841+
auto& indexes = pair.second;
842+
if (target != curr->default_) {
843+
for (auto i : indexes) {
844+
ValueBuilder::appendCaseToSwitch(theSwitch,
845+
ValueBuilder::makeNum(i));
846+
}
847+
ValueBuilder::appendCodeToSwitch(
848+
theSwitch, blockify(makeBreakOrContinue(target)), false);
849+
} else {
850+
// For the group going to the same place as the default, we can just
851+
// emit the default itself, which we do at the end.
852+
}
853+
}
854+
// TODO: if the group the default is in is not the largest, we can turn
855+
// the largest into
856+
// the default by using a local and a check on the range
838857
ValueBuilder::appendDefaultToSwitch(theSwitch);
839858
ValueBuilder::appendCodeToSwitch(
840859
theSwitch, blockify(makeBreakOrContinue(curr->default_)), false);

test/wasm2js/block.2asm.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,6 @@ function asmFunc(global, env, buffer) {
9595
}
9696
block46 : {
9797
switch (1 | 0) {
98-
case 0:
99-
break block46;
100-
case 1:
101-
break block46;
10298
default:
10399
break block46;
104100
};

0 commit comments

Comments
 (0)