Merge pull request #11306 from ethereum/toevminstruction

Add toEVMInstruction helper
This commit is contained in:
Harikrishnan Mulackal 2021-04-26 08:41:25 +02:00 committed by GitHub
commit 2cb525f607
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 19 deletions

View File

@ -19,11 +19,11 @@
*/
#include <libyul/optimiser/Metrics.h>
#include <libyul/optimiser/OptimizerUtilities.h>
#include <libyul/AST.h>
#include <libyul/Exceptions.h>
#include <libyul/Utilities.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <libevmasm/Instruction.h>
#include <libevmasm/GasMeter.h>
@ -139,13 +139,11 @@ void CodeCost::operator()(FunctionCall const& _funCall)
{
ASTWalker::operator()(_funCall);
if (EVMDialect const* dialect = dynamic_cast<EVMDialect const*>(&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;
}

View File

@ -21,6 +21,8 @@
#include <libyul/optimiser/OptimizerUtilities.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <libyul/Dialect.h>
#include <libyul/AST.h>
@ -47,3 +49,11 @@ bool yul::isRestrictedIdentifier(Dialect const& _dialect, YulString const& _iden
{
return _identifier.empty() || TokenTraits::isYulKeyword(_identifier.str()) || _dialect.reservedIdentifier(_identifier);
}
optional<evmasm::Instruction> yul::toEVMInstruction(Dialect const& _dialect, YulString const& _name)
{
if (auto const* dialect = dynamic_cast<EVMDialect const*>(&_dialect))
if (BuiltinFunctionForEVM const* builtin = dialect->builtin(_name))
return builtin->instruction;
return nullopt;
}

View File

@ -26,6 +26,13 @@
#include <libyul/Dialect.h>
#include <libyul/YulString.h>
#include <optional>
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<evmasm::Instruction> toEVMInstruction(Dialect const& _dialect, YulString const& _name);
}

View File

@ -17,14 +17,13 @@
#include <libyul/optimiser/ReasoningBasedSimplifier.h>
#include <libyul/optimiser/OptimizerUtilities.h>
#include <libyul/optimiser/SSAValueTracker.h>
#include <libyul/optimiser/Semantics.h>
#include <libyul/AST.h>
#include <libyul/Utilities.h>
#include <libyul/Dialect.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <libsmtutil/SMTPortfolio.h>
#include <libsmtutil/Helpers.h>
@ -123,10 +122,8 @@ smtutil::Expression ReasoningBasedSimplifier::encodeExpression(yul::Expression c
return std::visit(GenericVisitor{
[&](FunctionCall const& _functionCall)
{
if (auto const* dialect = dynamic_cast<EVMDialect const*>(&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)

View File

@ -21,10 +21,10 @@
#include <libyul/optimiser/Semantics.h>
#include <libyul/optimiser/OptimizerUtilities.h>
#include <libyul/Exceptions.h>
#include <libyul/AST.h>
#include <libyul/Dialect.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <libevmasm/SemanticInformation.h>
@ -197,9 +197,7 @@ TerminationFinder::ControlFlow TerminationFinder::controlFlowKind(Statement cons
bool TerminationFinder::isTerminatingBuiltin(ExpressionStatement const& _exprStmnt)
{
if (holds_alternative<FunctionCall>(_exprStmnt.expression))
if (auto const* dialect = dynamic_cast<EVMDialect const*>(&m_dialect))
if (auto const* builtin = dialect->builtin(std::get<FunctionCall>(_exprStmnt.expression).functionName.name))
if (builtin->instruction)
return evmasm::SemanticInformation::terminatesControlFlow(*builtin->instruction);
if (auto instruction = toEVMInstruction(m_dialect, std::get<FunctionCall>(_exprStmnt.expression).functionName.name))
return evmasm::SemanticInformation::terminatesControlFlow(*instruction);
return false;
}