P4C
The P4 Compiler
Loading...
Searching...
No Matches
pattern.h
1/*
2Copyright 2018-present Barefoot Networks, Inc.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef IR_PATTERN_H_
18#define IR_PATTERN_H_
19
20#include "ir/ir.h"
21
22namespace P4 {
23
30class Pattern {
31 class Base {
32 public:
33 virtual bool match(const IR::Node *) = 0;
34 } *pattern;
35 Pattern(Base *p) : pattern(p) {} // NOLINT(runtime/explicit)
36
37 template <class T>
38 class MatchExt : public Base {
39 const T *&m;
40
41 public:
42 bool match(const IR::Node *n) override { return (m = n->to<T>()); }
43 MatchExt(const T *&m) : m(m) {} // NOLINT(runtime/explicit)
44 };
45
46 class Const : public Base {
47 big_int value;
48
49 public:
50 bool match(const IR::Node *n) override {
51 if (auto k = n->to<IR::Constant>()) return k->value == value;
52 return false;
53 }
54 Const(big_int v) : value(v) {} // NOLINT(runtime/explicit)
55 Const(int v) : value(v) {} // NOLINT(runtime/explicit)
56 };
57 template <class T>
58 class Unary : public Base {
59 Base *expr;
60
61 public:
62 bool match(const IR::Node *n) override {
63 if (auto b = n->to<T>()) return expr->match(b->expr);
64 return false;
65 }
66 Unary(Base *e) : expr(e) {} // NOLINT(runtime/explicit)
67 };
68 template <class T>
69 class Binary : public Base {
70 Base *left, *right;
71 bool commutative;
72
73 public:
74 bool match(const IR::Node *n) override {
75 if (auto b = n->to<T>()) {
76 if (left->match(b->left) && right->match(b->right)) return true;
77 if (commutative && left->match(b->right) && right->match(b->left)) return true;
78 }
79 return false;
80 }
81 Binary(Base *l, Base *r, bool commute = false) : left(l), right(r), commutative(commute) {}
82 };
83
84 public:
85 template <class T>
86 class Match : public Base {
87 const T *m;
88
89 public:
90 bool match(const IR::Node *n) override { return (m = n->to<T>()); }
91 Match() : m(nullptr) {}
92 const T *operator->() const { return m; }
93 operator const T *() const { return m; } // NOLINT(runtime/explicit)
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 operator-(const Pattern &a) { return Pattern(*this) - 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 Pattern operator<=(const Pattern &a) { return Pattern(*this) <= a; }
105 Pattern operator>(const Pattern &a) { return Pattern(*this) > a; }
106 Pattern operator>=(const Pattern &a) { return Pattern(*this) >= a; }
107 Pattern Relation(const Pattern &a) { return Pattern(*this).Relation(a); }
108 Pattern operator&(const Pattern &a) { return Pattern(*this) & a; }
109 Pattern operator|(const Pattern &a) { return Pattern(*this) | a; }
110 Pattern operator^(const Pattern &a) { return Pattern(*this) ^ a; }
111 Pattern operator&&(const Pattern &a) { return Pattern(*this) && a; }
112 Pattern operator||(const Pattern &a) { return Pattern(*this) || a; }
113 // avoid ambiguous overloads with operator const T * above
114 Pattern operator+(int a) { return Pattern(*this) + Pattern(a); }
115 Pattern operator-(int a) { return Pattern(*this) - Pattern(a); }
116 Pattern operator==(int a) { return Pattern(*this) == Pattern(a); }
117 Pattern operator!=(int a) { return Pattern(*this) != Pattern(a); }
118 };
119
120 template <class T = IR::AssignmentStatement>
121 class Assign : public Base {
122 static_assert(std::is_base_of_v<IR::BaseAssignmentStatement, T>);
123 Base *left, *right;
124
125 public:
126 bool match(const IR::Node *n) override {
127 if (auto as = n->to<T>()) {
128 if (left->match(as->left) && right->match(as->right)) return true;
129 }
130 return false;
131 }
132 Assign(Base *l, Base *r) : left(l), right(r) {}
133 Assign(const Pattern &l, const Pattern &r) : left(l.pattern), right(r.pattern) {}
134 Assign(Base *l, int val) : left(l), right(new Const(val)) {}
135 Assign(Base *l, big_int val) : left(l), right(new Const(val)) {}
136 };
137
138 template <class T>
139 Pattern(const T *&m) : pattern(new MatchExt<T>(m)) {} // NOLINT(runtime/explicit)
140 template <class T>
141 Pattern(Match<T> &m) : pattern(&m) {} // NOLINT(runtime/explicit)
142 explicit Pattern(big_int v) : pattern(new Const(v)) {} // NOLINT(runtime/explicit)
143 explicit Pattern(int v) : pattern(new Const(v)) {} // NOLINT(runtime/explicit)
144 Pattern operator-() const { return Pattern(new Unary<IR::Neg>(pattern)); }
145 Pattern operator~() const { return Pattern(new Unary<IR::Cmpl>(pattern)); }
146 Pattern operator!() const { return Pattern(new Unary<IR::LNot>(pattern)); }
147 Pattern operator*(const Pattern &r) const {
148 return Pattern(new Binary<IR::Mul>(pattern, r.pattern, true));
149 }
150 Pattern operator/(const Pattern &r) const {
151 return Pattern(new Binary<IR::Div>(pattern, r.pattern));
152 }
153 Pattern operator%(const Pattern &r) const {
154 return Pattern(new Binary<IR::Mod>(pattern, r.pattern));
155 }
156 Pattern operator+(const Pattern &r) const {
157 return Pattern(new Binary<IR::Add>(pattern, r.pattern, true));
158 }
159 Pattern operator-(const Pattern &r) const {
160 return Pattern(new Binary<IR::Sub>(pattern, r.pattern));
161 }
162 Pattern operator<<(const Pattern &r) const {
163 return Pattern(new Binary<IR::Shl>(pattern, r.pattern));
164 }
165 Pattern operator>>(const Pattern &r) const {
166 return Pattern(new Binary<IR::Shr>(pattern, r.pattern));
167 }
168 Pattern operator==(const Pattern &r) const {
169 return Pattern(new Binary<IR::Equ>(pattern, r.pattern, true));
170 }
171 Pattern operator!=(const Pattern &r) const {
172 return Pattern(new Binary<IR::Neq>(pattern, r.pattern, true));
173 }
174 Pattern operator<(const Pattern &r) const {
175 return Pattern(new Binary<IR::Lss>(pattern, r.pattern));
176 }
177 Pattern operator<=(const Pattern &r) const {
178 return Pattern(new Binary<IR::Leq>(pattern, r.pattern));
179 }
180 Pattern operator>(const Pattern &r) const {
181 return Pattern(new Binary<IR::Grt>(pattern, r.pattern));
182 }
183 Pattern operator>=(const Pattern &r) const {
184 return Pattern(new Binary<IR::Geq>(pattern, r.pattern));
185 }
186 Pattern Relation(const Pattern &r) const {
187 return Pattern(new Binary<IR::Operation::Relation>(pattern, r.pattern, true));
188 }
189 Pattern operator&(const Pattern &r) const {
190 return Pattern(new Binary<IR::BAnd>(pattern, r.pattern, true));
191 }
192 Pattern operator|(const Pattern &r) const {
193 return Pattern(new Binary<IR::BOr>(pattern, r.pattern, true));
194 }
195 Pattern operator^(const Pattern &r) const {
196 return Pattern(new Binary<IR::BXor>(pattern, r.pattern, true));
197 }
198 Pattern operator&&(const Pattern &r) const {
199 return Pattern(new Binary<IR::LAnd>(pattern, r.pattern));
200 }
201 Pattern operator||(const Pattern &r) const {
202 return Pattern(new Binary<IR::LOr>(pattern, r.pattern));
203 }
206 // TODO: Ideally, we would fix these ambiguous overloads by making the Pattern class explicit in
207 // its initialization but that is a breaking change.
208 template <class T>
209 Pattern operator==(Match<T> &m) const {
210 return *this == Pattern(m);
211 }
212 template <class T>
213 Pattern operator!=(Match<T> &m) const {
214 return *this != Pattern(m);
215 }
216 template <class T>
217 Pattern operator==(const Match<T> &m) const {
218 return *this == Pattern(m);
219 }
220
221 bool match(const IR::Node *n) { return pattern->match(n); }
222};
223
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; }
233inline Pattern operator<(int v, const Pattern &a) { return Pattern(v) < a; }
234inline Pattern operator<=(int v, const Pattern &a) { return Pattern(v) <= a; }
235inline Pattern operator>(int v, const Pattern &a) { return Pattern(v) > a; }
236inline Pattern operator>=(int v, const Pattern &a) { return Pattern(v) >= a; }
237inline Pattern operator&(int v, const Pattern &a) { return Pattern(v) & a; }
238inline Pattern operator|(int v, const Pattern &a) { return Pattern(v) | a; }
239inline Pattern operator^(int v, const Pattern &a) { return Pattern(v) ^ a; }
240inline Pattern operator&&(int v, const Pattern &a) { return Pattern(v) && a; }
241inline Pattern operator||(int v, const Pattern &a) { return Pattern(v) || a; }
242
243} // namespace P4
244
245#endif /* IR_PATTERN_H_ */
Definition node.h:94
Definition pattern.h:86
Definition pattern.h:30
Pattern operator==(Match< T > &m) const
Definition pattern.h:209
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
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