CIRCT 20.0.0git
Loading...
Searching...
No Matches
EmissionPattern.h
Go to the documentation of this file.
1//===- EmissionPattern.h - Emission Pattern Base and Utility --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This declares the emission pattern base and utility classes.
10//
11//===----------------------------------------------------------------------===//
12
13// NOLINTNEXTLINE(llvm-header-guard)
14#ifndef CIRCT_TARGET_EXPORTSYSTEMC_EMISSIONPATTERN_H
15#define CIRCT_TARGET_EXPORTSYSTEMC_EMISSIONPATTERN_H
16
18#include "mlir/IR/Operation.h"
19#include <any>
20
21namespace circt {
22namespace ExportSystemC {
23// Forward declarations.
24class EmissionPrinter;
25
26//===----------------------------------------------------------------------===//
27// Inline emission utilities.
28//===----------------------------------------------------------------------===//
29
30/// This enum encodes the precedence of C++ expressions. A lower number means
31/// higher precedence. Source:
32/// https://en.cppreference.com/w/cpp/language/operator_precedence
33enum class Precedence {
34 LIT = 0,
35 VAR = 0,
37 POSTFIX_INC = 2,
38 POSTFIX_DEC = 2,
40 FUNCTION_CALL = 2,
41 SUBSCRIPT = 2,
42 MEMBER_ACCESS = 2,
43 PREFIX_INC = 3,
44 PREFIX_DEC = 3,
45 NOT = 3,
46 CAST = 3,
47 DEREFERENCE = 3,
48 ADDRESS_OF = 3,
49 SIZEOF = 3,
50 NEW = 3,
51 DELETE = 3,
53 MUL = 5,
54 DIV = 5,
55 MOD = 5,
56 ADD = 6,
57 SUB = 6,
58 SHL = 7,
59 SHR = 7,
60 RELATIONAL = 9,
61 EQUALITY = 10,
62 BITWISE_AND = 11,
63 BITWISE_XOR = 12,
64 BITWISE_OR = 13,
65 LOGICAL_AND = 14,
66 LOGICAL_OR = 15,
67 TERNARY = 16,
68 THROW = 16,
69 ASSIGN = 16,
70 COMMA = 17
71};
72
73/// This class allows a pattern's match function for inlining to pass its
74/// result's precedence to the pattern that requested the expression.
76public:
77 MatchResult() = default;
80
81 bool failed() const { return isFailure; }
83
84private:
85 bool isFailure = true;
87};
88
89//===----------------------------------------------------------------------===//
90// Emission pattern base classes.
91//===----------------------------------------------------------------------===//
92
93/// This is indented to be the base class for all emission patterns.
95public:
96 explicit PatternBase(const void *rootValue) : rootValue(rootValue) {}
97
98 template <typename E, typename... Args>
99 static std::unique_ptr<E> create(Args &&...args) {
100 std::unique_ptr<E> pattern =
101 std::make_unique<E>(std::forward<Args>(args)...);
102 return pattern;
103 }
104
105 /// Get a unique identifier for the C++ type the pattern is matching on. This
106 /// could be a specific MLIR type or operation.
107 const void *getRootValue() const { return rootValue; }
108
109private:
110 const void *rootValue;
111};
112
113/// This is intended to be the base class for all emission patterns matching on
114/// operations.
116 OpEmissionPatternBase(StringRef operationName, MLIRContext *context)
117 : PatternBase(
118 OperationName(operationName, context).getAsOpaquePointer()) {}
119 virtual ~OpEmissionPatternBase() = default;
120
121 /// Checks if this pattern is applicable to the given value to emit an
122 /// inlinable expression. Additionally returns information such as the
123 /// precedence to the pattern where this pattern's result is to be inlined.
124 virtual MatchResult matchInlinable(Value value) = 0;
125
126 /// Checks if this pattern is applicable to the given operation for statement
127 /// emission.
128 virtual bool matchStatement(mlir::Operation *op) = 0;
129
130 /// Emit the expression for the given value.
131 virtual void emitInlined(mlir::Value value, EmissionPrinter &p) = 0;
132
133 /// Emit zero or more statements for the given operation.
134 virtual void emitStatement(mlir::Operation *op, EmissionPrinter &p) = 0;
135};
136
137/// This is intended to be the base class for all emission patterns matching on
138/// types.
140 explicit TypeEmissionPatternBase(TypeID typeId)
141 : PatternBase(typeId.getAsOpaquePointer()) {}
142 virtual ~TypeEmissionPatternBase() = default;
143
144 /// Checks if this pattern is applicable to the given type.
145 virtual bool match(Type type) = 0;
146
147 /// Emit the given type to the emission printer.
148 virtual void emitType(Type type, EmissionPrinter &p) = 0;
149};
150
151/// This is intended to be the base class for all emission patterns matching on
152/// attributes.
154 explicit AttrEmissionPatternBase(TypeID typeId)
155 : PatternBase(typeId.getAsOpaquePointer()) {}
156 virtual ~AttrEmissionPatternBase() = default;
157
158 /// Checks if this pattern is applicable to the given attribute.
159 virtual bool match(Attribute attr) = 0;
160
161 /// Emit the given attribute to the emission printer.
162 virtual void emitAttr(Attribute attr, EmissionPrinter &p) = 0;
163};
164
165/// This is a convenience class providing default implementations for operation
166/// emission patterns.
167template <typename Op>
169 explicit OpEmissionPattern(MLIRContext *context)
170 : OpEmissionPatternBase(Op::getOperationName(), context) {}
171
172 void emitStatement(mlir::Operation *op, EmissionPrinter &p) final {
173 return emitStatement(cast<Op>(op), p);
174 }
175
176 /// Checks if this pattern is applicable to the given value to emit an
177 /// inlinable expression. Additionally returns information such as the
178 /// precedence to the pattern where this pattern's result is to be inlined.
179 /// Defaults to never match.
180 MatchResult matchInlinable(Value value) override { return MatchResult(); }
181
182 /// Checks if this pattern is applicable to the given operation for statement
183 /// emission. When not overriden this matches on all operations of the type
184 /// given as template parameter and emits nothing.
185 bool matchStatement(mlir::Operation *op) override { return isa<Op>(op); }
186
187 /// Emit the expression for the given value. This has to be overriden whenever
188 /// the 'matchInlinable' function is overriden and emit a valid expression.
189 void emitInlined(mlir::Value value, EmissionPrinter &p) override {}
190
191 /// Emit zero (default) or more statements for the given operation.
192 virtual void emitStatement(Op op, EmissionPrinter &p) {}
193};
194
195/// This is a convenience class providing default implementations for type
196/// emission patterns.
197template <typename Ty>
200
201 void emitType(Type type, EmissionPrinter &p) final {
202 emitType(cast<Ty>(type), p);
203 }
204
205 /// Checks if this pattern is applicable to the given type. Matches to the
206 /// type given as template argument by default.
207 bool match(Type type) override { return isa<Ty>(type); }
208
209 /// Emit the given type to the emission printer.
210 virtual void emitType(Ty type, EmissionPrinter &p) = 0;
211};
212
213/// This is a convenience class providing default implementations for attribute
214/// emission patterns.
215template <typename A>
218
219 void emitAttr(Attribute attr, EmissionPrinter &p) final {
220 emitAttr(cast<A>(attr), p);
221 }
222
223 /// Checks if this pattern is applicable to the given attribute. Matches to
224 /// the attribute given as template argument by default.
225 bool match(Attribute attr) override { return isa<A>(attr); }
226
227 /// Emit the given attribute to the emission printer.
228 virtual void emitAttr(A attr, EmissionPrinter &p) = 0;
229};
230
231//===----------------------------------------------------------------------===//
232// Emission pattern sets.
233//===----------------------------------------------------------------------===//
234
235/// This class collects a set of emission patterns with base type 'PatternTy'.
236template <typename PatternTy>
238public:
239 /// Add a new emission pattern that requires additional constructor arguments
240 /// to this set.
241 template <typename... Es, typename ConstructorArg,
242 typename... ConstructorArgs,
243 typename = std::enable_if_t<sizeof...(Es) != 0>>
244 void add(ConstructorArg &&arg, ConstructorArgs &&...args) {
245 (void)std::initializer_list<int>{
246 0, (addImpl<Es>(std::forward<ConstructorArg>(arg),
247 std::forward<ConstructorArgs>(args)...),
248 0)...};
249 }
250
251 /// Add a new emission pattern to the set.
252 template <typename... Es, typename = std::enable_if_t<sizeof...(Es) != 0>>
253 void add() {
254 (void)std::initializer_list<int>{0, (addImpl<Es>(), 0)...};
255 }
256
257 /// Get all the emission patterns added to this set.
258 std::vector<std::unique_ptr<PatternTy>> &getNativePatterns() {
259 return patterns;
260 }
261
262private:
263 template <typename E, typename... Args>
264 std::enable_if_t<std::is_base_of<PatternTy, E>::value>
265 addImpl(Args &&...args) {
266 std::unique_ptr<E> pattern =
267 PatternBase::create<E>(std::forward<Args>(args)...);
268 patterns.emplace_back(std::move(pattern));
269 }
270
271private:
272 std::vector<std::unique_ptr<PatternTy>> patterns;
273};
274
275/// This class intends to collect a set of emission patterns in a way to provide
276/// fast lookups, but does not allow to add more patterns after construction.
277template <typename PatternTy, typename KeyTy>
279 using NativePatternListT = std::vector<std::unique_ptr<PatternTy>>;
280
281public:
282 /// A map of type specific native patterns.
284 DenseMap<KeyTy, std::vector<PatternTy *>>;
285
286 FrozenEmissionPatternSet() : impl(std::make_shared<Impl>()) {}
287
288 /// Freeze the patterns held in `patterns`, and take ownership.
290 : impl(std::make_shared<Impl>()) {
291 for (std::unique_ptr<PatternTy> &pat : patterns.getNativePatterns()) {
292 impl->nativeOpSpecificPatternMap[KeyTy::getFromOpaquePointer(
293 pat->getRootValue())]
294 .push_back(pat.get());
295 impl->nativeOpSpecificPatternList.push_back(std::move(pat));
296 }
297 }
298
299 /// Return the native patterns held by this set.
301 return impl->nativeOpSpecificPatternMap;
302 }
303
304private:
305 /// The internal implementation of the frozen pattern set.
306 struct Impl {
307 /// The set of emission patterns that are matched to specific kinds.
309
310 /// The full native rewrite list. This allows for the map above
311 /// to contain duplicate patterns, e.g. for interfaces and traits.
313 };
314
315 /// A pointer to the internal pattern list. This uses a shared_ptr to avoid
316 /// the need to compile the same pattern list multiple times. For example,
317 /// during multi-threaded pass execution, all copies of a pass can share the
318 /// same pattern list.
319 std::shared_ptr<Impl> impl;
320};
321
322} // namespace ExportSystemC
323} // namespace circt
324
325#endif // CIRCT_TARGET_EXPORTSYSTEMC_EMISSIONPATTERN_H
RewritePatternSet pattern
This class collects a set of emission patterns with base type 'PatternTy'.
std::vector< std::unique_ptr< PatternTy > > patterns
std::vector< std::unique_ptr< PatternTy > > & getNativePatterns()
Get all the emission patterns added to this set.
void add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add a new emission pattern that requires additional constructor arguments to this set.
void add()
Add a new emission pattern to the set.
std::enable_if_t< std::is_base_of< PatternTy, E >::value > addImpl(Args &&...args)
This is intended to be the driving class for all pattern-based IR emission.
This class intends to collect a set of emission patterns in a way to provide fast lookups,...
DenseMap< KeyTy, std::vector< PatternTy * > > OpSpecificNativePatternListT
A map of type specific native patterns.
std::vector< std::unique_ptr< PatternTy > > NativePatternListT
std::shared_ptr< Impl > impl
A pointer to the internal pattern list.
const OpSpecificNativePatternListT & getSpecificNativePatterns() const
Return the native patterns held by this set.
FrozenEmissionPatternSet(EmissionPatternSet< PatternTy > &&patterns)
Freeze the patterns held in patterns, and take ownership.
This class allows a pattern's match function for inlining to pass its result's precedence to the patt...
MatchResult(Precedence precedence)
This is indented to be the base class for all emission patterns.
PatternBase(const void *rootValue)
const void * getRootValue() const
Get a unique identifier for the C++ type the pattern is matching on.
static std::unique_ptr< E > create(Args &&...args)
Precedence
This enum encodes the precedence of C++ expressions.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
This is intended to be the base class for all emission patterns matching on attributes.
virtual bool match(Attribute attr)=0
Checks if this pattern is applicable to the given attribute.
virtual void emitAttr(Attribute attr, EmissionPrinter &p)=0
Emit the given attribute to the emission printer.
This is a convenience class providing default implementations for attribute emission patterns.
bool match(Attribute attr) override
Checks if this pattern is applicable to the given attribute.
virtual void emitAttr(A attr, EmissionPrinter &p)=0
Emit the given attribute to the emission printer.
void emitAttr(Attribute attr, EmissionPrinter &p) final
Emit the given attribute to the emission printer.
The internal implementation of the frozen pattern set.
OpSpecificNativePatternListT nativeOpSpecificPatternMap
The set of emission patterns that are matched to specific kinds.
NativePatternListT nativeOpSpecificPatternList
The full native rewrite list.
This is intended to be the base class for all emission patterns matching on operations.
virtual void emitInlined(mlir::Value value, EmissionPrinter &p)=0
Emit the expression for the given value.
OpEmissionPatternBase(StringRef operationName, MLIRContext *context)
virtual bool matchStatement(mlir::Operation *op)=0
Checks if this pattern is applicable to the given operation for statement emission.
virtual void emitStatement(mlir::Operation *op, EmissionPrinter &p)=0
Emit zero or more statements for the given operation.
virtual MatchResult matchInlinable(Value value)=0
Checks if this pattern is applicable to the given value to emit an inlinable expression.
This is a convenience class providing default implementations for operation emission patterns.
void emitInlined(mlir::Value value, EmissionPrinter &p) override
Emit the expression for the given value.
bool matchStatement(mlir::Operation *op) override
Checks if this pattern is applicable to the given operation for statement emission.
void emitStatement(mlir::Operation *op, EmissionPrinter &p) final
Emit zero or more statements for the given operation.
virtual void emitStatement(Op op, EmissionPrinter &p)
Emit zero (default) or more statements for the given operation.
MatchResult matchInlinable(Value value) override
Checks if this pattern is applicable to the given value to emit an inlinable expression.
This is intended to be the base class for all emission patterns matching on types.
virtual bool match(Type type)=0
Checks if this pattern is applicable to the given type.
virtual void emitType(Type type, EmissionPrinter &p)=0
Emit the given type to the emission printer.
This is a convenience class providing default implementations for type emission patterns.
void emitType(Type type, EmissionPrinter &p) final
Emit the given type to the emission printer.
virtual void emitType(Ty type, EmissionPrinter &p)=0
Emit the given type to the emission printer.
bool match(Type type) override
Checks if this pattern is applicable to the given type.