31        virtual bool match(
const IR::Node *) = 0;
 
   33    Pattern(Base *p) : pattern(p) {}  
 
   36    class MatchExt : 
public Base {
 
   40        bool match(
const IR::Node *n)
 override { 
return (m = n->
to<T>()); }
 
   41        MatchExt(
const T *&m) : m(m) {}  
 
   44    class Const : 
public Base {
 
   48        bool match(
const IR::Node *n)
 override {
 
   49            if (
auto k = n->
to<IR::Constant>()) 
return k->value == value;
 
   52        Const(big_int v) : value(v) {}  
 
   53        Const(
int v) : value(v) {}      
 
   56    class Unary : 
public Base {
 
   60        bool match(
const IR::Node *n)
 override {
 
   61            if (
auto b = n->
to<T>()) 
return expr->match(b->expr);
 
   64        Unary(Base *e) : expr(e) {}  
 
   67    class Binary : 
public Base {
 
   72        bool match(
const IR::Node *n)
 override {
 
   73            if (
auto b = n->
to<T>()) {
 
   74                if (left->match(b->left) && right->match(b->right)) 
return true;
 
   75                if (commutative && left->match(b->right) && right->match(b->left)) 
return true;
 
   79        Binary(Base *l, Base *r, 
bool commute = 
false) : left(l), right(r), commutative(commute) {}
 
   88        bool match(
const IR::Node *n)
 override { 
return (m = n->
to<T>()); }
 
   89        Match() : m(
nullptr) {}
 
   90        const T *operator->()
 const { 
return m; }
 
   91        operator const T *() 
const { 
return m; }  
 
 
  119    Pattern(
const T *&m) : pattern(new MatchExt<T>(m)) {}  
 
  121    Pattern(Match<T> &m) : pattern(&m) {}                   
 
  122    explicit Pattern(big_int v) : pattern(new Const(v)) {}  
 
  123    explicit Pattern(
int v) : pattern(new Const(v)) {}      
 
  124    Pattern operator-()
 const { 
return Pattern(
new Unary<IR::Neg>(pattern)); }
 
  125    Pattern operator~()
 const { 
return Pattern(
new Unary<IR::Cmpl>(pattern)); }
 
  126    Pattern operator!()
 const { 
return Pattern(
new Unary<IR::LNot>(pattern)); }
 
  128        return Pattern(
new Binary<IR::Mul>(pattern, r.pattern, 
true));
 
  131        return Pattern(
new Binary<IR::Div>(pattern, r.pattern));
 
  134        return Pattern(
new Binary<IR::Mod>(pattern, r.pattern));
 
  137        return Pattern(
new Binary<IR::Add>(pattern, r.pattern, 
true));
 
  140        return Pattern(
new Binary<IR::Sub>(pattern, r.pattern));
 
  143        return Pattern(
new Binary<IR::Shl>(pattern, r.pattern));
 
  146        return Pattern(
new Binary<IR::Shr>(pattern, r.pattern));
 
  149        return Pattern(
new Binary<IR::Equ>(pattern, r.pattern, 
true));
 
  152        return Pattern(
new Binary<IR::Neq>(pattern, r.pattern, 
true));
 
  155        return Pattern(
new Binary<IR::Lss>(pattern, r.pattern));
 
  158        return Pattern(
new Binary<IR::Leq>(pattern, r.pattern));
 
  161        return Pattern(
new Binary<IR::Grt>(pattern, r.pattern));
 
  164        return Pattern(
new Binary<IR::Geq>(pattern, r.pattern));
 
  167        return Pattern(
new Binary<IR::Operation::Relation>(pattern, r.pattern, 
true));
 
  170        return Pattern(
new Binary<IR::BAnd>(pattern, r.pattern, 
true));
 
  173        return Pattern(
new Binary<IR::BOr>(pattern, r.pattern, 
true));
 
  176        return Pattern(
new Binary<IR::BXor>(pattern, r.pattern, 
true));
 
  179        return Pattern(
new Binary<IR::LAnd>(pattern, r.pattern));
 
  182        return Pattern(
new Binary<IR::LOr>(pattern, r.pattern));
 
  185    bool match(
const IR::Node *n) { 
return pattern->match(n); }