mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add EVM opcodes as builtins.
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include <libyul/optimiser/ASTCopier.h>
|
||||
#include <libyul/optimiser/Semantics.h>
|
||||
#include <libyul/optimiser/SyntacticalEquality.h>
|
||||
#include <libyul/backends/evm/EVMDialect.h>
|
||||
#include <libyul/AsmData.h>
|
||||
#include <libyul/Utilities.h>
|
||||
|
||||
@@ -41,14 +42,14 @@ SimplificationRule<yul::Pattern> const* SimplificationRules::findFirstMatch(
|
||||
map<YulString, Expression const*> const& _ssaValues
|
||||
)
|
||||
{
|
||||
if (_expr.type() != typeid(FunctionalInstruction))
|
||||
auto instruction = instructionAndArguments(_dialect, _expr);
|
||||
if (!instruction)
|
||||
return nullptr;
|
||||
|
||||
static SimplificationRules rules;
|
||||
assertThrow(rules.isInitialized(), OptimizerException, "Rule list not properly initialized.");
|
||||
|
||||
FunctionalInstruction const& instruction = boost::get<FunctionalInstruction>(_expr);
|
||||
for (auto const& rule: rules.m_rules[uint8_t(instruction.instruction)])
|
||||
for (auto const& rule: rules.m_rules[uint8_t(instruction->first)])
|
||||
{
|
||||
rules.resetMatchGroups();
|
||||
if (rule.pattern.matches(_expr, _dialect, _ssaValues))
|
||||
@@ -63,6 +64,20 @@ bool SimplificationRules::isInitialized() const
|
||||
return !m_rules[uint8_t(dev::eth::Instruction::ADD)].empty();
|
||||
}
|
||||
|
||||
boost::optional<std::pair<dev::eth::Instruction, vector<Expression> const*>>
|
||||
SimplificationRules::instructionAndArguments(Dialect const& _dialect, Expression const& _expr)
|
||||
{
|
||||
if (_expr.type() == typeid(FunctionalInstruction))
|
||||
return make_pair(boost::get<FunctionalInstruction>(_expr).instruction, &boost::get<FunctionalInstruction>(_expr).arguments);
|
||||
else if (_expr.type() == typeid(FunctionCall))
|
||||
if (auto const* dialect = dynamic_cast<EVMDialect const*>(&_dialect))
|
||||
if (auto const* builtin = dialect->builtin(boost::get<FunctionCall>(_expr).functionName.name))
|
||||
if (builtin->instruction)
|
||||
return make_pair(*builtin->instruction, &boost::get<FunctionCall>(_expr).arguments);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void SimplificationRules::addRules(vector<SimplificationRule<Pattern>> const& _rules)
|
||||
{
|
||||
for (auto const& r: _rules)
|
||||
@@ -139,14 +154,12 @@ bool Pattern::matches(
|
||||
}
|
||||
else if (m_kind == PatternKind::Operation)
|
||||
{
|
||||
if (expr->type() != typeid(FunctionalInstruction))
|
||||
auto instrAndArgs = SimplificationRules::instructionAndArguments(_dialect, *expr);
|
||||
if (!instrAndArgs || m_instruction != instrAndArgs->first)
|
||||
return false;
|
||||
FunctionalInstruction const& instr = boost::get<FunctionalInstruction>(*expr);
|
||||
if (m_instruction != instr.instruction)
|
||||
return false;
|
||||
assertThrow(m_arguments.size() == instr.arguments.size(), OptimizerException, "");
|
||||
assertThrow(m_arguments.size() == instrAndArgs->second->size(), OptimizerException, "");
|
||||
for (size_t i = 0; i < m_arguments.size(); ++i)
|
||||
if (!m_arguments[i].matches(instr.arguments.at(i), _dialect, _ssaValues))
|
||||
if (!m_arguments[i].matches(instrAndArgs->second->at(i), _dialect, _ssaValues))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <libyul/AsmData.h>
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
@@ -55,6 +56,10 @@ public:
|
||||
/// Checks whether the rulelist is non-empty. This is usually enforced
|
||||
/// by the constructor, but we had some issues with static initialization.
|
||||
bool isInitialized() const;
|
||||
|
||||
static boost::optional<std::pair<dev::eth::Instruction, std::vector<Expression> const*>>
|
||||
instructionAndArguments(Dialect const& _dialect, Expression const& _expr);
|
||||
|
||||
private:
|
||||
void addRules(std::vector<dev::eth::SimplificationRule<Pattern>> const& _rules);
|
||||
void addRule(dev::eth::SimplificationRule<Pattern> const& _rule);
|
||||
|
||||
Reference in New Issue
Block a user