diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-08-25 13:48:29 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2017-08-25 16:04:36 -0700 |
commit | 9592b881bd1d17dfa24cfee5aea31f6f9d8312d5 (patch) | |
tree | 5fe7c1b6d559040740ee8387efed0dbb6c0264b7 /src | |
parent | ddfa483430c35ce81f05a6497cc68536b594c2b3 (diff) | |
download | binaryen-9592b881bd1d17dfa24cfee5aea31f6f9d8312d5.tar.gz binaryen-9592b881bd1d17dfa24cfee5aea31f6f9d8312d5.tar.bz2 binaryen-9592b881bd1d17dfa24cfee5aea31f6f9d8312d5.zip |
fix flow of values stopping in remove-unused-brs: we must remove all flows with a value from the current state, not just set the global state as to whether we can flow or not (as it will be set later by other things)
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/RemoveUnusedBrs.cpp | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index a3ef15639..e627ce138 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -74,7 +74,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> { flows.push_back(currp); self->valueCanFlow = true; // start optimistic } else { - self->valueCanFlow = false; + self->stopValueFlow(); } } else if (curr->is<Return>()) { flows.clear(); @@ -84,6 +84,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> { auto* iff = curr->cast<If>(); if (iff->condition->type == unreachable) { // avoid trying to optimize this, we never reach it anyhow + self->stopFlow(); return; } if (iff->ifFalse) { @@ -94,7 +95,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> { self->ifStack.pop_back(); } else { // if without else stops the flow of values - self->valueCanFlow = false; + self->stopValueFlow(); } } else if (curr->is<Block>()) { // any breaks flowing to here are unnecessary, as we get here anyhow @@ -132,16 +133,31 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> { } } else if (curr->is<Nop>()) { // ignore (could be result of a previous cycle) - self->valueCanFlow = false; + self->stopValueFlow(); } else if (curr->is<Loop>()) { // do nothing - it's ok for values to flow out } else { // anything else stops the flow - flows.clear(); - self->valueCanFlow = false; + self->stopFlow(); } } + void stopFlow() { + flows.clear(); + valueCanFlow = false; + } + + void stopValueFlow() { + flows.erase(std::remove_if(flows.begin(), flows.end(), [&](Expression** currp) { + auto* curr = *currp; + if (auto* ret = curr->dynCast<Return>()) { + return ret->value; + } + return curr->cast<Break>()->value; + }), flows.end()); + valueCanFlow = false; + } + static void clear(RemoveUnusedBrs* self, Expression** currp) { self->flows.clear(); } |