diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-01-23 14:18:35 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-01-23 14:18:35 -0800 |
commit | da726f060373d957704c51cdb019026e6c3c0a41 (patch) | |
tree | 64b07dcc545360812720a9b3a8948e26b584a2d4 /src/passes/RemoveUnusedBrs.cpp | |
parent | 0e6ba7b1ee49bacd2a5ff4ae1b01982f624463f6 (diff) | |
download | binaryen-da726f060373d957704c51cdb019026e6c3c0a41.tar.gz binaryen-da726f060373d957704c51cdb019026e6c3c0a41.tar.bz2 binaryen-da726f060373d957704c51cdb019026e6c3c0a41.zip |
fold if-br into br_if
Diffstat (limited to 'src/passes/RemoveUnusedBrs.cpp')
-rw-r--r-- | src/passes/RemoveUnusedBrs.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index 245642055..c7fa43df9 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -28,7 +28,15 @@ struct RemoveUnusedBrs : public WalkerPass<WasmWalker<RemoveUnusedBrs>> { // specifically for if-else, turn an if-else with branches to the same target at the end of each // child, and with a value, to a branch to that target containing the if-else void visitIf(If* curr) { - if (!curr->ifFalse) return; + if (!curr->ifFalse) { + // try to reduce an if (condition) br => br_if (condition) , which might open up other optimization opportunities + Break* br = curr->ifTrue->dyn_cast<Break>(); + if (br && !br->condition) { // TODO: if there is a condition, join them + br->condition = curr->condition; + replaceCurrent(br); + } + return; + } if (curr->type != none) return; // already has a returned value // an if_else that indirectly returns a value by breaking to the same target can potentially remove both breaks, and break outside once auto getLast = [](Expression *side) -> Expression* { @@ -66,9 +74,10 @@ struct RemoveUnusedBrs : public WalkerPass<WasmWalker<RemoveUnusedBrs>> { void visitBlock(Block *curr) { if (curr->name.isNull()) return; if (curr->list.size() == 0) return; - // preparation - remove all code after a break, since it can't execute, and it might confuse us (we look at the last) + // preparation - remove all code after an unconditional break, since it can't execute, and it might confuse us (we look at the last) for (size_t i = 0; i < curr->list.size()-1; i++) { - if (curr->list[i]->is<Break>()) { + Break* br = curr->list[i]->dyn_cast<Break>(); + if (br && !br->condition) { curr->list.resize(i+1); break; } |