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 <libsolutil/CommonData.h>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/range/algorithm_ext/erase.hpp> #include <boost/range/algorithm_ext/erase.hpp>
#include <variant> #include <variant>
@ -104,16 +103,14 @@ void DataFlowAnalyzer::operator()(Assignment& _assignment)
void DataFlowAnalyzer::operator()(VariableDeclaration& _varDecl) void DataFlowAnalyzer::operator()(VariableDeclaration& _varDecl)
{ {
if (_varDecl.value)
clearKnowledgeIfInvalidated(*_varDecl.value);
Scoper::operator()(_varDecl);
set<YulString> names; set<YulString> names;
for (auto const& var: _varDecl.variables) for (auto const& var: _varDecl.variables)
names.emplace(var.name); names.emplace(var.name);
m_variableScopes.back().variables += names;
if (_varDecl.value)
{
clearKnowledgeIfInvalidated(*_varDecl.value);
visit(*_varDecl.value);
}
handleAssignment(names, _varDecl.value.get(), true); handleAssignment(names, _varDecl.value.get(), true);
} }
@ -171,22 +168,15 @@ void DataFlowAnalyzer::operator()(FunctionDefinition& _fun)
swap(m_references, references); swap(m_references, references);
swap(m_storage, storage); swap(m_storage, storage);
swap(m_memory, memory); 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) for (auto const& var: _fun.returnVariables)
{
m_variableScopes.back().variables.emplace(var.name);
handleAssignment({var.name}, nullptr, true); handleAssignment({var.name}, nullptr, true);
}
ASTModifier::operator()(_fun); Scoper::operator()(_fun);
// Note that the contents of return variables, storage and memory at this point // 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`` // might be incorrect due to the fact that the DataFlowAnalyzer ignores the ``leave``
// statement. // statement.
popScope();
swap(m_value, value); swap(m_value, value);
swap(m_loopDepth, loopDepth); swap(m_loopDepth, loopDepth);
swap(m_references, references); swap(m_references, references);
@ -228,14 +218,6 @@ void DataFlowAnalyzer::operator()(ForLoop& _for)
--m_loopDepth; --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) 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() void DataFlowAnalyzer::popScope()
{ {
clearValues(std::move(m_variableScopes.back().variables)); clearValues(std::move(m_variableScopes.back().variables));
@ -396,18 +373,6 @@ void DataFlowAnalyzer::joinKnowledgeHelper(
_this.eraseKey(key); _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( std::optional<pair<YulString, YulString>> DataFlowAnalyzer::isSimpleStore(
StoreLoadLocation _location, StoreLoadLocation _location,
ExpressionStatement const& _statement ExpressionStatement const& _statement
@ -432,4 +397,3 @@ std::optional<YulString> DataFlowAnalyzer::isSimpleLoad(
return key->name; return key->name;
return {}; return {};
} }

View File

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