diff --git a/libyul/optimiser/Metrics.cpp b/libyul/optimiser/Metrics.cpp index a26ea547d..b9577f0fb 100644 --- a/libyul/optimiser/Metrics.cpp +++ b/libyul/optimiser/Metrics.cpp @@ -19,11 +19,11 @@ */ #include +#include #include #include #include -#include #include #include @@ -139,13 +139,11 @@ void CodeCost::operator()(FunctionCall const& _funCall) { ASTWalker::operator()(_funCall); - if (EVMDialect const* dialect = dynamic_cast(&m_dialect)) - if (BuiltinFunctionForEVM const* f = dialect->builtin(_funCall.functionName.name)) - if (f->instruction) - { - addInstructionCost(*f->instruction); - return; - } + if (auto instruction = toEVMInstruction(m_dialect, _funCall.functionName.name)) + { + addInstructionCost(*instruction); + return; + } m_cost += 49; } diff --git a/libyul/optimiser/OptimizerUtilities.cpp b/libyul/optimiser/OptimizerUtilities.cpp index 52019356e..e00531f14 100644 --- a/libyul/optimiser/OptimizerUtilities.cpp +++ b/libyul/optimiser/OptimizerUtilities.cpp @@ -21,6 +21,8 @@ #include +#include + #include #include @@ -47,3 +49,11 @@ bool yul::isRestrictedIdentifier(Dialect const& _dialect, YulString const& _iden { return _identifier.empty() || TokenTraits::isYulKeyword(_identifier.str()) || _dialect.reservedIdentifier(_identifier); } + +optional yul::toEVMInstruction(Dialect const& _dialect, YulString const& _name) +{ + if (auto const* dialect = dynamic_cast(&_dialect)) + if (BuiltinFunctionForEVM const* builtin = dialect->builtin(_name)) + return builtin->instruction; + return nullopt; +} diff --git a/libyul/optimiser/OptimizerUtilities.h b/libyul/optimiser/OptimizerUtilities.h index 22191538b..09ea9ed5a 100644 --- a/libyul/optimiser/OptimizerUtilities.h +++ b/libyul/optimiser/OptimizerUtilities.h @@ -26,6 +26,13 @@ #include #include +#include + +namespace solidity::evmasm +{ +enum class Instruction: uint8_t; +} + namespace solidity::yul { @@ -36,4 +43,7 @@ void removeEmptyBlocks(Block& _block); /// This includes Yul keywords and builtins of the given dialect. bool isRestrictedIdentifier(Dialect const& _dialect, YulString const& _identifier); +/// Helper function that returns the instruction, if the `_name` is a BuiltinFunction +std::optional toEVMInstruction(Dialect const& _dialect, YulString const& _name); + } diff --git a/libyul/optimiser/ReasoningBasedSimplifier.cpp b/libyul/optimiser/ReasoningBasedSimplifier.cpp index f61bee321..b428cbab5 100644 --- a/libyul/optimiser/ReasoningBasedSimplifier.cpp +++ b/libyul/optimiser/ReasoningBasedSimplifier.cpp @@ -17,14 +17,13 @@ #include +#include #include #include #include #include #include -#include - #include #include @@ -123,10 +122,8 @@ smtutil::Expression ReasoningBasedSimplifier::encodeExpression(yul::Expression c return std::visit(GenericVisitor{ [&](FunctionCall const& _functionCall) { - if (auto const* dialect = dynamic_cast(&m_dialect)) - if (auto const* builtin = dialect->builtin(_functionCall.functionName.name)) - if (builtin->instruction) - return encodeEVMBuiltin(*builtin->instruction, _functionCall.arguments); + if (auto instruction = toEVMInstruction(m_dialect, _functionCall.functionName.name)) + return encodeEVMBuiltin(*instruction, _functionCall.arguments); return newRestrictedVariable(); }, [&](Identifier const& _identifier) diff --git a/libyul/optimiser/Semantics.cpp b/libyul/optimiser/Semantics.cpp index 88d0e4772..d51af2de2 100644 --- a/libyul/optimiser/Semantics.cpp +++ b/libyul/optimiser/Semantics.cpp @@ -21,10 +21,10 @@ #include +#include #include #include #include -#include #include @@ -197,9 +197,7 @@ TerminationFinder::ControlFlow TerminationFinder::controlFlowKind(Statement cons bool TerminationFinder::isTerminatingBuiltin(ExpressionStatement const& _exprStmnt) { if (holds_alternative(_exprStmnt.expression)) - if (auto const* dialect = dynamic_cast(&m_dialect)) - if (auto const* builtin = dialect->builtin(std::get(_exprStmnt.expression).functionName.name)) - if (builtin->instruction) - return evmasm::SemanticInformation::terminatesControlFlow(*builtin->instruction); + if (auto instruction = toEVMInstruction(m_dialect, std::get(_exprStmnt.expression).functionName.name)) + return evmasm::SemanticInformation::terminatesControlFlow(*instruction); return false; }