summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/RemoveUnusedBrs.cpp16
-rw-r--r--test/emcc_hello_world.fromasm1
-rw-r--r--test/emcc_hello_world.fromasm.imprecise1
-rw-r--r--test/passes/remove-unused-brs.txt8
4 files changed, 19 insertions, 7 deletions
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index 255d86b9c..3d6d6973f 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -27,6 +27,8 @@ namespace wasm {
struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<RemoveUnusedBrs>>> {
bool isFunctionParallel() { return true; }
+ bool anotherCycle;
+
typedef std::vector<Break*> Flows;
// list of breaks that are currently flowing. if they reach their target without
@@ -68,6 +70,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
if (flows[i]->name == name) {
ExpressionManipulator::nop(flows[i]);
skip++;
+ self->anotherCycle = true;
} else if (skip > 0) {
flows[i - skip] = flows[i];
}
@@ -79,6 +82,8 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
} else if (curr->is<Loop>()) {
// TODO we might optimize branches out of here
flows.clear();
+ } else if (curr->is<Nop>()) {
+ // ignore (could be result of a previous cycle)
} else {
// anything else stops the flow
flows.clear();
@@ -100,6 +105,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
if (br && !br->condition) { // TODO: if there is a condition, join them
br->condition = curr->condition;
replaceCurrent(br);
+ anotherCycle = true;
}
}
}
@@ -125,7 +131,15 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
}
}
- // TODO: multiple rounds?
+ void walk(Expression*& root) {
+ // multiple cycles may be needed
+ do {
+ anotherCycle = false;
+ WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<RemoveUnusedBrs>>>::walk(root);
+ assert(ifStack.empty());
+ assert(flows.empty());
+ } while (anotherCycle);
+ }
};
static RegisterPass<RemoveUnusedBrs> registerPass("remove-unused-brs", "removes breaks from locations that are not needed");
diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm
index 9d50d32b2..75e2bf024 100644
--- a/test/emcc_hello_world.fromasm
+++ b/test/emcc_hello_world.fromasm
@@ -10864,7 +10864,6 @@
(get_local $$arg)
(get_local $$110)
)
- (br $label$break$L1)
)
)
)
diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise
index b303c5cac..4ada9b367 100644
--- a/test/emcc_hello_world.fromasm.imprecise
+++ b/test/emcc_hello_world.fromasm.imprecise
@@ -10862,7 +10862,6 @@
(get_local $$arg)
(get_local $$110)
)
- (br $label$break$L1)
)
)
)
diff --git a/test/passes/remove-unused-brs.txt b/test/passes/remove-unused-brs.txt
index 2404e7b39..226065f3f 100644
--- a/test/passes/remove-unused-brs.txt
+++ b/test/passes/remove-unused-brs.txt
@@ -169,9 +169,9 @@
(block $a
(block $b
(block $c
- (br $a)
+ (nop)
)
- (br $a)
+ (nop)
)
(nop)
)
@@ -187,9 +187,9 @@
(block $a
(block $b
(block $c
- (br $b)
+ (nop)
)
- (br $a)
+ (nop)
)
(nop)
)