mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Replaced code for assigning scopes with the class Scoper
This commit is contained in:
parent
c9ed116621
commit
a4aa2639d0
@ -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 {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user