summaryrefslogtreecommitdiff
path: root/src/passes/RemoveUnusedBrs.cpp
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-04-25 16:51:49 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-04-25 17:09:21 -0700
commit8a68b4e6506e66312d75c3cff8aa0b36563548e3 (patch)
treefe42733df528358ac059121b73929e4db52e18cd /src/passes/RemoveUnusedBrs.cpp
parentb48cfe91be0381a049a413e1c6d7d1ba83514a95 (diff)
downloadbinaryen-8a68b4e6506e66312d75c3cff8aa0b36563548e3.tar.gz
binaryen-8a68b4e6506e66312d75c3cff8aa0b36563548e3.tar.bz2
binaryen-8a68b4e6506e66312d75c3cff8aa0b36563548e3.zip
optimize returns that flow out
Diffstat (limited to 'src/passes/RemoveUnusedBrs.cpp')
-rw-r--r--src/passes/RemoveUnusedBrs.cpp24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index 58c765d83..1dd16d07b 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -56,6 +56,10 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
} else {
self->valueCanFlow = false;
}
+ } else if (curr->is<Return>()) {
+ flows.clear();
+ flows.push_back(currp);
+ self->valueCanFlow = true; // start optimistic
} else if (curr->is<If>()) {
auto* iff = curr->cast<If>();
if (iff->ifFalse) {
@@ -73,8 +77,8 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
size_t size = flows.size();
size_t skip = 0;
for (size_t i = 0; i < size; i++) {
- auto* flow = (*flows[i])->cast<Break>();
- if (flow->name == name) {
+ auto* flow = (*flows[i])->dynCast<Break>();
+ if (flow && flow->name == name) {
if (!flow->value || self->valueCanFlow) {
if (!flow->value) {
// br => nop
@@ -96,6 +100,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
// drop a nop at the end of a block, which prevents a value flowing
while (block->list.size() > 0 && block->list.back()->is<Nop>()) {
block->list.resize(block->list.size() - 1);
+ self->anotherCycle = true;
}
}
} else if (curr->is<Nop>()) {
@@ -155,7 +160,20 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
anotherCycle = false;
WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<RemoveUnusedBrs>>>::walk(root);
assert(ifStack.empty());
- assert(flows.empty());
+ // flows may contain returns, which are flowing out and so can be optimized
+ for (size_t i = 0; i < flows.size(); i++) {
+ auto* flow = (*flows[i])->cast<Return>(); // cannot be a break
+ if (!flow->value) {
+ // return => nop
+ ExpressionManipulator::nop(flow);
+ anotherCycle = true;
+ } else if (valueCanFlow) {
+ // return with value => value
+ *flows[i] = flow->value;
+ anotherCycle = true;
+ }
+ }
+ flows.clear();
} while (anotherCycle);
}
};