diff options
Diffstat (limited to 'src/ir/LocalGraph.cpp')
-rw-r--r-- | src/ir/LocalGraph.cpp | 79 |
1 files changed, 46 insertions, 33 deletions
diff --git a/src/ir/LocalGraph.cpp b/src/ir/LocalGraph.cpp index 1cf883c19..1a2ccc0a2 100644 --- a/src/ir/LocalGraph.cpp +++ b/src/ir/LocalGraph.cpp @@ -16,11 +16,11 @@ #include <iterator> -#include <wasm-builder.h> -#include <wasm-printing.h> +#include <cfg/cfg-traversal.h> #include <ir/find_all.h> #include <ir/local-graph.h> -#include <cfg/cfg-traversal.h> +#include <wasm-builder.h> +#include <wasm-printing.h> namespace wasm { @@ -28,8 +28,10 @@ namespace LocalGraphInternal { // Information about a basic block. struct Info { - std::vector<Expression*> actions; // actions occurring in this block: local.gets and local.sets - std::unordered_map<Index, SetLocal*> lastSets; // for each index, the last local.set for it + // actions occurring in this block: local.gets and local.sets + std::vector<Expression*> actions; + // for each index, the last local.set for it + std::unordered_map<Index, SetLocal*> lastSets; }; // flow helper class. flows the gets to their sets @@ -38,7 +40,10 @@ struct Flower : public CFGWalker<Flower, Visitor<Flower>, Info> { LocalGraph::GetSetses& getSetses; LocalGraph::Locations& locations; - Flower(LocalGraph::GetSetses& getSetses, LocalGraph::Locations& locations, Function* func) : getSetses(getSetses), locations(locations) { + Flower(LocalGraph::GetSetses& getSetses, + LocalGraph::Locations& locations, + Function* func) + : getSetses(getSetses), locations(locations) { setFunction(func); // create the CFG by walking the IR CFGWalker<Flower, Visitor<Flower>, Info>::doWalkFunction(func); @@ -46,16 +51,15 @@ struct Flower : public CFGWalker<Flower, Visitor<Flower>, Info> { flow(func); } - BasicBlock* makeBasicBlock() { - return new BasicBlock(); - } + BasicBlock* makeBasicBlock() { return new BasicBlock(); } // cfg traversal work static void doVisitGetLocal(Flower* self, Expression** currp) { auto* curr = (*currp)->cast<GetLocal>(); - // if in unreachable code, skip - if (!self->currBasicBlock) return; + // if in unreachable code, skip + if (!self->currBasicBlock) + return; self->currBasicBlock->contents.actions.emplace_back(curr); self->locations[curr] = currp; } @@ -63,27 +67,32 @@ struct Flower : public CFGWalker<Flower, Visitor<Flower>, Info> { static void doVisitSetLocal(Flower* self, Expression** currp) { auto* curr = (*currp)->cast<SetLocal>(); // if in unreachable code, skip - if (!self->currBasicBlock) return; + if (!self->currBasicBlock) + return; self->currBasicBlock->contents.actions.emplace_back(curr); self->currBasicBlock->contents.lastSets[curr->index] = curr; self->locations[curr] = currp; } void flow(Function* func) { - // This block struct is optimized for this flow process (Minimal information, iteration index). + // This block struct is optimized for this flow process (Minimal + // information, iteration index). struct FlowBlock { - // Last Traversed Iteration: This value helps us to find if this block has been seen while traversing blocks. - // We compare this value to the current iteration index in order to determine if we already process this block in the current iteration. - // This speeds up the processing compared to unordered_set or other struct usage. (No need to reset internal values, lookup into container, ...) + // Last Traversed Iteration: This value helps us to find if this block has + // been seen while traversing blocks. We compare this value to the current + // iteration index in order to determine if we already process this block + // in the current iteration. This speeds up the processing compared to + // unordered_set or other struct usage. (No need to reset internal values, + // lookup into container, ...) size_t lastTraversedIteration; std::vector<Expression*> actions; std::vector<FlowBlock*> in; // Sor each index, the last local.set for it // The unordered_map from BasicBlock.Info is converted into a vector - // This speeds up search as there are usually few sets in a block, so just scanning - // them linearly is efficient, avoiding hash computations (while in Info, - // it's convenient to have a map so we can assign them easily, where - // the last one seen overwrites the previous; and, we do that O(1)). + // This speeds up search as there are usually few sets in a block, so just + // scanning them linearly is efficient, avoiding hash computations (while + // in Info, it's convenient to have a map so we can assign them easily, + // where the last one seen overwrites the previous; and, we do that O(1)). std::vector<std::pair<Index, SetLocal*>> lastSets; }; @@ -92,7 +101,8 @@ struct Flower : public CFGWalker<Flower, Visitor<Flower>, Info> { allGets.resize(numLocals); std::vector<FlowBlock*> work; - // Convert input blocks (basicBlocks) into more efficient flow blocks to improve memory access. + // Convert input blocks (basicBlocks) into more efficient flow blocks to + // improve memory access. std::vector<FlowBlock> flowBlocks; flowBlocks.resize(basicBlocks.size()); @@ -109,15 +119,17 @@ struct Flower : public CFGWalker<Flower, Visitor<Flower>, Info> { auto& block = basicBlocks[i]; auto& flowBlock = flowBlocks[i]; // Get the equivalent block to entry in the flow list - if (block.get() == entry) entryFlowBlock = &flowBlock; + if (block.get() == entry) + entryFlowBlock = &flowBlock; flowBlock.lastTraversedIteration = NULL_ITERATION; flowBlock.actions.swap(block->contents.actions); // Map in block to flow blocks auto& in = block->in; flowBlock.in.resize(in.size()); - std::transform(in.begin(), in.end(), flowBlock.in.begin(), [&](BasicBlock* block) { - return basicToFlowMap[block]; - }); + std::transform(in.begin(), + in.end(), + flowBlock.in.begin(), + [&](BasicBlock* block) { return basicToFlowMap[block]; }); // Convert unordered_map to vector. flowBlock.lastSets.reserve(block->contents.lastSets.size()); for (auto set : block->contents.lastSets) { @@ -159,7 +171,8 @@ struct Flower : public CFGWalker<Flower, Visitor<Flower>, Info> { // can do that for all gets as a whole, they will get the same results. for (Index index = 0; index < numLocals; index++) { auto& gets = allGets[index]; - if (gets.empty()) continue; + if (gets.empty()) + continue; work.push_back(&block); // Note that we may need to revisit the later parts of this initial // block, if we are in a loop, so don't mark it as seen. @@ -182,9 +195,12 @@ struct Flower : public CFGWalker<Flower, Visitor<Flower>, Info> { continue; } pred->lastTraversedIteration = currentIteration; - auto lastSet = std::find_if(pred->lastSets.begin(), pred->lastSets.end(), [&](std::pair<Index, SetLocal*>& value) { - return value.first == index; - }); + auto lastSet = + std::find_if(pred->lastSets.begin(), + pred->lastSets.end(), + [&](std::pair<Index, SetLocal*>& value) { + return value.first == index; + }); if (lastSet != pred->lastSets.end()) { // There is a set here, apply it, and stop the flow. for (auto* get : gets) { @@ -271,9 +287,6 @@ void LocalGraph::computeSSAIndexes() { } } -bool LocalGraph::isSSA(Index x) { - return SSAIndexes.count(x); -} +bool LocalGraph::isSSA(Index x) { return SSAIndexes.count(x); } } // namespace wasm - |