summaryrefslogtreecommitdiff
path: root/src/passes/RemoveUnusedBrs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/RemoveUnusedBrs.cpp')
-rw-r--r--src/passes/RemoveUnusedBrs.cpp15
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;
}