mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into merge_develop_060
This commit is contained in:
@@ -133,12 +133,12 @@ Statement ASTCopier::operator ()(Block const& _block)
|
||||
|
||||
Expression ASTCopier::translate(Expression const& _expression)
|
||||
{
|
||||
return _expression.apply_visitor(static_cast<ExpressionCopier&>(*this));
|
||||
return std::visit(static_cast<ExpressionCopier&>(*this), _expression);
|
||||
}
|
||||
|
||||
Statement ASTCopier::translate(Statement const& _statement)
|
||||
{
|
||||
return _statement.apply_visitor(static_cast<StatementCopier&>(*this));
|
||||
return std::visit(static_cast<StatementCopier&>(*this), _statement);
|
||||
}
|
||||
|
||||
Block ASTCopier::translate(Block const& _block)
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
#include <libyul/YulString.h>
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
@@ -34,7 +32,7 @@
|
||||
namespace yul
|
||||
{
|
||||
|
||||
class ExpressionCopier: public boost::static_visitor<Expression>
|
||||
class ExpressionCopier
|
||||
{
|
||||
public:
|
||||
virtual ~ExpressionCopier() = default;
|
||||
@@ -43,7 +41,7 @@ public:
|
||||
virtual Expression operator()(FunctionCall const&) = 0;
|
||||
};
|
||||
|
||||
class StatementCopier: public boost::static_visitor<Statement>
|
||||
class StatementCopier
|
||||
{
|
||||
public:
|
||||
virtual ~StatementCopier() = default;
|
||||
|
||||
@@ -89,12 +89,12 @@ void ASTWalker::operator()(Block const& _block)
|
||||
|
||||
void ASTWalker::visit(Statement const& _st)
|
||||
{
|
||||
boost::apply_visitor(*this, _st);
|
||||
std::visit(*this, _st);
|
||||
}
|
||||
|
||||
void ASTWalker::visit(Expression const& _e)
|
||||
{
|
||||
boost::apply_visitor(*this, _e);
|
||||
std::visit(*this, _e);
|
||||
}
|
||||
|
||||
void ASTModifier::operator()(FunctionCall& _funCall)
|
||||
@@ -170,10 +170,10 @@ void ASTModifier::operator()(Block& _block)
|
||||
|
||||
void ASTModifier::visit(Statement& _st)
|
||||
{
|
||||
boost::apply_visitor(*this, _st);
|
||||
std::visit(*this, _st);
|
||||
}
|
||||
|
||||
void ASTModifier::visit(Expression& _e)
|
||||
{
|
||||
boost::apply_visitor(*this, _e);
|
||||
std::visit(*this, _e);
|
||||
}
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#include <libyul/Exceptions.h>
|
||||
#include <libyul/YulString.h>
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
@@ -38,7 +36,7 @@ namespace yul
|
||||
/**
|
||||
* Generic AST walker.
|
||||
*/
|
||||
class ASTWalker: public boost::static_visitor<>
|
||||
class ASTWalker
|
||||
{
|
||||
public:
|
||||
virtual ~ASTWalker() = default;
|
||||
@@ -72,7 +70,7 @@ protected:
|
||||
/**
|
||||
* Generic AST modifier (i.e. non-const version of ASTWalker).
|
||||
*/
|
||||
class ASTModifier: public boost::static_visitor<>
|
||||
class ASTModifier
|
||||
{
|
||||
public:
|
||||
virtual ~ASTModifier() = default;
|
||||
|
||||
@@ -32,8 +32,8 @@ void BlockFlattener::operator()(Block& _block)
|
||||
_block.statements,
|
||||
[](Statement& _s) -> std::optional<vector<Statement>>
|
||||
{
|
||||
if (_s.type() == typeid(Block))
|
||||
return std::move(boost::get<Block>(_s).statements);
|
||||
if (holds_alternative<Block>(_s))
|
||||
return std::move(std::get<Block>(_s).statements);
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -56,8 +56,8 @@ void CommonSubexpressionEliminator::visit(Expression& _e)
|
||||
bool descend = true;
|
||||
// If this is a function call to a function that requires literal arguments,
|
||||
// do not try to simplify there.
|
||||
if (_e.type() == typeid(FunctionCall))
|
||||
if (BuiltinFunction const* builtin = m_dialect.builtin(boost::get<FunctionCall>(_e).functionName.name))
|
||||
if (holds_alternative<FunctionCall>(_e))
|
||||
if (BuiltinFunction const* builtin = m_dialect.builtin(std::get<FunctionCall>(_e).functionName.name))
|
||||
if (builtin->literalArguments)
|
||||
// We should not modify function arguments that have to be literals
|
||||
// Note that replacing the function call entirely is fine,
|
||||
@@ -72,16 +72,16 @@ void CommonSubexpressionEliminator::visit(Expression& _e)
|
||||
if (descend)
|
||||
DataFlowAnalyzer::visit(_e);
|
||||
|
||||
if (_e.type() == typeid(Identifier))
|
||||
if (holds_alternative<Identifier>(_e))
|
||||
{
|
||||
Identifier& identifier = boost::get<Identifier>(_e);
|
||||
Identifier& identifier = std::get<Identifier>(_e);
|
||||
YulString name = identifier.name;
|
||||
if (m_value.count(name))
|
||||
{
|
||||
assertThrow(m_value.at(name), OptimizerException, "");
|
||||
if (m_value.at(name)->type() == typeid(Identifier))
|
||||
if (holds_alternative<Identifier>(*m_value.at(name)))
|
||||
{
|
||||
YulString value = boost::get<Identifier>(*m_value.at(name)).name;
|
||||
YulString value = std::get<Identifier>(*m_value.at(name)).name;
|
||||
assertThrow(inScope(value), OptimizerException, "");
|
||||
_e = Identifier{locationOf(_e), value};
|
||||
}
|
||||
|
||||
@@ -29,12 +29,12 @@ using namespace yul;
|
||||
void ConditionalSimplifier::operator()(Switch& _switch)
|
||||
{
|
||||
visit(*_switch.expression);
|
||||
if (_switch.expression->type() != typeid(Identifier))
|
||||
if (!holds_alternative<Identifier>(*_switch.expression))
|
||||
{
|
||||
ASTModifier::operator()(_switch);
|
||||
return;
|
||||
}
|
||||
YulString expr = boost::get<Identifier>(*_switch.expression).name;
|
||||
YulString expr = std::get<Identifier>(*_switch.expression).name;
|
||||
for (auto& _case: _switch.cases)
|
||||
{
|
||||
if (_case.value)
|
||||
@@ -59,17 +59,17 @@ void ConditionalSimplifier::operator()(Block& _block)
|
||||
[&](Statement& _s) -> std::optional<vector<Statement>>
|
||||
{
|
||||
visit(_s);
|
||||
if (_s.type() == typeid(If))
|
||||
if (holds_alternative<If>(_s))
|
||||
{
|
||||
If& _if = boost::get<If>(_s);
|
||||
If& _if = std::get<If>(_s);
|
||||
if (
|
||||
_if.condition->type() == typeid(Identifier) &&
|
||||
holds_alternative<Identifier>(*_if.condition) &&
|
||||
!_if.body.statements.empty() &&
|
||||
TerminationFinder(m_dialect).controlFlowKind(_if.body.statements.back()) !=
|
||||
TerminationFinder::ControlFlow::FlowOut
|
||||
)
|
||||
{
|
||||
YulString condition = boost::get<Identifier>(*_if.condition).name;
|
||||
YulString condition = std::get<Identifier>(*_if.condition).name;
|
||||
langutil::SourceLocation location = _if.location;
|
||||
return make_vector<Statement>(
|
||||
std::move(_s),
|
||||
|
||||
@@ -29,12 +29,12 @@ using namespace yul;
|
||||
void ConditionalUnsimplifier::operator()(Switch& _switch)
|
||||
{
|
||||
visit(*_switch.expression);
|
||||
if (_switch.expression->type() != typeid(Identifier))
|
||||
if (!holds_alternative<Identifier>(*_switch.expression))
|
||||
{
|
||||
ASTModifier::operator()(_switch);
|
||||
return;
|
||||
}
|
||||
YulString expr = boost::get<Identifier>(*_switch.expression).name;
|
||||
YulString expr = std::get<Identifier>(*_switch.expression).name;
|
||||
for (auto& _case: _switch.cases)
|
||||
{
|
||||
if (_case.value)
|
||||
@@ -42,15 +42,15 @@ void ConditionalUnsimplifier::operator()(Switch& _switch)
|
||||
(*this)(*_case.value);
|
||||
if (
|
||||
!_case.body.statements.empty() &&
|
||||
_case.body.statements.front().type() == typeid(Assignment)
|
||||
holds_alternative<Assignment>(_case.body.statements.front())
|
||||
)
|
||||
{
|
||||
Assignment const& assignment = boost::get<Assignment>(_case.body.statements.front());
|
||||
Assignment const& assignment = std::get<Assignment>(_case.body.statements.front());
|
||||
if (
|
||||
assignment.variableNames.size() == 1 &&
|
||||
assignment.variableNames.front().name == expr &&
|
||||
assignment.value->type() == typeid(Literal) &&
|
||||
valueOfLiteral(boost::get<Literal>(*assignment.value)) == valueOfLiteral(*_case.value)
|
||||
holds_alternative<Literal>(*assignment.value) &&
|
||||
valueOfLiteral(std::get<Literal>(*assignment.value)) == valueOfLiteral(*_case.value)
|
||||
)
|
||||
_case.body.statements.erase(_case.body.statements.begin());
|
||||
}
|
||||
@@ -66,27 +66,27 @@ void ConditionalUnsimplifier::operator()(Block& _block)
|
||||
_block.statements,
|
||||
[&](Statement& _stmt1, Statement& _stmt2) -> std::optional<vector<Statement>>
|
||||
{
|
||||
if (_stmt1.type() == typeid(If))
|
||||
if (holds_alternative<If>(_stmt1))
|
||||
{
|
||||
If& _if = boost::get<If>(_stmt1);
|
||||
If& _if = std::get<If>(_stmt1);
|
||||
if (
|
||||
_if.condition->type() == typeid(Identifier) &&
|
||||
holds_alternative<Identifier>(*_if.condition) &&
|
||||
!_if.body.statements.empty()
|
||||
)
|
||||
{
|
||||
YulString condition = boost::get<Identifier>(*_if.condition).name;
|
||||
YulString condition = std::get<Identifier>(*_if.condition).name;
|
||||
if (
|
||||
_stmt2.type() == typeid(Assignment) &&
|
||||
holds_alternative<Assignment>(_stmt2) &&
|
||||
TerminationFinder(m_dialect).controlFlowKind(_if.body.statements.back()) !=
|
||||
TerminationFinder::ControlFlow::FlowOut
|
||||
)
|
||||
{
|
||||
Assignment const& assignment = boost::get<Assignment>(_stmt2);
|
||||
Assignment const& assignment = std::get<Assignment>(_stmt2);
|
||||
if (
|
||||
assignment.variableNames.size() == 1 &&
|
||||
assignment.variableNames.front().name == condition &&
|
||||
assignment.value->type() == typeid(Literal) &&
|
||||
valueOfLiteral(boost::get<Literal>(*assignment.value)) == 0
|
||||
holds_alternative<Literal>(*assignment.value) &&
|
||||
valueOfLiteral(std::get<Literal>(*assignment.value)) == 0
|
||||
)
|
||||
return {make_vector<Statement>(std::move(_stmt1))};
|
||||
}
|
||||
|
||||
@@ -145,9 +145,9 @@ void ControlFlowSimplifier::operator()(FunctionDefinition& _funDef)
|
||||
|
||||
void ControlFlowSimplifier::visit(Statement& _st)
|
||||
{
|
||||
if (_st.type() == typeid(ForLoop))
|
||||
if (holds_alternative<ForLoop>(_st))
|
||||
{
|
||||
ForLoop& forLoop = boost::get<ForLoop>(_st);
|
||||
ForLoop& forLoop = std::get<ForLoop>(_st);
|
||||
yulAssert(forLoop.pre.statements.empty(), "");
|
||||
|
||||
size_t outerBreak = m_numBreakStatements;
|
||||
@@ -221,7 +221,7 @@ void ControlFlowSimplifier::simplify(std::vector<yul::Statement>& _statements)
|
||||
_statements,
|
||||
[&](Statement& _stmt) -> OptionalStatements
|
||||
{
|
||||
OptionalStatements result = boost::apply_visitor(visitor, _stmt);
|
||||
OptionalStatements result = std::visit(visitor, _stmt);
|
||||
if (result)
|
||||
simplify(*result);
|
||||
else
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
#include <boost/range/algorithm_ext/erase.hpp>
|
||||
#include <variant>
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
@@ -368,19 +369,19 @@ std::optional<pair<YulString, YulString>> DataFlowAnalyzer::isSimpleStore(
|
||||
_store == dev::eth::Instruction::SSTORE,
|
||||
""
|
||||
);
|
||||
if (_statement.expression.type() == typeid(FunctionCall))
|
||||
if (holds_alternative<FunctionCall>(_statement.expression))
|
||||
{
|
||||
FunctionCall const& funCall = boost::get<FunctionCall>(_statement.expression);
|
||||
FunctionCall const& funCall = std::get<FunctionCall>(_statement.expression);
|
||||
if (EVMDialect const* dialect = dynamic_cast<EVMDialect const*>(&m_dialect))
|
||||
if (auto const* builtin = dialect->builtin(funCall.functionName.name))
|
||||
if (builtin->instruction == _store)
|
||||
if (
|
||||
funCall.arguments.at(0).type() == typeid(Identifier) &&
|
||||
funCall.arguments.at(1).type() == typeid(Identifier)
|
||||
holds_alternative<Identifier>(funCall.arguments.at(0)) &&
|
||||
holds_alternative<Identifier>(funCall.arguments.at(1))
|
||||
)
|
||||
{
|
||||
YulString key = boost::get<Identifier>(funCall.arguments.at(0)).name;
|
||||
YulString value = boost::get<Identifier>(funCall.arguments.at(1)).name;
|
||||
YulString key = std::get<Identifier>(funCall.arguments.at(0)).name;
|
||||
YulString value = std::get<Identifier>(funCall.arguments.at(1)).name;
|
||||
return make_pair(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ void DeadCodeEliminator::operator()(Block& _block)
|
||||
remove_if(
|
||||
_block.statements.begin() + index + 1,
|
||||
_block.statements.end(),
|
||||
[] (Statement const& _s) { return _s.type() != typeid(yul::FunctionDefinition); }
|
||||
[] (Statement const& _s) { return !holds_alternative<yul::FunctionDefinition>(_s); }
|
||||
),
|
||||
_block.statements.end()
|
||||
);
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#include <libyul/optimiser/ASTCopier.h>
|
||||
#include <libyul/optimiser/NameDispenser.h>
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
#include <optional>
|
||||
#include <set>
|
||||
|
||||
|
||||
@@ -49,9 +49,9 @@ void ExpressionInliner::operator()(FunctionDefinition& _fun)
|
||||
void ExpressionInliner::visit(Expression& _expression)
|
||||
{
|
||||
ASTModifier::visit(_expression);
|
||||
if (_expression.type() == typeid(FunctionCall))
|
||||
if (holds_alternative<FunctionCall>(_expression))
|
||||
{
|
||||
FunctionCall& funCall = boost::get<FunctionCall>(_expression);
|
||||
FunctionCall& funCall = std::get<FunctionCall>(_expression);
|
||||
if (!m_inlinableFunctions.count(funCall.functionName.name))
|
||||
return;
|
||||
FunctionDefinition const& fun = *m_inlinableFunctions.at(funCall.functionName.name);
|
||||
@@ -74,6 +74,6 @@ void ExpressionInliner::visit(Expression& _expression)
|
||||
substitutions[paraName] = &arg;
|
||||
}
|
||||
|
||||
_expression = Substitution(substitutions).translate(*boost::get<Assignment>(fun.body.statements.front()).value);
|
||||
_expression = Substitution(substitutions).translate(*std::get<Assignment>(fun.body.statements.front()).value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,7 @@
|
||||
#include <libyul/optimiser/ASTWalker.h>
|
||||
#include <libyul/AsmDataForward.h>
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace yul
|
||||
|
||||
@@ -61,12 +61,12 @@ void ExpressionJoiner::operator()(Block& _block)
|
||||
|
||||
void ExpressionJoiner::visit(Expression& _e)
|
||||
{
|
||||
if (_e.type() == typeid(Identifier))
|
||||
if (holds_alternative<Identifier>(_e))
|
||||
{
|
||||
Identifier const& identifier = boost::get<Identifier>(_e);
|
||||
Identifier const& identifier = std::get<Identifier>(_e);
|
||||
if (isLatestStatementVarDeclJoinable(identifier))
|
||||
{
|
||||
VariableDeclaration& varDecl = boost::get<VariableDeclaration>(*latestStatement());
|
||||
VariableDeclaration& varDecl = std::get<VariableDeclaration>(*latestStatement());
|
||||
_e = std::move(*varDecl.value);
|
||||
|
||||
// Delete the variable declaration (also get the moved-from structure back into a sane state)
|
||||
@@ -96,7 +96,7 @@ void ExpressionJoiner::handleArguments(vector<Expression>& _arguments)
|
||||
for (Expression const& arg: _arguments | boost::adaptors::reversed)
|
||||
{
|
||||
--i;
|
||||
if (arg.type() != typeid(Identifier) && arg.type() != typeid(Literal))
|
||||
if (!holds_alternative<Identifier>(arg) && !holds_alternative<Literal>(arg))
|
||||
break;
|
||||
}
|
||||
// i points to the last element that is neither an identifier nor a literal,
|
||||
@@ -133,9 +133,9 @@ Statement* ExpressionJoiner::latestStatement()
|
||||
bool ExpressionJoiner::isLatestStatementVarDeclJoinable(Identifier const& _identifier)
|
||||
{
|
||||
Statement const* statement = latestStatement();
|
||||
if (!statement || statement->type() != typeid(VariableDeclaration))
|
||||
if (!statement || !holds_alternative<VariableDeclaration>(*statement))
|
||||
return false;
|
||||
VariableDeclaration const& varDecl = boost::get<VariableDeclaration>(*statement);
|
||||
VariableDeclaration const& varDecl = std::get<VariableDeclaration>(*statement);
|
||||
if (varDecl.variables.size() != 1 || !varDecl.value)
|
||||
return false;
|
||||
assertThrow(varDecl.variables.size() == 1, OptimizerException, "");
|
||||
|
||||
@@ -95,7 +95,7 @@ void ExpressionSplitter::operator()(Block& _block)
|
||||
|
||||
void ExpressionSplitter::outlineExpression(Expression& _expr)
|
||||
{
|
||||
if (_expr.type() == typeid(Identifier))
|
||||
if (holds_alternative<Identifier>(_expr))
|
||||
return;
|
||||
|
||||
visit(_expr);
|
||||
|
||||
@@ -33,8 +33,8 @@ void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop)
|
||||
{
|
||||
if (
|
||||
m_dialect.booleanNegationFunction() &&
|
||||
_forLoop.condition->type() != typeid(Literal) &&
|
||||
_forLoop.condition->type() != typeid(Identifier)
|
||||
!holds_alternative<Literal>(*_forLoop.condition) &&
|
||||
!holds_alternative<Identifier>(*_forLoop.condition)
|
||||
)
|
||||
{
|
||||
langutil::SourceLocation const loc = locationOf(*_forLoop.condition);
|
||||
|
||||
@@ -36,17 +36,17 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop)
|
||||
|
||||
if (
|
||||
!m_dialect.booleanNegationFunction() ||
|
||||
_forLoop.condition->type() != typeid(Literal) ||
|
||||
valueOfLiteral(boost::get<Literal>(*_forLoop.condition)) == u256(0) ||
|
||||
!holds_alternative<Literal>(*_forLoop.condition) ||
|
||||
valueOfLiteral(std::get<Literal>(*_forLoop.condition)) == u256(0) ||
|
||||
_forLoop.body.statements.empty() ||
|
||||
_forLoop.body.statements.front().type() != typeid(If)
|
||||
!holds_alternative<If>(_forLoop.body.statements.front())
|
||||
)
|
||||
return;
|
||||
|
||||
If& firstStatement = boost::get<If>(_forLoop.body.statements.front());
|
||||
If& firstStatement = std::get<If>(_forLoop.body.statements.front());
|
||||
if (
|
||||
firstStatement.body.statements.empty() ||
|
||||
firstStatement.body.statements.front().type() != typeid(Break)
|
||||
!holds_alternative<Break>(firstStatement.body.statements.front())
|
||||
)
|
||||
return;
|
||||
if (!SideEffectsCollector(m_dialect, *firstStatement.condition).movable())
|
||||
@@ -56,10 +56,10 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop)
|
||||
langutil::SourceLocation location = locationOf(*firstStatement.condition);
|
||||
|
||||
if (
|
||||
firstStatement.condition->type() == typeid(FunctionCall) &&
|
||||
boost::get<FunctionCall>(*firstStatement.condition).functionName.name == iszero
|
||||
holds_alternative<FunctionCall>(*firstStatement.condition) &&
|
||||
std::get<FunctionCall>(*firstStatement.condition).functionName.name == iszero
|
||||
)
|
||||
_forLoop.condition = make_unique<Expression>(std::move(boost::get<FunctionCall>(*firstStatement.condition).arguments.front()));
|
||||
_forLoop.condition = make_unique<Expression>(std::move(std::get<FunctionCall>(*firstStatement.condition).arguments.front()));
|
||||
else
|
||||
_forLoop.condition = make_unique<Expression>(FunctionCall{
|
||||
location,
|
||||
|
||||
@@ -29,9 +29,9 @@ void ForLoopInitRewriter::operator()(Block& _block)
|
||||
_block.statements,
|
||||
[&](Statement& _stmt) -> std::optional<vector<Statement>>
|
||||
{
|
||||
if (_stmt.type() == typeid(ForLoop))
|
||||
if (holds_alternative<ForLoop>(_stmt))
|
||||
{
|
||||
auto& forLoop = boost::get<ForLoop>(_stmt);
|
||||
auto& forLoop = std::get<ForLoop>(_stmt);
|
||||
(*this)(forLoop.pre);
|
||||
(*this)(forLoop.body);
|
||||
(*this)(forLoop.post);
|
||||
|
||||
@@ -51,7 +51,7 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser):
|
||||
SSAValueTracker tracker;
|
||||
tracker(m_ast);
|
||||
for (auto const& ssaValue: tracker.values())
|
||||
if (ssaValue.second && ssaValue.second->type() == typeid(Literal))
|
||||
if (ssaValue.second && holds_alternative<Literal>(*ssaValue.second))
|
||||
m_constants.emplace(ssaValue.first);
|
||||
|
||||
// Store size of global statements.
|
||||
@@ -59,9 +59,9 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser):
|
||||
map<YulString, size_t> references = ReferencesCounter::countReferences(m_ast);
|
||||
for (auto& statement: m_ast.statements)
|
||||
{
|
||||
if (statement.type() != typeid(FunctionDefinition))
|
||||
if (!holds_alternative<FunctionDefinition>(statement))
|
||||
continue;
|
||||
FunctionDefinition& fun = boost::get<FunctionDefinition>(statement);
|
||||
FunctionDefinition& fun = std::get<FunctionDefinition>(statement);
|
||||
m_functions[fun.name] = &fun;
|
||||
if (LeaveFinder::containsLeave(fun))
|
||||
m_noInlineFunctions.insert(fun.name);
|
||||
@@ -75,8 +75,8 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser):
|
||||
void FullInliner::run()
|
||||
{
|
||||
for (auto& statement: m_ast.statements)
|
||||
if (statement.type() == typeid(Block))
|
||||
handleBlock({}, boost::get<Block>(statement));
|
||||
if (holds_alternative<Block>(statement))
|
||||
handleBlock({}, std::get<Block>(statement));
|
||||
|
||||
// TODO it might be good to determine a visiting order:
|
||||
// first handle functions that are called from many places.
|
||||
@@ -115,9 +115,9 @@ bool FullInliner::shallInline(FunctionCall const& _funCall, YulString _callSite)
|
||||
// Constant arguments might provide a means for further optimization, so they cause a bonus.
|
||||
bool constantArg = false;
|
||||
for (auto const& argument: _funCall.arguments)
|
||||
if (argument.type() == typeid(Literal) || (
|
||||
argument.type() == typeid(Identifier) &&
|
||||
m_constants.count(boost::get<Identifier>(argument).name)
|
||||
if (holds_alternative<Literal>(argument) || (
|
||||
holds_alternative<Identifier>(argument) &&
|
||||
m_constants.count(std::get<Identifier>(argument).name)
|
||||
))
|
||||
{
|
||||
constantArg = true;
|
||||
@@ -160,7 +160,7 @@ void InlineModifier::operator()(Block& _block)
|
||||
std::optional<vector<Statement>> InlineModifier::tryInlineStatement(Statement& _statement)
|
||||
{
|
||||
// Only inline for expression statements, assignments and variable declarations.
|
||||
Expression* e = boost::apply_visitor(GenericFallbackReturnsVisitor<Expression*, ExpressionStatement, Assignment, VariableDeclaration>(
|
||||
Expression* e = std::visit(GenericFallbackReturnsVisitor<Expression*, ExpressionStatement, Assignment, VariableDeclaration>(
|
||||
[](ExpressionStatement& _s) { return &_s.expression; },
|
||||
[](Assignment& _s) { return _s.value.get(); },
|
||||
[](VariableDeclaration& _s) { return _s.value.get(); }
|
||||
@@ -168,7 +168,7 @@ std::optional<vector<Statement>> InlineModifier::tryInlineStatement(Statement& _
|
||||
if (e)
|
||||
{
|
||||
// Only inline direct function calls.
|
||||
FunctionCall* funCall = boost::apply_visitor(GenericFallbackReturnsVisitor<FunctionCall*, FunctionCall&>(
|
||||
FunctionCall* funCall = std::visit(GenericFallbackReturnsVisitor<FunctionCall*, FunctionCall&>(
|
||||
[](FunctionCall& _e) { return &_e; }
|
||||
), *e);
|
||||
if (funCall && m_driver.shallInline(*funCall, m_currentFunction))
|
||||
@@ -206,9 +206,9 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
|
||||
newVariable(var, nullptr);
|
||||
|
||||
Statement newBody = BodyCopier(m_nameDispenser, variableReplacements)(function->body);
|
||||
newStatements += std::move(boost::get<Block>(newBody).statements);
|
||||
newStatements += std::move(std::get<Block>(newBody).statements);
|
||||
|
||||
boost::apply_visitor(GenericFallbackVisitor<Assignment, VariableDeclaration>{
|
||||
std::visit(GenericFallbackVisitor<Assignment, VariableDeclaration>{
|
||||
[&](Assignment& _assignment)
|
||||
{
|
||||
for (size_t i = 0; i < _assignment.variableNames.size(); ++i)
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
|
||||
#include <liblangutil/SourceLocation.h>
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
#include <optional>
|
||||
#include <set>
|
||||
|
||||
|
||||
@@ -40,10 +40,10 @@ void FunctionGrouper::operator()(Block& _block)
|
||||
|
||||
for (auto&& statement: _block.statements)
|
||||
{
|
||||
if (statement.type() == typeid(FunctionDefinition))
|
||||
if (holds_alternative<FunctionDefinition>(statement))
|
||||
reordered.emplace_back(std::move(statement));
|
||||
else
|
||||
boost::get<Block>(reordered.front()).statements.emplace_back(std::move(statement));
|
||||
std::get<Block>(reordered.front()).statements.emplace_back(std::move(statement));
|
||||
}
|
||||
_block.statements = std::move(reordered);
|
||||
}
|
||||
@@ -52,10 +52,10 @@ bool FunctionGrouper::alreadyGrouped(Block const& _block)
|
||||
{
|
||||
if (_block.statements.empty())
|
||||
return false;
|
||||
if (_block.statements.front().type() != typeid(Block))
|
||||
if (!holds_alternative<Block>(_block.statements.front()))
|
||||
return false;
|
||||
for (size_t i = 1; i < _block.statements.size(); ++i)
|
||||
if (_block.statements.at(i).type() != typeid(FunctionDefinition))
|
||||
if (!holds_alternative<FunctionDefinition>(_block.statements.at(i)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ void FunctionHoister::operator()(Block& _block)
|
||||
m_isTopLevel = false;
|
||||
for (auto&& statement: _block.statements)
|
||||
{
|
||||
boost::apply_visitor(*this, statement);
|
||||
if (statement.type() == typeid(FunctionDefinition))
|
||||
std::visit(*this, statement);
|
||||
if (holds_alternative<FunctionDefinition>(statement))
|
||||
{
|
||||
m_functions.emplace_back(std::move(statement));
|
||||
statement = Block{_block.location, {}};
|
||||
|
||||
@@ -45,9 +45,9 @@ void InlinableExpressionFunctionFinder::operator()(FunctionDefinition const& _fu
|
||||
{
|
||||
YulString retVariable = _function.returnVariables.front().name;
|
||||
Statement const& bodyStatement = _function.body.statements.front();
|
||||
if (bodyStatement.type() == typeid(Assignment))
|
||||
if (holds_alternative<Assignment>(bodyStatement))
|
||||
{
|
||||
Assignment const& assignment = boost::get<Assignment>(bodyStatement);
|
||||
Assignment const& assignment = std::get<Assignment>(bodyStatement);
|
||||
if (assignment.variableNames.size() == 1 && assignment.variableNames.front().name == retVariable)
|
||||
{
|
||||
// TODO: use code size metric here
|
||||
@@ -57,7 +57,7 @@ void InlinableExpressionFunctionFinder::operator()(FunctionDefinition const& _fu
|
||||
// function body.
|
||||
assertThrow(m_disallowedIdentifiers.empty() && !m_foundDisallowedIdentifier, OptimizerException, "");
|
||||
m_disallowedIdentifiers = set<YulString>{retVariable, _function.name};
|
||||
boost::apply_visitor(*this, *assignment.value);
|
||||
std::visit(*this, *assignment.value);
|
||||
if (!m_foundDisallowedIdentifier)
|
||||
m_inlinableFunctions[_function.name] = &_function;
|
||||
m_disallowedIdentifiers.clear();
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
|
||||
#include <libdevcore/CommonData.h>
|
||||
|
||||
#include <variant>
|
||||
|
||||
using namespace std;
|
||||
using namespace yul;
|
||||
using namespace dev;
|
||||
|
||||
@@ -37,12 +40,12 @@ bool KnowledgeBase::knownToBeDifferent(YulString _a, YulString _b)
|
||||
// If that fails, try `eq(_a, _b)`.
|
||||
|
||||
Expression expr1 = simplify(FunctionCall{{}, {{}, "sub"_yulstring}, make_vector<Expression>(Identifier{{}, _a}, Identifier{{}, _b})});
|
||||
if (expr1.type() == typeid(Literal))
|
||||
return valueOfLiteral(boost::get<Literal>(expr1)) != 0;
|
||||
if (holds_alternative<Literal>(expr1))
|
||||
return valueOfLiteral(std::get<Literal>(expr1)) != 0;
|
||||
|
||||
Expression expr2 = simplify(FunctionCall{{}, {{}, "eq"_yulstring}, make_vector<Expression>(Identifier{{}, _a}, Identifier{{}, _b})});
|
||||
if (expr2.type() == typeid(Literal))
|
||||
return valueOfLiteral(boost::get<Literal>(expr2)) == 0;
|
||||
if (holds_alternative<Literal>(expr2))
|
||||
return valueOfLiteral(std::get<Literal>(expr2)) == 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -53,9 +56,9 @@ bool KnowledgeBase::knownToBeDifferentByAtLeast32(YulString _a, YulString _b)
|
||||
// current values to turn `sub(_a, _b)` into a constant whose absolute value is at least 32.
|
||||
|
||||
Expression expr1 = simplify(FunctionCall{{}, {{}, "sub"_yulstring}, make_vector<Expression>(Identifier{{}, _a}, Identifier{{}, _b})});
|
||||
if (expr1.type() == typeid(Literal))
|
||||
if (holds_alternative<Literal>(expr1))
|
||||
{
|
||||
u256 val = valueOfLiteral(boost::get<Literal>(expr1));
|
||||
u256 val = valueOfLiteral(std::get<Literal>(expr1));
|
||||
return val >= 32 && val <= u256(0) - 32;
|
||||
}
|
||||
|
||||
@@ -74,8 +77,8 @@ Expression KnowledgeBase::simplify(Expression _expression)
|
||||
else
|
||||
--m_recursionCounter;
|
||||
|
||||
if (_expression.type() == typeid(FunctionCall))
|
||||
for (Expression& arg: boost::get<FunctionCall>(_expression).arguments)
|
||||
if (holds_alternative<FunctionCall>(_expression))
|
||||
for (Expression& arg: std::get<FunctionCall>(_expression).arguments)
|
||||
arg = simplify(arg);
|
||||
|
||||
if (auto match = SimplificationRules::findFirstMatch(_expression, m_dialect, m_variableValues))
|
||||
|
||||
@@ -48,9 +48,9 @@ void LoadResolver::visit(Expression& _e)
|
||||
if (!dynamic_cast<EVMDialect const*>(&m_dialect))
|
||||
return;
|
||||
|
||||
if (_e.type() == typeid(FunctionCall))
|
||||
if (holds_alternative<FunctionCall>(_e))
|
||||
{
|
||||
FunctionCall const& funCall = boost::get<FunctionCall>(_e);
|
||||
FunctionCall const& funCall = std::get<FunctionCall>(_e);
|
||||
if (auto const* builtin = dynamic_cast<EVMDialect const&>(m_dialect).builtin(funCall.functionName.name))
|
||||
if (builtin->instruction)
|
||||
tryResolve(_e, *builtin->instruction, funCall.arguments);
|
||||
@@ -63,10 +63,10 @@ void LoadResolver::tryResolve(
|
||||
vector<Expression> const& _arguments
|
||||
)
|
||||
{
|
||||
if (_arguments.empty() || _arguments.at(0).type() != typeid(Identifier))
|
||||
if (_arguments.empty() || !holds_alternative<Identifier>(_arguments.at(0)))
|
||||
return;
|
||||
|
||||
YulString key = boost::get<Identifier>(_arguments.at(0)).name;
|
||||
YulString key = std::get<Identifier>(_arguments.at(0)).name;
|
||||
if (
|
||||
_instruction == dev::eth::Instruction::SLOAD &&
|
||||
m_storage.values.count(key)
|
||||
|
||||
@@ -35,13 +35,13 @@ using namespace yul;
|
||||
void MainFunction::operator()(Block& _block)
|
||||
{
|
||||
assertThrow(_block.statements.size() >= 1, OptimizerException, "");
|
||||
assertThrow(_block.statements[0].type() == typeid(Block), OptimizerException, "");
|
||||
assertThrow(holds_alternative<Block>(_block.statements[0]), OptimizerException, "");
|
||||
for (size_t i = 1; i < _block.statements.size(); ++i)
|
||||
assertThrow(_block.statements.at(i).type() == typeid(FunctionDefinition), OptimizerException, "");
|
||||
assertThrow(holds_alternative<FunctionDefinition>(_block.statements.at(i)), OptimizerException, "");
|
||||
/// @todo this should handle scopes properly and instead of an assertion it should rename the conflicting function
|
||||
assertThrow(NameCollector(_block).names().count("main"_yulstring) == 0, OptimizerException, "");
|
||||
|
||||
Block& block = boost::get<Block>(_block.statements[0]);
|
||||
Block& block = std::get<Block>(_block.statements[0]);
|
||||
FunctionDefinition main{
|
||||
block.location,
|
||||
"main"_yulstring,
|
||||
|
||||
@@ -65,24 +65,24 @@ size_t CodeSize::codeSizeIncludingFunctions(Block const& _block)
|
||||
|
||||
void CodeSize::visit(Statement const& _statement)
|
||||
{
|
||||
if (_statement.type() == typeid(FunctionDefinition) && m_ignoreFunctions)
|
||||
if (holds_alternative<FunctionDefinition>(_statement) && m_ignoreFunctions)
|
||||
return;
|
||||
else if (
|
||||
_statement.type() == typeid(If) ||
|
||||
_statement.type() == typeid(Break) ||
|
||||
_statement.type() == typeid(Continue) ||
|
||||
_statement.type() == typeid(Leave)
|
||||
holds_alternative<If>(_statement) ||
|
||||
holds_alternative<Break>(_statement) ||
|
||||
holds_alternative<Continue>(_statement) ||
|
||||
holds_alternative<Leave>(_statement)
|
||||
)
|
||||
m_size += 2;
|
||||
else if (_statement.type() == typeid(ForLoop))
|
||||
else if (holds_alternative<ForLoop>(_statement))
|
||||
m_size += 3;
|
||||
else if (_statement.type() == typeid(Switch))
|
||||
m_size += 1 + 2 * boost::get<Switch>(_statement).cases.size();
|
||||
else if (holds_alternative<Switch>(_statement))
|
||||
m_size += 1 + 2 * std::get<Switch>(_statement).cases.size();
|
||||
else if (!(
|
||||
_statement.type() == typeid(Block) ||
|
||||
_statement.type() == typeid(ExpressionStatement) ||
|
||||
_statement.type() == typeid(Assignment) ||
|
||||
_statement.type() == typeid(VariableDeclaration)
|
||||
holds_alternative<Block>(_statement) ||
|
||||
holds_alternative<ExpressionStatement>(_statement) ||
|
||||
holds_alternative<Assignment>(_statement) ||
|
||||
holds_alternative<VariableDeclaration>(_statement)
|
||||
))
|
||||
++m_size;
|
||||
|
||||
@@ -91,7 +91,7 @@ void CodeSize::visit(Statement const& _statement)
|
||||
|
||||
void CodeSize::visit(Expression const& _expression)
|
||||
{
|
||||
if (_expression.type() != typeid(Identifier))
|
||||
if (!holds_alternative<Identifier>(_expression))
|
||||
++m_size;
|
||||
ASTWalker::visit(_expression);
|
||||
}
|
||||
|
||||
@@ -64,8 +64,8 @@ void NameDisplacer::operator()(Block& _block)
|
||||
// First replace all the names of function definitions
|
||||
// because of scoping.
|
||||
for (auto& st: _block.statements)
|
||||
if (st.type() == typeid(FunctionDefinition))
|
||||
checkAndReplaceNew(boost::get<FunctionDefinition>(st).name);
|
||||
if (holds_alternative<FunctionDefinition>(st))
|
||||
checkAndReplaceNew(std::get<FunctionDefinition>(st).name);
|
||||
|
||||
ASTModifier::operator()(_block);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ using namespace yul;
|
||||
void yul::removeEmptyBlocks(Block& _block)
|
||||
{
|
||||
auto isEmptyBlock = [](Statement const& _st) -> bool {
|
||||
return _st.type() == typeid(Block) && boost::get<Block>(_st).statements.empty();
|
||||
return holds_alternative<Block>(_st) && std::get<Block>(_st).statements.empty();
|
||||
};
|
||||
boost::range::remove_erase_if(_block.statements, isEmptyBlock);
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ void RedundantAssignEliminator::finalize(
|
||||
void AssignmentRemover::operator()(Block& _block)
|
||||
{
|
||||
boost::range::remove_erase_if(_block.statements, [=](Statement const& _statement) -> bool {
|
||||
return _statement.type() == typeid(Assignment) && m_toRemove.count(&boost::get<Assignment>(_statement));
|
||||
return holds_alternative<Assignment>(_statement) && m_toRemove.count(&std::get<Assignment>(_statement));
|
||||
});
|
||||
|
||||
ASTModifier::operator()(_block);
|
||||
|
||||
@@ -68,9 +68,9 @@ Rematerialiser::Rematerialiser(
|
||||
|
||||
void Rematerialiser::visit(Expression& _e)
|
||||
{
|
||||
if (_e.type() == typeid(Identifier))
|
||||
if (holds_alternative<Identifier>(_e))
|
||||
{
|
||||
Identifier& identifier = boost::get<Identifier>(_e);
|
||||
Identifier& identifier = std::get<Identifier>(_e);
|
||||
YulString name = identifier.name;
|
||||
if (m_value.count(name))
|
||||
{
|
||||
@@ -96,15 +96,15 @@ void Rematerialiser::visit(Expression& _e)
|
||||
|
||||
void LiteralRematerialiser::visit(Expression& _e)
|
||||
{
|
||||
if (_e.type() == typeid(Identifier))
|
||||
if (holds_alternative<Identifier>(_e))
|
||||
{
|
||||
Identifier& identifier = boost::get<Identifier>(_e);
|
||||
Identifier& identifier = std::get<Identifier>(_e);
|
||||
YulString name = identifier.name;
|
||||
if (m_value.count(name))
|
||||
{
|
||||
Expression const* value = m_value.at(name);
|
||||
assertThrow(value, OptimizerException, "");
|
||||
if (value->type() == typeid(Literal))
|
||||
if (holds_alternative<Literal>(*value))
|
||||
_e = *value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <libyul/AsmData.h>
|
||||
#include <libdevcore/CommonData.h>
|
||||
|
||||
#include <variant>
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace yul;
|
||||
@@ -37,7 +39,7 @@ void SSAReverser::operator()(Block& _block)
|
||||
_block.statements,
|
||||
[&](Statement& _stmt1, Statement& _stmt2) -> std::optional<vector<Statement>>
|
||||
{
|
||||
auto* varDecl = boost::get<VariableDeclaration>(&_stmt1);
|
||||
auto* varDecl = std::get_if<VariableDeclaration>(&_stmt1);
|
||||
|
||||
if (!varDecl || varDecl->variables.size() != 1 || !varDecl->value)
|
||||
return {};
|
||||
@@ -48,9 +50,9 @@ void SSAReverser::operator()(Block& _block)
|
||||
// with
|
||||
// a := E
|
||||
// let a_1 := a
|
||||
if (auto* assignment = boost::get<Assignment>(&_stmt2))
|
||||
if (auto* assignment = std::get_if<Assignment>(&_stmt2))
|
||||
{
|
||||
auto* identifier = boost::get<Identifier>(assignment->value.get());
|
||||
auto* identifier = std::get_if<Identifier>(assignment->value.get());
|
||||
if (
|
||||
assignment->variableNames.size() == 1 &&
|
||||
identifier &&
|
||||
@@ -81,9 +83,9 @@ void SSAReverser::operator()(Block& _block)
|
||||
// with
|
||||
// let a := E
|
||||
// let a_1 := a
|
||||
else if (auto* varDecl2 = boost::get<VariableDeclaration>(&_stmt2))
|
||||
else if (auto* varDecl2 = std::get_if<VariableDeclaration>(&_stmt2))
|
||||
{
|
||||
auto* identifier = boost::get<Identifier>(varDecl2->value.get());
|
||||
auto* identifier = std::get_if<Identifier>(varDecl2->value.get());
|
||||
if (
|
||||
varDecl2->variables.size() == 1 &&
|
||||
identifier &&
|
||||
|
||||
@@ -60,9 +60,9 @@ void IntroduceSSA::operator()(Block& _block)
|
||||
_block.statements,
|
||||
[&](Statement& _s) -> std::optional<vector<Statement>>
|
||||
{
|
||||
if (_s.type() == typeid(VariableDeclaration))
|
||||
if (holds_alternative<VariableDeclaration>(_s))
|
||||
{
|
||||
VariableDeclaration& varDecl = boost::get<VariableDeclaration>(_s);
|
||||
VariableDeclaration& varDecl = std::get<VariableDeclaration>(_s);
|
||||
if (varDecl.value)
|
||||
visit(*varDecl.value);
|
||||
|
||||
@@ -90,12 +90,12 @@ void IntroduceSSA::operator()(Block& _block)
|
||||
make_unique<Expression>(Identifier{loc, newName})
|
||||
});
|
||||
}
|
||||
boost::get<VariableDeclaration>(statements.front()).variables = std::move(newVariables);
|
||||
std::get<VariableDeclaration>(statements.front()).variables = std::move(newVariables);
|
||||
return { std::move(statements) };
|
||||
}
|
||||
else if (_s.type() == typeid(Assignment))
|
||||
else if (holds_alternative<Assignment>(_s))
|
||||
{
|
||||
Assignment& assignment = boost::get<Assignment>(_s);
|
||||
Assignment& assignment = std::get<Assignment>(_s);
|
||||
visit(*assignment.value);
|
||||
for (auto const& var: assignment.variableNames)
|
||||
assertThrow(m_variablesToReplace.count(var.name), OptimizerException, "");
|
||||
@@ -117,7 +117,7 @@ void IntroduceSSA::operator()(Block& _block)
|
||||
make_unique<Expression>(Identifier{loc, newName})
|
||||
});
|
||||
}
|
||||
boost::get<VariableDeclaration>(statements.front()).variables = std::move(newVariables);
|
||||
std::get<VariableDeclaration>(statements.front()).variables = std::move(newVariables);
|
||||
return { std::move(statements) };
|
||||
}
|
||||
else
|
||||
@@ -228,9 +228,9 @@ void IntroduceControlFlowSSA::operator()(Block& _block)
|
||||
}
|
||||
m_variablesToReassign.clear();
|
||||
|
||||
if (_s.type() == typeid(VariableDeclaration))
|
||||
if (holds_alternative<VariableDeclaration>(_s))
|
||||
{
|
||||
VariableDeclaration& varDecl = boost::get<VariableDeclaration>(_s);
|
||||
VariableDeclaration& varDecl = std::get<VariableDeclaration>(_s);
|
||||
for (auto const& var: varDecl.variables)
|
||||
if (m_variablesToReplace.count(var.name))
|
||||
{
|
||||
@@ -238,9 +238,9 @@ void IntroduceControlFlowSSA::operator()(Block& _block)
|
||||
m_variablesInScope.insert(var.name);
|
||||
}
|
||||
}
|
||||
else if (_s.type() == typeid(Assignment))
|
||||
else if (holds_alternative<Assignment>(_s))
|
||||
{
|
||||
Assignment& assignment = boost::get<Assignment>(_s);
|
||||
Assignment& assignment = std::get<Assignment>(_s);
|
||||
for (auto const& var: assignment.variableNames)
|
||||
if (m_variablesToReplace.count(var.name))
|
||||
assignedVariables.insert(var.name);
|
||||
@@ -304,14 +304,14 @@ void PropagateValues::operator()(VariableDeclaration& _varDecl)
|
||||
if (m_variablesToReplace.count(variable))
|
||||
{
|
||||
// `let a := a_1` - regular declaration of non-SSA variable
|
||||
yulAssert(_varDecl.value->type() == typeid(Identifier), "");
|
||||
m_currentVariableValues[variable] = boost::get<Identifier>(*_varDecl.value).name;
|
||||
yulAssert(holds_alternative<Identifier>(*_varDecl.value), "");
|
||||
m_currentVariableValues[variable] = std::get<Identifier>(*_varDecl.value).name;
|
||||
m_clearAtEndOfBlock.insert(variable);
|
||||
}
|
||||
else if (_varDecl.value && _varDecl.value->type() == typeid(Identifier))
|
||||
else if (_varDecl.value && holds_alternative<Identifier>(*_varDecl.value))
|
||||
{
|
||||
// `let a_1 := a` - assignment to SSA variable after a branch.
|
||||
YulString value = boost::get<Identifier>(*_varDecl.value).name;
|
||||
YulString value = std::get<Identifier>(*_varDecl.value).name;
|
||||
if (m_variablesToReplace.count(value))
|
||||
{
|
||||
// This is safe because `a_1` is not a "variable to replace" and thus
|
||||
@@ -333,8 +333,8 @@ void PropagateValues::operator()(Assignment& _assignment)
|
||||
if (!m_variablesToReplace.count(name))
|
||||
return;
|
||||
|
||||
yulAssert(_assignment.value && _assignment.value->type() == typeid(Identifier), "");
|
||||
m_currentVariableValues[name] = boost::get<Identifier>(*_assignment.value).name;
|
||||
yulAssert(_assignment.value && holds_alternative<Identifier>(*_assignment.value), "");
|
||||
m_currentVariableValues[name] = std::get<Identifier>(*_assignment.value).name;
|
||||
m_clearAtEndOfBlock.insert(name);
|
||||
}
|
||||
|
||||
|
||||
@@ -150,13 +150,13 @@ pair<TerminationFinder::ControlFlow, size_t> TerminationFinder::firstUncondition
|
||||
TerminationFinder::ControlFlow TerminationFinder::controlFlowKind(Statement const& _statement)
|
||||
{
|
||||
if (
|
||||
_statement.type() == typeid(ExpressionStatement) &&
|
||||
isTerminatingBuiltin(boost::get<ExpressionStatement>(_statement))
|
||||
holds_alternative<ExpressionStatement>(_statement) &&
|
||||
isTerminatingBuiltin(std::get<ExpressionStatement>(_statement))
|
||||
)
|
||||
return ControlFlow::Terminate;
|
||||
else if (_statement.type() == typeid(Break))
|
||||
else if (holds_alternative<Break>(_statement))
|
||||
return ControlFlow::Break;
|
||||
else if (_statement.type() == typeid(Continue))
|
||||
else if (holds_alternative<Continue>(_statement))
|
||||
return ControlFlow::Continue;
|
||||
else if (_statement.type() == typeid(Leave))
|
||||
return ControlFlow::Leave;
|
||||
@@ -166,9 +166,9 @@ TerminationFinder::ControlFlow TerminationFinder::controlFlowKind(Statement cons
|
||||
|
||||
bool TerminationFinder::isTerminatingBuiltin(ExpressionStatement const& _exprStmnt)
|
||||
{
|
||||
if (_exprStmnt.expression.type() == typeid(FunctionCall))
|
||||
if (holds_alternative<FunctionCall>(_exprStmnt.expression))
|
||||
if (auto const* dialect = dynamic_cast<EVMDialect const*>(&m_dialect))
|
||||
if (auto const* builtin = dialect->builtin(boost::get<FunctionCall>(_exprStmnt.expression).functionName.name))
|
||||
if (auto const* builtin = dialect->builtin(std::get<FunctionCall>(_exprStmnt.expression).functionName.name))
|
||||
if (builtin->instruction)
|
||||
return eth::SemanticInformation::terminatesControlFlow(*builtin->instruction);
|
||||
return false;
|
||||
|
||||
@@ -67,11 +67,11 @@ bool SimplificationRules::isInitialized() const
|
||||
std::optional<std::pair<dev::eth::Instruction, vector<Expression> const*>>
|
||||
SimplificationRules::instructionAndArguments(Dialect const& _dialect, Expression const& _expr)
|
||||
{
|
||||
if (_expr.type() == typeid(FunctionCall))
|
||||
if (holds_alternative<FunctionCall>(_expr))
|
||||
if (auto const* dialect = dynamic_cast<EVMDialect const*>(&_dialect))
|
||||
if (auto const* builtin = dialect->builtin(boost::get<FunctionCall>(_expr).functionName.name))
|
||||
if (auto const* builtin = dialect->builtin(std::get<FunctionCall>(_expr).functionName.name))
|
||||
if (builtin->instruction)
|
||||
return make_pair(*builtin->instruction, &boost::get<FunctionCall>(_expr).arguments);
|
||||
return make_pair(*builtin->instruction, &std::get<FunctionCall>(_expr).arguments);
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -134,9 +134,9 @@ bool Pattern::matches(
|
||||
|
||||
// Resolve the variable if possible.
|
||||
// Do not do it for "Any" because we can check identity better for variables.
|
||||
if (m_kind != PatternKind::Any && _expr.type() == typeid(Identifier))
|
||||
if (m_kind != PatternKind::Any && holds_alternative<Identifier>(_expr))
|
||||
{
|
||||
YulString varName = boost::get<Identifier>(_expr).name;
|
||||
YulString varName = std::get<Identifier>(_expr).name;
|
||||
if (_ssaValues.count(varName))
|
||||
if (Expression const* new_expr = _ssaValues.at(varName))
|
||||
expr = new_expr;
|
||||
@@ -145,9 +145,9 @@ bool Pattern::matches(
|
||||
|
||||
if (m_kind == PatternKind::Constant)
|
||||
{
|
||||
if (expr->type() != typeid(Literal))
|
||||
if (!holds_alternative<Literal>(*expr))
|
||||
return false;
|
||||
Literal const& literal = boost::get<Literal>(*expr);
|
||||
Literal const& literal = std::get<Literal>(*expr);
|
||||
if (literal.kind != LiteralKind::Number)
|
||||
return false;
|
||||
if (m_data && *m_data != u256(literal.value.str()))
|
||||
@@ -238,7 +238,7 @@ Expression Pattern::toExpression(SourceLocation const& _location) const
|
||||
|
||||
u256 Pattern::d() const
|
||||
{
|
||||
return valueOfNumberLiteral(boost::get<Literal>(matchGroupValue()));
|
||||
return valueOfNumberLiteral(std::get<Literal>(matchGroupValue()));
|
||||
}
|
||||
|
||||
Expression const& Pattern::matchGroupValue() const
|
||||
|
||||
@@ -85,9 +85,9 @@ public:
|
||||
// get called on left-hand-sides of assignments.
|
||||
void visit(Expression& _e) override
|
||||
{
|
||||
if (_e.type() == typeid(Identifier))
|
||||
if (holds_alternative<Identifier>(_e))
|
||||
{
|
||||
YulString name = boost::get<Identifier>(_e).name;
|
||||
YulString name = std::get<Identifier>(_e).name;
|
||||
if (m_expressionCodeCost.count(name))
|
||||
{
|
||||
if (!m_value.count(name))
|
||||
@@ -162,7 +162,7 @@ bool StackCompressor::run(
|
||||
{
|
||||
yulAssert(
|
||||
_object.code &&
|
||||
_object.code->statements.size() > 0 && _object.code->statements.at(0).type() == typeid(Block),
|
||||
_object.code->statements.size() > 0 && holds_alternative<Block>(_object.code->statements.at(0)),
|
||||
"Need to run the function grouper before the stack compressor."
|
||||
);
|
||||
bool allowMSizeOptimzation = !MSizeFinder::containsMSize(_dialect, *_object.code);
|
||||
@@ -177,7 +177,7 @@ bool StackCompressor::run(
|
||||
yulAssert(stackSurplus.at({}) > 0, "Invalid surplus value.");
|
||||
eliminateVariables(
|
||||
_dialect,
|
||||
boost::get<Block>(_object.code->statements.at(0)),
|
||||
std::get<Block>(_object.code->statements.at(0)),
|
||||
stackSurplus.at({}),
|
||||
allowMSizeOptimzation
|
||||
);
|
||||
@@ -185,7 +185,7 @@ bool StackCompressor::run(
|
||||
|
||||
for (size_t i = 1; i < _object.code->statements.size(); ++i)
|
||||
{
|
||||
FunctionDefinition& fun = boost::get<FunctionDefinition>(_object.code->statements[i]);
|
||||
FunctionDefinition& fun = std::get<FunctionDefinition>(_object.code->statements[i]);
|
||||
if (!stackSurplus.count(fun.name))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ void StructuralSimplifier::simplify(std::vector<yul::Statement>& _statements)
|
||||
_statements,
|
||||
[&](Statement& _stmt) -> OptionalStatements
|
||||
{
|
||||
OptionalStatements result = boost::apply_visitor(visitor, _stmt);
|
||||
OptionalStatements result = std::visit(visitor, _stmt);
|
||||
if (result)
|
||||
simplify(*result);
|
||||
else
|
||||
@@ -123,8 +123,8 @@ bool StructuralSimplifier::expressionAlwaysFalse(Expression const& _expression)
|
||||
|
||||
std::optional<dev::u256> StructuralSimplifier::hasLiteralValue(Expression const& _expression) const
|
||||
{
|
||||
if (_expression.type() == typeid(Literal))
|
||||
return valueOfLiteral(boost::get<Literal>(_expression));
|
||||
if (holds_alternative<Literal>(_expression))
|
||||
return valueOfLiteral(std::get<Literal>(_expression));
|
||||
else
|
||||
return std::optional<u256>();
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ using namespace yul;
|
||||
|
||||
Expression Substitution::translate(Expression const& _expression)
|
||||
{
|
||||
if (_expression.type() == typeid(Identifier))
|
||||
if (holds_alternative<Identifier>(_expression))
|
||||
{
|
||||
YulString name = boost::get<Identifier>(_expression).name;
|
||||
YulString name = std::get<Identifier>(_expression).name;
|
||||
if (m_substitutions.count(name))
|
||||
// No recursive substitution
|
||||
return ASTCopier().translate(*m_substitutions.at(name));
|
||||
|
||||
@@ -80,7 +80,7 @@ void OptimiserSuite::run(
|
||||
set<YulString> reservedIdentifiers = _externallyUsedIdentifiers;
|
||||
reservedIdentifiers += _dialect.fixedFunctionNames();
|
||||
|
||||
*_object.code = boost::get<Block>(Disambiguator(
|
||||
*_object.code = std::get<Block>(Disambiguator(
|
||||
_dialect,
|
||||
*_object.analysisInfo,
|
||||
reservedIdentifiers
|
||||
@@ -291,7 +291,7 @@ void OptimiserSuite::run(
|
||||
{
|
||||
// If the first statement is an empty block, remove it.
|
||||
// We should only have function definitions after that.
|
||||
if (ast.statements.size() > 1 && boost::get<Block>(ast.statements.front()).statements.empty())
|
||||
if (ast.statements.size() > 1 && std::get<Block>(ast.statements.front()).statements.empty())
|
||||
ast.statements.erase(ast.statements.begin());
|
||||
}
|
||||
suite.runSequence({
|
||||
@@ -361,7 +361,7 @@ void OptimiserSuite::runSequence(std::vector<string> const& _steps, Block& _ast)
|
||||
{
|
||||
unique_ptr<Block> copy;
|
||||
if (m_debug == Debug::PrintChanges)
|
||||
copy = make_unique<Block>(boost::get<Block>(ASTCopier{}(_ast)));
|
||||
copy = make_unique<Block>(std::get<Block>(ASTCopier{}(_ast)));
|
||||
for (string const& step: _steps)
|
||||
{
|
||||
if (m_debug == Debug::PrintStep)
|
||||
@@ -376,7 +376,7 @@ void OptimiserSuite::runSequence(std::vector<string> const& _steps, Block& _ast)
|
||||
{
|
||||
cout << "== Running " << step << " changed the AST." << endl;
|
||||
cout << AsmPrinter{}(_ast) << endl;
|
||||
copy = make_unique<Block>(boost::get<Block>(ASTCopier{}(_ast)));
|
||||
copy = make_unique<Block>(std::get<Block>(ASTCopier{}(_ast)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ using namespace yul;
|
||||
|
||||
bool SyntacticallyEqual::operator()(Expression const& _lhs, Expression const& _rhs)
|
||||
{
|
||||
return boost::apply_visitor([this](auto&& _lhsExpr, auto&& _rhsExpr) -> bool {
|
||||
return std::visit([this](auto&& _lhsExpr, auto&& _rhsExpr) -> bool {
|
||||
// ``this->`` is redundant, but required to work around a bug present in gcc 6.x.
|
||||
return this->expressionEqual(_lhsExpr, _rhsExpr);
|
||||
}, _lhs, _rhs);
|
||||
@@ -40,7 +40,7 @@ bool SyntacticallyEqual::operator()(Expression const& _lhs, Expression const& _r
|
||||
|
||||
bool SyntacticallyEqual::operator()(Statement const& _lhs, Statement const& _rhs)
|
||||
{
|
||||
return boost::apply_visitor([this](auto&& _lhsStmt, auto&& _rhsStmt) -> bool {
|
||||
return std::visit([this](auto&& _lhsStmt, auto&& _rhsStmt) -> bool {
|
||||
// ``this->`` is redundant, but required to work around a bug present in gcc 6.x.
|
||||
return this->statementEqual(_lhsStmt, _rhsStmt);
|
||||
}, _lhs, _rhs);
|
||||
|
||||
@@ -68,18 +68,18 @@ UnusedPruner::UnusedPruner(
|
||||
void UnusedPruner::operator()(Block& _block)
|
||||
{
|
||||
for (auto&& statement: _block.statements)
|
||||
if (statement.type() == typeid(FunctionDefinition))
|
||||
if (holds_alternative<FunctionDefinition>(statement))
|
||||
{
|
||||
FunctionDefinition& funDef = boost::get<FunctionDefinition>(statement);
|
||||
FunctionDefinition& funDef = std::get<FunctionDefinition>(statement);
|
||||
if (!used(funDef.name))
|
||||
{
|
||||
subtractReferences(ReferencesCounter::countReferences(funDef.body));
|
||||
statement = Block{std::move(funDef.location), {}};
|
||||
}
|
||||
}
|
||||
else if (statement.type() == typeid(VariableDeclaration))
|
||||
else if (holds_alternative<VariableDeclaration>(statement))
|
||||
{
|
||||
VariableDeclaration& varDecl = boost::get<VariableDeclaration>(statement);
|
||||
VariableDeclaration& varDecl = std::get<VariableDeclaration>(statement);
|
||||
// Multi-variable declarations are special. We can only remove it
|
||||
// if all variables are unused and the right-hand-side is either
|
||||
// movable or it returns a single value. In the latter case, we
|
||||
@@ -108,9 +108,9 @@ void UnusedPruner::operator()(Block& _block)
|
||||
}};
|
||||
}
|
||||
}
|
||||
else if (statement.type() == typeid(ExpressionStatement))
|
||||
else if (holds_alternative<ExpressionStatement>(statement))
|
||||
{
|
||||
ExpressionStatement& exprStmt = boost::get<ExpressionStatement>(statement);
|
||||
ExpressionStatement& exprStmt = std::get<ExpressionStatement>(statement);
|
||||
if (
|
||||
SideEffectsCollector(m_dialect, exprStmt.expression, m_functionSideEffects).
|
||||
sideEffectFree(m_allowMSizeOptimization)
|
||||
|
||||
@@ -51,5 +51,5 @@ void VarDeclInitializer::operator()(Block& _block)
|
||||
}
|
||||
}
|
||||
};
|
||||
iterateReplacing(_block.statements, boost::apply_visitor(visitor));
|
||||
iterateReplacing(_block.statements, [&](auto&& _statement) { return std::visit(visitor, _statement); });
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ VarNameCleaner::VarNameCleaner(
|
||||
m_translatedNames{}
|
||||
{
|
||||
for (auto const& statement: _ast.statements)
|
||||
if (statement.type() == typeid(FunctionDefinition))
|
||||
m_blacklist.insert(boost::get<FunctionDefinition>(statement).name);
|
||||
if (holds_alternative<FunctionDefinition>(statement))
|
||||
m_blacklist.insert(std::get<FunctionDefinition>(statement).name);
|
||||
m_usedNames = m_blacklist;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user