From 0bb233f1c0048074fc6e05973f68f260e2befea6 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 20 Dec 2022 14:58:35 +0100 Subject: [PATCH] implement inves --- libyul/optimiser/DataFlowAnalyzer.cpp | 19 ++++++++++++++++--- libyul/optimiser/DataFlowAnalyzer.h | 4 +++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index 81028e300..32cbe1217 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -271,7 +271,17 @@ void DataFlowAnalyzer::handleAssignment(set const& _variables, Expres auto const& referencedVariables = movableChecker.referencedVariables(); for (auto const& name: _variables) { + // TODO these might be interdependent and it could matter which order we + // run this loop! + if (!_isDeclaration) + { + for (YulString v: m_state.references[name]) + m_state.referencedBy[v].erase(name); + } + for (YulString v: referencedVariables) + m_state.referencedBy[v].insert(name); m_state.references[name] = referencedVariables; + if (!_isDeclaration) { // assignment to slot denoted by "name" @@ -316,6 +326,8 @@ void DataFlowAnalyzer::popScope() for (auto const& name: m_variableScopes.back().variables) { m_state.value.erase(name); + for (YulString v: m_state.references[name]) + m_state.referencedBy[v].erase(name); m_state.references.erase(name); } m_variableScopes.pop_back(); @@ -351,16 +363,17 @@ void DataFlowAnalyzer::clearValues(set _variables) _variables.count(_item.second); }); + // Use referencedBy // Also clear variables that reference variables to be cleared. for (auto const& variableToClear: _variables) - for (auto const& [ref, names]: m_state.references) - if (names.count(variableToClear)) - _variables.emplace(ref); + _variables += m_state.referencedBy[variableToClear]; // Clear the value and update the reference relation. for (auto const& name: _variables) { m_state.value.erase(name); + for (YulString v: m_state.references[name]) + m_state.referencedBy[v].erase(name); m_state.references.erase(name); } } diff --git a/libyul/optimiser/DataFlowAnalyzer.h b/libyul/optimiser/DataFlowAnalyzer.h index b449357e6..e0a387cbc 100644 --- a/libyul/optimiser/DataFlowAnalyzer.h +++ b/libyul/optimiser/DataFlowAnalyzer.h @@ -179,8 +179,10 @@ private: { /// Current values of variables, always movable. std::map value; - /// m_references[a].contains(b) <=> the current expression assigned to a references b + /// references[a].contains(b) <=> the current expression assigned to a references b std::unordered_map> references; + /// The inverse of references. + std::unordered_map> referencedBy; Environment environment; };