P4C
The P4 Compiler
Loading...
Searching...
No Matches
pattern.h
1/*
2 * SPDX-FileCopyrightText: 2018 Barefoot Networks, Inc.
3 * Copyright 2018-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef IR_PATTERN_H_
9#define IR_PATTERN_H_
10
11#include "ir/ir.h"
12
13namespace P4 {
14
21class Pattern {
22 class Base {
23 public:
24 virtual bool match(const IR::Node *) = 0;
25 } *pattern;
26 Pattern(Base *p) : pattern(p) {} // NOLINT(runtime/explicit)
27
28 template <class T>
29 class MatchExt : public Base {
30 const T *&m;
31
32 public:
33 bool match(const IR::Node *n) override { return (m = n->to<T>()); }
34 MatchExt(const T *&m) : m(m) {} // NOLINT(runtime/explicit)
35 };
36
37 class Const : public Base {
38 big_int value;
39
40 public:
41 bool match(const IR::Node *n) override {
42 if (auto k = n->to<IR::Constant>()) return k->value == value;
43 return false;
44 }
45 Const(big_int v) : value(v) {} // NOLINT(runtime/explicit)
46 Const(int v) : value(v) {} // NOLINT(runtime/explicit)
47 };
48 template <class T>
49 class Unary : public Base {
50 Base *expr;
51
52 public:
53 bool match(const IR::Node *n) override {
54 if (auto b = n->to<T>()) return expr->match(b->expr);
55 return false;
56 }
57 Unary(Base *e) : expr(e) {} // NOLINT(runtime/explicit)
58 };
59 template <class T>
60 class Binary : public Base {
61 Base *left, *right;
62 bool commutative;
63
64 public:
65 bool match(const IR::Node *n) override {
66 if (auto b = n->to<T>()) {
67 if (left->match(b->left) && right->match(b->right)) return true;
68 if (commutative && left->match(b->right) && right->match(b->left)) return true;
69 }
70 return false;
71 }
72 Binary(Base *l, Base *r, bool commute = false) : left(l), right(r), commutative(commute) {}
73 };
74
75 public:
76 template <class T>
77 class Match : public Base {
78 const T *m;
79
80 public:
81 bool match(const IR::Node *n) override { return (m = n->to<T>()); }
82 Match() : m(nullptr) {}
83 const T *operator->() const { return m; }
84 operator const T *() const { return m; } // NOLINT(runtime/explicit)
85 Pattern operator*(const Pattern &a) { return Pattern(*this) * a; }
86 Pattern operator/(const Pattern &a) { return Pattern(*this) / a; }
87 Pattern operator%(const Pattern &a) { return Pattern(*this) % a; }
88 Pattern operator+(const Pattern &a) { return Pattern(*this) + a; }
89 Pattern operator-(const Pattern &a) { return Pattern(*this) - a; }
90 Pattern operator<<(const Pattern &a) { return Pattern(*this) << a; }
91 Pattern operator>>(const Pattern &a) { return Pattern(*this) >> a; }
92 Pattern operator==(const Pattern &a) { return Pattern(*this) == a; }
93 Pattern operator!=(const Pattern &a) { return Pattern(*this) != a; }
94 Pattern operator<(const Pattern &a) { return Pattern(*this) < a; }
95 Pattern operator<=(const Pattern &a) { return Pattern(*this) <= a; }
96 Pattern operator>(const Pattern &a) { return Pattern(*this) > a; }
97 Pattern operator>=(const Pattern &a) { return Pattern(*this) >= a; }
98 Pattern Relation(const Pattern &a) { return Pattern(*this).Relation(a); }
99 Pattern operator&(const Pattern &a) { return Pattern(*this) & a; }
100 Pattern operator|(const Pattern &a) { return Pattern(*this) | a; }
101 Pattern operator^(const Pattern &a) { return Pattern(*this) ^ a; }
102 Pattern operator&&(const Pattern &a) { return Pattern(*this) && a; }
103 Pattern operator||(const Pattern &a) { return Pattern(*this) || a; }
104 // avoid ambiguous overloads with operator const T * above
105 Pattern operator+(int a) { return Pattern(*this) + Pattern(a); }
106 Pattern operator-(int a) { return Pattern(*this) - Pattern(a); }
107 Pattern operator==(int a) { return Pattern(*this) == Pattern(a); }
108 Pattern operator!=(int a) { return Pattern(*this) != Pattern(a); }
109 };
110
111 template <class T = IR::AssignmentStatement>
112 class Assign : public Base {
113 static_assert(std::is_base_of_v<IR::BaseAssignmentStatement, T>);
114 Base *left, *right;
115
116 public:
117 bool match(const IR::Node *n) override {
118 if (auto as = n->to<T>()) {
119 if (left->match(as->left) && right->match(as->right)) return true;
120 }
121 return false;
122 }
123 Assign(Base *l, Base *r) : left(l), right(r) {}
124 Assign(const Pattern &l, const Pattern &r) : left(l.pattern), right(r.pattern) {}
125 Assign(Base *l, int val) : left(l), right(new Const(val)) {}
126 Assign(Base *l, big_int val) : left(l), right(new Const(val)) {}
127 };
128
129 template <class T>
130 Pattern(const T *&m) : pattern(new MatchExt<T>(m)) {} // NOLINT(runtime/explicit)
131 template <class T>
132 Pattern(Match<T> &m) : pattern(&m) {} // NOLINT(runtime/explicit)
133 explicit Pattern(big_int v) : pattern(new Const(v)) {} // NOLINT(runtime/explicit)
134 explicit Pattern(int v) : pattern(new Const(v)) {} // NOLINT(runtime/explicit)
135 Pattern operator-() const { return Pattern(new Unary<IR::Neg>(pattern)); }
136 Pattern operator~() const { return Pattern(new Unary<IR::Cmpl>(pattern)); }
137 Pattern operator!() const { return Pattern(new Unary<IR::LNot>(pattern)); }
138 Pattern operator*(const Pattern &r) const {
139 return Pattern(new Binary<IR::Mul>(pattern, r.pattern, true));
140 }
141 Pattern operator/(const Pattern &r) const {
142 return Pattern(new Binary<IR::Div>(pattern, r.pattern));
143 }
144 Pattern operator%(const Pattern &r) const {
145 return Pattern(new Binary<IR::Mod>(pattern, r.pattern));
146 }
147 Pattern operator+(const Pattern &r) const {
148 return Pattern(new Binary<IR::Add>(pattern, r.pattern, true));
149 }
150 Pattern operator-(const Pattern &r) const {
151 return Pattern(new Binary<IR::Sub>(pattern, r.pattern));
152 }
153 Pattern operator<<(const Pattern &r) const {
154 return Pattern(new Binary<IR::Shl>(pattern, r.pattern));
155 }
156 Pattern operator>>(const Pattern &r) const {
157 return Pattern(new Binary<IR::Shr>(pattern, r.pattern));
158 }
159 Pattern operator==(const Pattern &r) const {
160 return Pattern(new Binary<IR::Equ>(pattern, r.pattern, true));
161 }
162 Pattern operator!=(const Pattern &r) const {
163 return Pattern(new Binary<IR::Neq>(pattern, r.pattern, true));
164 }
165 Pattern operator<(const Pattern &r) const {
166 return Pattern(new Binary<IR::Lss>(pattern, r.pattern));
167 }
168 Pattern operator<=(const Pattern &r) const {
169 return Pattern(new Binary<IR::Leq>(pattern, r.pattern));
170 }
171 Pattern operator>(const Pattern &r) const {
172 return Pattern(new Binary<IR::Grt>(pattern, r.pattern));
173 }
174 Pattern operator>=(const Pattern &r) const {
175 return Pattern(new Binary<IR::Geq>(pattern, r.pattern));
176 }
177 Pattern Relation(const Pattern &r) const {
178 return Pattern(new Binary<IR::Operation::Relation>(pattern, r.pattern, true));
179 }
180 Pattern operator&(const Pattern &r) const {
181 return Pattern(new Binary<IR::BAnd>(pattern, r.pattern, true));
182 }
183 Pattern operator|(const Pattern &r) const {
184 return Pattern(new Binary<IR::BOr>(pattern, r.pattern, true));
185 }
186 Pattern operator^(const Pattern &r) const {
187 return Pattern(new Binary<IR::BXor>(pattern, r.pattern, true));
188 }
189 Pattern operator&&(const Pattern &r) const {
190 return Pattern(new Binary<IR::LAnd>(pattern, r.pattern));
191 }
192 Pattern operator||(const Pattern &r) const {
193 return Pattern(new Binary<IR::LOr>(pattern, r.pattern));
194 }
197 // TODO: Ideally, we would fix these ambiguous overloads by making the Pattern class explicit in
198 // its initialization but that is a breaking change.
199 template <class T>
200 Pattern operator==(Match<T> &m) const {
201 return *this == Pattern(m);
202 }
203 template <class T>
204 Pattern operator!=(Match<T> &m) const {
205 return *this != Pattern(m);
206 }
207 template <class T>
208 Pattern operator==(const Match<T> &m) const {
209 return *this == Pattern(m);
210 }
211
212 bool match(const IR::Node *n) { return pattern->match(n); }
213};
214
215inline Pattern operator*(int v, const Pattern &a) { return Pattern(v) * a; }
216inline Pattern operator/(int v, const Pattern &a) { return Pattern(v) / a; }
217inline Pattern operator%(int v, const Pattern &a) { return Pattern(v) % a; }
218inline Pattern operator+(int v, const Pattern &a) { return Pattern(v) + a; }
219inline Pattern operator-(int v, const Pattern &a) { return Pattern(v) - a; }
220inline Pattern operator<<(int v, const Pattern &a) { return Pattern(v) << a; }
221inline Pattern operator>>(int v, const Pattern &a) { return Pattern(v) >> a; }
222inline Pattern operator==(int v, const Pattern &a) { return Pattern(v) == a; }
223inline Pattern operator!=(int v, const Pattern &a) { return Pattern(v) != a; }
224inline Pattern operator<(int v, const Pattern &a) { return Pattern(v) < a; }
225inline Pattern operator<=(int v, const Pattern &a) { return Pattern(v) <= a; }
226inline Pattern operator>(int v, const Pattern &a) { return Pattern(v) > a; }
227inline Pattern operator>=(int v, const Pattern &a) { return Pattern(v) >= a; }
228inline Pattern operator&(int v, const Pattern &a) { return Pattern(v) & a; }
229inline Pattern operator|(int v, const Pattern &a) { return Pattern(v) | a; }
230inline Pattern operator^(int v, const Pattern &a) { return Pattern(v) ^ a; }
231inline Pattern operator&&(int v, const Pattern &a) { return Pattern(v) && a; }
232inline Pattern operator||(int v, const Pattern &a) { return Pattern(v) || a; }
233
234} // namespace P4
235
236#endif /* IR_PATTERN_H_ */
Definition node.h:53
Definition pattern.h:77
Definition pattern.h:21
Pattern operator==(Match< T > &m) const
Definition pattern.h:200
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13
std::pair< HalfOpenRange< Unit, Order >, HalfOpenRange< Unit, Order > > operator-(HalfOpenRange< Unit, Order > left, HalfOpenRange< Unit, Order > right)
Definition lib/bitrange.h:716
Definition tables.h:1466
T * to() noexcept
Definition rtti.h:226