diff options
author | Alon Zakai <azakai@google.com> | 2024-09-10 09:53:32 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-10 09:53:32 -0700 |
commit | 2467e70524c96481c34e5ac23b9f068eb60abcbf (patch) | |
tree | d3b96a2d0ee01862c742cba24775b6dd15c80cf1 /src | |
parent | 0b07c1b125715ec599c01e182db6729d550bd329 (diff) | |
download | binaryen-2467e70524c96481c34e5ac23b9f068eb60abcbf.tar.gz binaryen-2467e70524c96481c34e5ac23b9f068eb60abcbf.tar.bz2 binaryen-2467e70524c96481c34e5ac23b9f068eb60abcbf.zip |
[NFC] Make LazyLocalGraph even lazier (#6919)
Do not even construct the Flower helper class until we actually need it.
This avoids even scanning the function and building the internal CFG if
we never get any API call that needs it.
This speeds up LICM by 50% (as now we never construct the CFG if we
don't find a loop), and Stack IR-enabled binary writing by 10% (as many
functions do not have locals in positions that can be optimized using
LocalGraph).
This moves |locations| from the base class to LocalGraph. It is not
needed in the lazy version, so that makes sense for now (we can't keep
it in the base, as then it would need to be mutable, which only makes
sense for laziness).
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/LocalGraph.cpp | 15 | ||||
-rw-r--r-- | src/ir/local-graph.h | 17 |
2 files changed, 26 insertions, 6 deletions
diff --git a/src/ir/LocalGraph.cpp b/src/ir/LocalGraph.cpp index 11965040c..af1370731 100644 --- a/src/ir/LocalGraph.cpp +++ b/src/ir/LocalGraph.cpp @@ -552,7 +552,14 @@ bool LocalGraph::isSSA(Index x) { return SSAIndexes.count(x); } // LazyLocalGraph LazyLocalGraph::LazyLocalGraph(Function* func, Module* module) - : LocalGraphBase(func, module) { + : LocalGraphBase(func, module) {} + +void LazyLocalGraph::makeFlower() const { + // Lazy graphs do not provide |locations| publicly. TODO: perhaps refactor to + // avoid filling in this dummy data structure, but we may want to add a lazy + // version of it too, so see which makes sense first. + LocalGraph::Locations locations; + flower = std::make_unique<LocalGraphFlower>(getSetsMap, locations, func, module); @@ -578,10 +585,16 @@ LazyLocalGraph::~LazyLocalGraph() { } void LazyLocalGraph::computeGetSets(LocalGet* get) const { + if (!flower) { + makeFlower(); + } flower->computeGetSets(get); } void LazyLocalGraph::computeSetInfluences(LocalSet* set) const { + if (!flower) { + makeFlower(); + } flower->computeSetInfluences(set, setInfluences); } diff --git a/src/ir/local-graph.h b/src/ir/local-graph.h index 7fe9adedc..46bc135e0 100644 --- a/src/ir/local-graph.h +++ b/src/ir/local-graph.h @@ -58,11 +58,8 @@ public: // get. Typically only one or two apply there, so this is a small set. using Sets = SmallSet<LocalSet*, 2>; - // Where each get and set is. We compute this while doing the main computation - // and make it accessible for users, for easy replacing of things without - // extra work. + // Where each get and set is. using Locations = std::map<Expression*, Expression**>; - Locations locations; // A map of each get to the sets relevant to it (i.e., that it can read from). using GetSetsMap = std::unordered_map<LocalGet*, Sets>; @@ -104,6 +101,11 @@ struct LocalGraph : public LocalGraphBase { return iter->second; } + // We compute the locations of gets and sets while doing the main computation + // and make it accessible for users, for easy replacing of things without + // extra work. + Locations locations; + // Checks if two gets are equivalent, that is, definitely have the same // value. bool equivalent(LocalGet* a, LocalGet* b); @@ -213,7 +215,12 @@ private: void computeSetInfluences(LocalSet* set) const; // This remains alive as long as we are, so that we can compute things lazily. - std::unique_ptr<LocalGraphFlower> flower; + // It is mutable as when we construct this is an internal detail, that does + // not cause observable differences in API calls. + mutable std::unique_ptr<LocalGraphFlower> flower; + + // We create |flower| lazily. + void makeFlower() const; }; } // namespace wasm |