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

View File

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