Optimize pattern matcher.

This commit is contained in:
chriseth 2017-01-06 11:25:02 +01:00
parent afad40ac5a
commit 652d8dab19
2 changed files with 22 additions and 16 deletions

View File

@ -185,7 +185,7 @@ class Rules: public boost::noncopyable
public:
Rules();
void resetMatchGroups() { m_matchGroups.clear(); }
vector<pair<Pattern, function<Pattern()>>> rules() const { return m_rules; }
vector<pair<Pattern, function<Pattern()>>> const& rules() const { return m_rules; }
private:
using Expression = ExpressionClasses::Expression;
@ -417,8 +417,7 @@ ExpressionClasses::Id ExpressionClasses::rebuildExpression(ExpressionTemplate co
Pattern::Pattern(Instruction _instruction, std::vector<Pattern> const& _arguments):
m_type(Operation),
m_requireDataMatch(true),
m_data(_instruction),
m_instruction(_instruction),
m_arguments(_arguments)
{
}
@ -449,7 +448,10 @@ bool Pattern::matches(Expression const& _expr, ExpressionClasses const& _classes
AssemblyItem Pattern::toAssemblyItem(SourceLocation const& _location) const
{
return AssemblyItem(m_type, m_data, _location);
if (m_type == Operation)
return AssemblyItem(m_instruction, _location);
else
return AssemblyItem(m_type, data(), _location);
}
string Pattern::toString() const
@ -458,16 +460,16 @@ string Pattern::toString() const
switch (m_type)
{
case Operation:
s << instructionInfo(Instruction(unsigned(m_data))).name;
s << instructionInfo(m_instruction).name;
break;
case Push:
s << "PUSH " << hex << m_data;
s << "PUSH " << hex << data();
break;
case UndefinedItem:
s << "ANY";
break;
default:
s << "t=" << dec << m_type << " d=" << hex << m_data;
s << "t=" << dec << m_type << " d=" << hex << data();
break;
}
if (!m_requireDataMatch)
@ -489,13 +491,10 @@ bool Pattern::matchesBaseItem(AssemblyItem const* _item) const
return false;
if (m_type != _item->type())
return false;
if (m_requireDataMatch)
{
if (m_type == Operation)
return m_data == u256(byte(_item->instruction()));
else
return m_data == _item->data();
}
else if (m_type == Operation)
return m_instruction == _item->instruction();
else if (m_requireDataMatch)
return data() == _item->data();
return true;
}
@ -507,6 +506,11 @@ Pattern::Expression const& Pattern::matchGroupValue() const
return *(*m_matchGroups)[m_matchGroup];
}
u256 const& Pattern::data() const
{
assertThrow(m_data, OptimizerException, "");
return *m_data;
}
ExpressionTemplate::ExpressionTemplate(Pattern const& _pattern, SourceLocation const& _location)
{

View File

@ -135,7 +135,7 @@ public:
// Matches a specific constant value.
Pattern(unsigned _value): Pattern(u256(_value)) {}
// Matches a specific constant value.
Pattern(u256 const& _value): m_type(Push), m_requireDataMatch(true), m_data(_value) {}
Pattern(u256 const& _value): m_type(Push), m_requireDataMatch(true), m_data(std::make_shared<u256>(_value)) {}
// Matches a specific assembly item type or anything if not given.
Pattern(AssemblyItemType _type = UndefinedItem): m_type(_type) {}
// Matches a given instruction with given arguments
@ -160,10 +160,12 @@ public:
private:
bool matchesBaseItem(AssemblyItem const* _item) const;
Expression const& matchGroupValue() const;
u256 const& data() const;
AssemblyItemType m_type;
bool m_requireDataMatch = false;
u256 m_data = 0;
Instruction m_instruction; ///< Only valid if m_type is Operation
std::shared_ptr<u256> m_data; ///< Only valid if m_type is not Operation
std::vector<Pattern> m_arguments;
unsigned m_matchGroup = 0;
std::map<unsigned, Expression const*>* m_matchGroups = nullptr;