diff options
author | Alon Zakai <azakai@google.com> | 2024-09-04 14:47:19 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-04 14:47:19 -0700 |
commit | 0812ad3564ab802db5c2df7f0fe9fdb22709a535 (patch) | |
tree | 6ad2dabc342652f2fcc48bb7bc92ffba211ed021 /src | |
parent | 9671b985aca3ce8ee18e7886229ba03c02e73fac (diff) | |
download | binaryen-0812ad3564ab802db5c2df7f0fe9fdb22709a535.tar.gz binaryen-0812ad3564ab802db5c2df7f0fe9fdb22709a535.tar.bz2 binaryen-0812ad3564ab802db5c2df7f0fe9fdb22709a535.zip |
[NFC] Convert LocalGraph influences accesses to function calls (#6899)
This replaces direct access of the data structure graph.*influences[foo] with a call
graph.get*influences(foo). This will allow a later PR to make those calls optionally
lazy.
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/local-graph.h | 30 | ||||
-rw-r--r-- | src/passes/Heap2Local.cpp | 20 | ||||
-rw-r--r-- | src/passes/MergeLocals.cpp | 8 | ||||
-rw-r--r-- | src/passes/OptimizeAddedConstants.cpp | 2 | ||||
-rw-r--r-- | src/passes/Precompute.cpp | 4 | ||||
-rw-r--r-- | src/passes/SSAify.cpp | 2 | ||||
-rw-r--r-- | src/passes/Souperify.cpp | 4 | ||||
-rw-r--r-- | src/wasm/wasm-stack-opts.cpp | 2 |
8 files changed, 40 insertions, 32 deletions
diff --git a/src/ir/local-graph.h b/src/ir/local-graph.h index 8ff4ee3be..17cc6ff31 100644 --- a/src/ir/local-graph.h +++ b/src/ir/local-graph.h @@ -74,7 +74,8 @@ struct LocalGraph { bool equivalent(LocalGet* a, LocalGet* b); // Optional: compute the influence graphs between sets and gets (useful for - // algorithms that propagate changes). + // algorithms that propagate changes). Set influences are the gets that can + // read from it; get influences are the sets that can (directly) read from it. void computeSetInfluences(); void computeGetInfluences(); @@ -83,11 +84,27 @@ struct LocalGraph { computeGetInfluences(); } - // for each get, the sets whose values are influenced by that get - using GetInfluences = std::unordered_set<LocalSet*>; - std::unordered_map<LocalGet*, GetInfluences> getInfluences; using SetInfluences = std::unordered_set<LocalGet*>; - std::unordered_map<LocalSet*, SetInfluences> setInfluences; + using GetInfluences = std::unordered_set<LocalSet*>; + + const SetInfluences& getSetInfluences(LocalSet* set) const { + auto iter = setInfluences.find(set); + if (iter == setInfluences.end()) { + // Use a canonical constant empty set to avoid allocation. + static const SetInfluences empty; + return empty; + } + return iter->second; + } + const GetInfluences& getGetInfluences(LocalGet* get) const { + auto iter = getInfluences.find(get); + if (iter == getInfluences.end()) { + // Use a canonical constant empty set to avoid allocation. + static const GetInfluences empty; + return empty; + } + return iter->second; + } // Optional: Compute the local indexes that are SSA, in the sense of // * a single set for all the gets for that local index @@ -132,6 +149,9 @@ private: // with that. It could alternatively be a shared_ptr, but that runs into what // seems to be a false positive of clang's (but not gcc's) UBSan. std::unique_ptr<LocalGraphFlower> flower; + + std::unordered_map<LocalSet*, SetInfluences> setInfluences; + std::unordered_map<LocalGet*, GetInfluences> getInfluences; }; } // namespace wasm diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index 80700118a..82a5e90bb 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -279,10 +279,8 @@ struct EscapeAnalyzer { sets.insert(set); // We must also look at how the value flows from those gets. - if (auto* getsReached = getGetsReached(set)) { - for (auto* get : *getsReached) { - flows.push({get, parents.getParent(get)}); - } + for (auto* get : localGraph.getSetInfluences(set)) { + flows.push({get, parents.getParent(get)}); } } @@ -479,14 +477,6 @@ struct EscapeAnalyzer { return ParentChildInteraction::Mixes; } - const LocalGraph::SetInfluences* getGetsReached(LocalSet* set) { - auto iter = localGraph.setInfluences.find(set); - if (iter != localGraph.setInfluences.end()) { - return &iter->second; - } - return nullptr; - } - const BranchUtils::NameSet branchesSentByParent(Expression* child, Expression* parent) { BranchUtils::NameSet names; @@ -508,10 +498,8 @@ struct EscapeAnalyzer { // Find all the relevant gets (which may overlap between the sets). std::unordered_set<LocalGet*> gets; for (auto* set : sets) { - if (auto* getsReached = getGetsReached(set)) { - for (auto* get : *getsReached) { - gets.insert(get); - } + for (auto* get : localGraph.getSetInfluences(set)) { + gets.insert(get); } } diff --git a/src/passes/MergeLocals.cpp b/src/passes/MergeLocals.cpp index b04215d73..e6cf71538 100644 --- a/src/passes/MergeLocals.cpp +++ b/src/passes/MergeLocals.cpp @@ -115,7 +115,7 @@ struct MergeLocals for (auto* copy : copies) { auto* trivial = copy->value->cast<LocalSet>(); bool canOptimizeToCopy = false; - auto& trivialInfluences = preGraph.setInfluences[trivial]; + auto& trivialInfluences = preGraph.getSetInfluences(trivial); if (!trivialInfluences.empty()) { canOptimizeToCopy = true; for (auto* influencedGet : trivialInfluences) { @@ -156,7 +156,7 @@ struct MergeLocals // if the trivial set we added has influences, it means $y lives on if (!trivialInfluences.empty()) { - auto& copyInfluences = preGraph.setInfluences[copy]; + auto& copyInfluences = preGraph.getSetInfluences(copy); if (!copyInfluences.empty()) { bool canOptimizeToTrivial = true; for (auto* influencedGet : copyInfluences) { @@ -198,7 +198,7 @@ struct MergeLocals LocalGraph postGraph(func, getModule()); postGraph.computeSetInfluences(); for (auto& [copy, trivial] : optimizedToCopy) { - auto& trivialInfluences = preGraph.setInfluences[trivial]; + auto& trivialInfluences = preGraph.getSetInfluences(trivial); for (auto* influencedGet : trivialInfluences) { // verify the set auto& sets = postGraph.getSets(influencedGet); @@ -212,7 +212,7 @@ struct MergeLocals } } for (auto& [copy, trivial] : optimizedToTrivial) { - auto& copyInfluences = preGraph.setInfluences[copy]; + auto& copyInfluences = preGraph.getSetInfluences(copy); for (auto* influencedGet : copyInfluences) { // verify the set auto& sets = postGraph.getSets(influencedGet); diff --git a/src/passes/OptimizeAddedConstants.cpp b/src/passes/OptimizeAddedConstants.cpp index af5d48be7..8efbcca26 100644 --- a/src/passes/OptimizeAddedConstants.cpp +++ b/src/passes/OptimizeAddedConstants.cpp @@ -359,7 +359,7 @@ private: if (add->left->is<Const>() || add->right->is<Const>()) { // Looks like this might be relevant, check all uses. bool canPropagate = true; - for (auto* get : localGraph->setInfluences[set]) { + for (auto* get : localGraph->getSetInfluences(set)) { auto* parent = parents.getParent(get); // if this is at the top level, it's the whole body - no set can // exist! diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index 61220ece8..0d2df04d7 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -802,7 +802,7 @@ private: } setValues[set] = values; if (values.isConcrete()) { - for (auto* get : localGraph.setInfluences[set]) { + for (auto* get : localGraph.getSetInfluences(set)) { work.push(get); } } @@ -861,7 +861,7 @@ private: if (values.isConcrete()) { // we did! getValues[get] = values; - for (auto* set : localGraph.getInfluences[get]) { + for (auto* set : localGraph.getGetInfluences(get)) { work.push(set); } propagated = true; diff --git a/src/passes/SSAify.cpp b/src/passes/SSAify.cpp index 0a9c6891d..c220fdd06 100644 --- a/src/passes/SSAify.cpp +++ b/src/passes/SSAify.cpp @@ -120,7 +120,7 @@ struct SSAify : public Pass { } bool hasMerges(LocalSet* set, LocalGraph& graph) { - for (auto* get : graph.setInfluences[set]) { + for (auto* get : graph.getSetInfluences(set)) { if (graph.getSets(get).size() > 1) { return true; } diff --git a/src/passes/Souperify.cpp b/src/passes/Souperify.cpp index 913a58e81..826c3f350 100644 --- a/src/passes/Souperify.cpp +++ b/src/passes/Souperify.cpp @@ -90,7 +90,7 @@ struct UseFinder { return; } // Find all the uses of that set. - auto& gets = localGraph.setInfluences[set]; + auto& gets = localGraph.getSetInfluences(set); if (debug() >= 2) { std::cout << "addSetUses for " << set << ", " << gets.size() << " gets\n"; } @@ -98,7 +98,7 @@ struct UseFinder { // Each of these relevant gets is either // (1) a child of a set, which we can track, or // (2) not a child of a set, e.g., a call argument or such - auto& sets = localGraph.getInfluences[get]; // TODO: iterator + auto& sets = localGraph.getGetInfluences(get); // TODO: iterator // In flat IR, each get can influence at most 1 set. assert(sets.size() <= 1); if (sets.size() == 0) { diff --git a/src/wasm/wasm-stack-opts.cpp b/src/wasm/wasm-stack-opts.cpp index 5902b40a5..a39b82b98 100644 --- a/src/wasm/wasm-stack-opts.cpp +++ b/src/wasm/wasm-stack-opts.cpp @@ -227,7 +227,7 @@ void StackIROptimizer::local2Stack() { // used by this get and nothing else, check that. auto& sets = localGraph.getSets(get); if (sets.size() == 1 && *sets.begin() == set) { - auto& setInfluences = localGraph.setInfluences[set]; + auto& setInfluences = localGraph.getSetInfluences(set); // If this has the proper value of 1, also do the potentially- // expensive check of whether we can remove this pair at all. if (setInfluences.size() == 1 && |