implement inves

This commit is contained in:
chriseth 2022-12-20 14:58:35 +01:00
parent fff91b676d
commit 0bb233f1c0
2 changed files with 19 additions and 4 deletions

View File

@ -271,7 +271,17 @@ void DataFlowAnalyzer::handleAssignment(set<YulString> 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<YulString> _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);
}
}

View File

@ -179,8 +179,10 @@ private:
{
/// Current values of variables, always movable.
std::map<YulString, AssignedValue> 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<YulString, std::set<YulString>> references;
/// The inverse of references.
std::unordered_map<YulString, std::set<YulString>> referencedBy;
Environment environment;
};