diff options
Diffstat (limited to 'src/passes/CodePushing.cpp')
-rw-r--r-- | src/passes/CodePushing.cpp | 87 |
1 files changed, 45 insertions, 42 deletions
diff --git a/src/passes/CodePushing.cpp b/src/passes/CodePushing.cpp index 52aab08ad..342cb5182 100644 --- a/src/passes/CodePushing.cpp +++ b/src/passes/CodePushing.cpp @@ -19,10 +19,10 @@ // a location behind a condition, where it might not always execute. // -#include <wasm.h> +#include <ir/effects.h> #include <pass.h> #include <wasm-builder.h> -#include <ir/effects.h> +#include <wasm.h> namespace wasm { @@ -50,26 +50,23 @@ struct LocalAnalyzer : public PostWalker<LocalAnalyzer> { std::fill(sfa.begin() + func->getNumParams(), sfa.end(), true); walk(func->body); for (Index i = 0; i < num; i++) { - if (numSets[i] == 0) sfa[i] = false; + if (numSets[i] == 0) + sfa[i] = false; } } - bool isSFA(Index i) { - return sfa[i]; - } + bool isSFA(Index i) { return sfa[i]; } - Index getNumGets(Index i) { - return numGets[i]; - } + Index getNumGets(Index i) { return numGets[i]; } - void visitGetLocal(GetLocal *curr) { + void visitGetLocal(GetLocal* curr) { if (numSets[curr->index] == 0) { sfa[curr->index] = false; } numGets[curr->index]++; } - void visitSetLocal(SetLocal *curr) { + void visitSetLocal(SetLocal* curr) { numSets[curr->index]++; if (numSets[curr->index] > 1) { sfa[curr->index] = false; @@ -86,12 +83,18 @@ class Pusher { PassOptions& passOptions; public: - Pusher(Block* block, LocalAnalyzer& analyzer, std::vector<Index>& numGetsSoFar, PassOptions& passOptions) : list(block->list), analyzer(analyzer), numGetsSoFar(numGetsSoFar), passOptions(passOptions) { + Pusher(Block* block, + LocalAnalyzer& analyzer, + std::vector<Index>& numGetsSoFar, + PassOptions& passOptions) + : list(block->list), analyzer(analyzer), numGetsSoFar(numGetsSoFar), + passOptions(passOptions) { // Find an optimization segment: from the first pushable thing, to the first // point past which we want to push. We then push in that range before // continuing forward. - Index relevant = list.size() - 1; // we never need to push past a final element, as - // we couldn't be used after it. + // we never need to push past a final element, as we couldn't be used after + // it. + Index relevant = list.size() - 1; const Index nothing = -1; Index i = 0; Index firstPushable = nothing; @@ -114,7 +117,8 @@ public: private: SetLocal* isPushable(Expression* curr) { auto* set = curr->dynCast<SetLocal>(); - if (!set) return nullptr; + if (!set) + return nullptr; auto index = set->index; // to be pushable, this must be SFA and the right # of gets, // but also have no side effects, as it may not execute if pushed. @@ -133,7 +137,8 @@ private: if (auto* drop = curr->dynCast<Drop>()) { curr = drop->value; } - if (curr->is<If>()) return true; + if (curr->is<If>()) + return true; if (auto* br = curr->dynCast<Break>()) { return !!br->condition; } @@ -146,12 +151,14 @@ private: // forward, that way we can push later things out of the way // of earlier ones. Once we know all we can push, we push it all // in one pass, keeping the order of the pushables intact. - assert(firstPushable != Index(-1) && pushPoint != Index(-1) && firstPushable < pushPoint); - EffectAnalyzer cumulativeEffects(passOptions); // everything that matters if you want - // to be pushed past the pushPoint + assert(firstPushable != Index(-1) && pushPoint != Index(-1) && + firstPushable < pushPoint); + // everything that matters if you want to be pushed past the pushPoint + EffectAnalyzer cumulativeEffects(passOptions); cumulativeEffects.analyze(list[pushPoint]); - cumulativeEffects.branches = false; // it is ok to ignore the branching here, - // that is the crucial point of this opt + // it is ok to ignore the branching here, that is the crucial point of this + // opt + cumulativeEffects.branches = false; std::vector<SetLocal*> toPush; Index i = pushPoint - 1; while (1) { @@ -159,11 +166,11 @@ private: if (pushable) { auto iter = pushableEffects.find(pushable); if (iter == pushableEffects.end()) { - iter = pushableEffects.emplace( - std::piecewise_construct, - std::forward_as_tuple(pushable), - std::forward_as_tuple(passOptions, pushable) - ).first; + iter = pushableEffects + .emplace(std::piecewise_construct, + std::forward_as_tuple(pushable), + std::forward_as_tuple(passOptions, pushable)) + .first; } auto& effects = iter->second; if (cumulativeEffects.invalidates(effects)) { @@ -236,30 +243,26 @@ struct CodePushing : public WalkerPass<PostWalker<CodePushing>> { walk(func->body); } - void visitGetLocal(GetLocal *curr) { - numGetsSoFar[curr->index]++; - } + void visitGetLocal(GetLocal* curr) { numGetsSoFar[curr->index]++; } void visitBlock(Block* curr) { // Pushing code only makes sense if we are size 3 or above: we need // one element to push, an element to push it past, and an element to use // what we pushed. - if (curr->list.size() < 3) return; - // At this point in the postorder traversal we have gone through all our children. - // Therefore any variable whose gets seen so far is equal to the total gets must - // have no further users after this block. And therefore when we see an SFA - // variable defined here, we know it isn't used before it either, and has just this - // one assign. So we can push it forward while we don't hit a non-control-flow - // ordering invalidation issue, since if this isn't a loop, it's fine (we're not - // used outside), and if it is, we hit the assign before any use (as we can't - // push it past a use). + if (curr->list.size() < 3) + return; + // At this point in the postorder traversal we have gone through all our + // children. Therefore any variable whose gets seen so far is equal to the + // total gets must have no further users after this block. And therefore + // when we see an SFA variable defined here, we know it isn't used before it + // either, and has just this one assign. So we can push it forward while we + // don't hit a non-control-flow ordering invalidation issue, since if this + // isn't a loop, it's fine (we're not used outside), and if it is, we hit + // the assign before any use (as we can't push it past a use). Pusher pusher(curr, analyzer, numGetsSoFar, getPassOptions()); } }; -Pass *createCodePushingPass() { - return new CodePushing(); -} +Pass* createCodePushingPass() { return new CodePushing(); } } // namespace wasm - |