Replaced code for assigning scopes with the class Scoper

This commit is contained in:
hrkrshnn 2020-12-28 22:51:14 +01:00
parent c9ed116621
commit a4aa2639d0
2 changed files with 10 additions and 60 deletions

View File

@ -30,7 +30,6 @@
#include <libsolutil/CommonData.h>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/range/algorithm_ext/erase.hpp>
#include <variant>
@ -104,16 +103,14 @@ void DataFlowAnalyzer::operator()(Assignment& _assignment)
void DataFlowAnalyzer::operator()(VariableDeclaration& _varDecl)
{
if (_varDecl.value)
clearKnowledgeIfInvalidated(*_varDecl.value);
Scoper::operator()(_varDecl);
set<YulString> names;
for (auto const& var: _varDecl.variables)
names.emplace(var.name);
m_variableScopes.back().variables += names;
if (_varDecl.value)
{
clearKnowledgeIfInvalidated(*_varDecl.value);
visit(*_varDecl.value);
}
handleAssignment(names, _varDecl.value.get(), true);
}
@ -171,22 +168,15 @@ void DataFlowAnalyzer::operator()(FunctionDefinition& _fun)
swap(m_references, references);
swap(m_storage, storage);
swap(m_memory, memory);
pushScope(true);
for (auto const& parameter: _fun.parameters)
m_variableScopes.back().variables.emplace(parameter.name);
for (auto const& var: _fun.returnVariables)
{
m_variableScopes.back().variables.emplace(var.name);
handleAssignment({var.name}, nullptr, true);
}
ASTModifier::operator()(_fun);
Scoper::operator()(_fun);
// Note that the contents of return variables, storage and memory at this point
// might be incorrect due to the fact that the DataFlowAnalyzer ignores the ``leave``
// statement.
popScope();
swap(m_value, value);
swap(m_loopDepth, loopDepth);
swap(m_references, references);
@ -228,14 +218,6 @@ void DataFlowAnalyzer::operator()(ForLoop& _for)
--m_loopDepth;
}
void DataFlowAnalyzer::operator()(Block& _block)
{
size_t numScopes = m_variableScopes.size();
pushScope(false);
ASTModifier::operator()(_block);
popScope();
assertThrow(numScopes == m_variableScopes.size(), OptimizerException, "");
}
void DataFlowAnalyzer::handleAssignment(set<YulString> const& _variables, Expression* _value, bool _isDeclaration)
{
@ -291,11 +273,6 @@ void DataFlowAnalyzer::handleAssignment(set<YulString> const& _variables, Expres
}
}
void DataFlowAnalyzer::pushScope(bool _functionScope)
{
m_variableScopes.emplace_back(_functionScope);
}
void DataFlowAnalyzer::popScope()
{
clearValues(std::move(m_variableScopes.back().variables));
@ -396,18 +373,6 @@ void DataFlowAnalyzer::joinKnowledgeHelper(
_this.eraseKey(key);
}
bool DataFlowAnalyzer::inScope(YulString _variableName) const
{
for (auto const& scope: m_variableScopes | boost::adaptors::reversed)
{
if (scope.variables.count(_variableName))
return true;
if (scope.isFunction)
return false;
}
return false;
}
std::optional<pair<YulString, YulString>> DataFlowAnalyzer::isSimpleStore(
StoreLoadLocation _location,
ExpressionStatement const& _statement
@ -432,4 +397,3 @@ std::optional<YulString> DataFlowAnalyzer::isSimpleLoad(
return key->name;
return {};
}

View File

@ -23,6 +23,7 @@
#pragma once
#include <libyul/optimiser/Scoper.h>
#include <libyul/optimiser/ASTWalker.h>
#include <libyul/optimiser/KnowledgeBase.h>
#include <libyul/YulString.h>
@ -76,7 +77,7 @@ struct AssignedValue
*
* Prerequisite: Disambiguator, ForLoopInitRewriter.
*/
class DataFlowAnalyzer: public ASTModifier
class DataFlowAnalyzer: public Scoper
{
public:
/// @param _functionSideEffects
@ -96,17 +97,13 @@ public:
void operator()(Switch& _switch) override;
void operator()(FunctionDefinition&) override;
void operator()(ForLoop&) override;
void operator()(Block& _block) override;
protected:
/// Registers the assignment.
void handleAssignment(std::set<YulString> const& _names, Expression* _value, bool _isDeclaration);
/// Creates a new inner scope.
void pushScope(bool _functionScope);
/// Removes the innermost scope and clears all variables in it.
void popScope();
void popScope() override;
/// Clears information about the values assigned to the given variables,
/// for example at points where control flow is merged.
@ -133,9 +130,6 @@ protected:
InvertibleMap<YulString, YulString> const& _olderData
);
/// Returns true iff the variable is in scope.
bool inScope(YulString _variableName) const;
enum class StoreLoadLocation {
Memory = 0,
Storage = 1,
@ -178,17 +172,9 @@ protected:
/// Current nesting depth of loops.
size_t m_loopDepth{0};
struct Scope
{
explicit Scope(bool _isFunction): isFunction(_isFunction) {}
std::set<YulString> variables;
bool isFunction;
};
/// Special expression whose address will be used in m_value.
/// YulString does not need to be reset because DataFlowAnalyzer is short-lived.
Expression const m_zero{Literal{{}, LiteralKind::Number, YulString{"0"}, {}}};
/// List of scopes.
std::vector<Scope> m_variableScopes;
};
}