From a054285f31fbf332de2230e727a844b86090dc21 Mon Sep 17 00:00:00 2001 From: chriseth <chris@ethereum.org> Date: Wed, 16 Mar 2022 16:43:21 +0100 Subject: [PATCH] Simplify rematerialization candidates. --- libyul/optimiser/StackCompressor.cpp | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index eb0629258..b3402e4d7 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -61,16 +61,15 @@ public: /// @returns a map from function name to rematerialisation costs to a vector of variables to rematerialise /// and variables that occur in their expression. /// While the map is sorted by cost, the contained vectors are sorted by the order of occurrence. - map<YulString, map<size_t, vector<tuple<YulString, set<YulString>>>>> candidates() + map<YulString, map<size_t, vector<YulString>>> candidates() { - map<YulString, map<size_t, vector<tuple<YulString, set<YulString>>>>> cand; + map<YulString, map<size_t, vector<YulString>>> cand; for (auto const& [functionName, candidate]: m_candidates) { if (size_t const* cost = util::valueOrNullptr(m_expressionCodeCost, candidate)) { size_t numRef = m_numReferences[candidate]; - set<YulString> const* ref = references(candidate); - cand[functionName][*cost * numRef].emplace_back(candidate, ref ? move(*ref) : set<YulString>{}); + cand[functionName][*cost * numRef].emplace_back(candidate); } } return cand; @@ -144,25 +143,16 @@ public: /// Selects at most @a _numVariables among @a _candidates. set<YulString> chooseVarsToEliminate( - map<size_t, vector<tuple<YulString, set<YulString>>>> const& _candidates, + map<size_t, vector<YulString>> const& _candidates, size_t _numVariables ) { set<YulString> varsToEliminate; for (auto&& [cost, candidates]: _candidates) - for (auto&& [candidate, references]: candidates) + for (auto&& candidate: candidates) { if (varsToEliminate.size() >= _numVariables) return varsToEliminate; - // If a variable we would like to eliminate references another one - // we already selected for elimination, then stop selecting - // candidates. If we would add that variable, then the cost calculation - // for the previous variable would be off. Furthermore, we - // do not skip the variable because it would be better to properly re-compute - // the costs of all other variables instead. - for (YulString const& referencedVar: references) - if (varsToEliminate.count(referencedVar)) - return varsToEliminate; varsToEliminate.insert(candidate); } return varsToEliminate; @@ -177,7 +167,7 @@ void eliminateVariables( { RematCandidateSelector selector{_dialect}; selector(_ast); - map<YulString, map<size_t, vector<tuple<YulString, set<YulString>>>>> candidates = selector.candidates(); + map<YulString, map<size_t, vector<YulString>>> candidates = selector.candidates(); set<YulString> varsToEliminate; for (auto const& [functionName, numVariables]: _numVariables) @@ -209,7 +199,7 @@ void eliminateVariablesOptimizedCodegen( for (auto const& [functionName, candidatesInFunction]: selector.candidates()) for (auto [cost, candidatesWithCost]: candidatesInFunction) for (auto candidate: candidatesWithCost) - candidates[get<0>(candidate)] = cost; + candidates[candidate] = cost; set<YulString> varsToEliminate;