MLIR  22.0.0git
CodeGenHelpers.h
Go to the documentation of this file.
1 //===----------------------------------------------------------------------===//
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 file defines common utilities for generating C++ from tablegen
10 // structures.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_TABLEGEN_CODEGENHELPERS_H
15 #define MLIR_TABLEGEN_CODEGENHELPERS_H
16 
18 #include "mlir/TableGen/Dialect.h"
19 #include "mlir/TableGen/Format.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/MapVector.h"
22 #include "llvm/ADT/StringExtras.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/TableGen/CodeGenHelpers.h"
25 #include <utility>
26 
27 namespace llvm {
28 class RecordKeeper;
29 } // namespace llvm
30 
31 namespace mlir {
32 namespace tblgen {
33 class Constraint;
34 class DagLeaf;
35 
36 // Format into a std::string
37 template <typename... Parameters>
38 std::string strfmt(const char *fmt, Parameters &&...parameters) {
39  return llvm::formatv(fmt, std::forward<Parameters>(parameters)...).str();
40 }
41 
42 // A helper RAII class to emit nested namespaces for a dialect.
44 public:
45  DialectNamespaceEmitter(raw_ostream &os, const Dialect &dialect) {
46  if (!dialect)
47  return;
48  nsEmitter.emplace(os, dialect.getCppNamespace());
49  }
50 
51 private:
52  std::optional<llvm::NamespaceEmitter> nsEmitter;
53 };
54 
55 /// This class deduplicates shared operation verification code by emitting
56 /// static functions alongside the op definitions. These methods are local to
57 /// the definition file, and are invoked within the operation verify methods.
58 /// An example is shown below:
59 ///
60 /// static LogicalResult localVerify(...)
61 ///
62 /// LogicalResult OpA::verify(...) {
63 /// if (failed(localVerify(...)))
64 /// return failure();
65 /// ...
66 /// }
67 ///
68 /// LogicalResult OpB::verify(...) {
69 /// if (failed(localVerify(...)))
70 /// return failure();
71 /// ...
72 /// }
73 ///
75 public:
76  /// Create a constraint uniquer with a unique prefix derived from the record
77  /// keeper with an optional tag.
78  StaticVerifierFunctionEmitter(raw_ostream &os,
79  const llvm::RecordKeeper &records,
80  StringRef tag = "");
81 
82  /// Collect and unique all the constraints used by operations.
84 
85  /// Collect and unique all compatible type, attribute, successor, and region
86  /// constraints from the operations in the file and emit them at the top of
87  /// the generated file.
88  ///
89  /// Constraints that do not meet the restriction that they can only reference
90  /// `$_self` and `$_op` are not uniqued.
91  void emitOpConstraints();
92 
93  /// Unique all compatible type and attribute constraints from a pattern file
94  /// and emit them at the top of the generated file.
95  ///
96  /// Constraints that do not meet the restriction that they can only reference
97  /// `$_self`, `$_op`, and `$_builder` are not uniqued.
98  void emitPatternConstraints(const ArrayRef<DagLeaf> constraints);
99 
100  /// Get the name of the static function used for the given type constraint.
101  /// These functions are used for operand and result constraints and have the
102  /// form:
103  ///
104  /// LogicalResult(Operation *op, Type type, StringRef valueKind,
105  /// unsigned valueIndex);
106  ///
107  /// Pattern constraints have the form:
108  ///
109  /// LogicalResult(PatternRewriter &rewriter, Operation *op, Type type,
110  /// StringRef failureStr);
111  ///
112  StringRef getTypeConstraintFn(const Constraint &constraint) const;
113 
114  /// Get the name of the static function used for the given attribute
115  /// constraint. These functions are in the form:
116  ///
117  /// LogicalResult(Operation *op, Attribute attr, StringRef attrName);
118  ///
119  /// If a uniqued constraint was not found, this function returns std::nullopt.
120  /// The uniqued constraints cannot be used in the context of an OpAdaptor.
121  ///
122  /// Pattern constraints have the form:
123  ///
124  /// LogicalResult(PatternRewriter &rewriter, Operation *op, Attribute attr,
125  /// StringRef failureStr);
126  ///
127  std::optional<StringRef>
128  getAttrConstraintFn(const Constraint &constraint) const;
129 
130  /// Get the name of the static function used for the given property
131  /// constraint. These functions are in the form:
132  ///
133  /// LogicalResult(Operation *op, T property, StringRef propName);
134  ///
135  /// where T is the interface type specified in the constraint.
136  /// If a uniqued constraint was not found, this function returns std::nullopt.
137  /// The uniqued constraints cannot be used in the context of an OpAdaptor.
138  ///
139  /// Pattern constraints have the form:
140  ///
141  /// LogicalResult(PatternRewriter &rewriter, Operation *op, T property,
142  /// StringRef failureStr);
143  ///
144  std::optional<StringRef>
145  getPropConstraintFn(const Constraint &constraint) const;
146 
147  /// Get the name of the static function used for the given successor
148  /// constraint. These functions are in the form:
149  ///
150  /// LogicalResult(Operation *op, Block *successor, StringRef successorName,
151  /// unsigned successorIndex);
152  ///
153  StringRef getSuccessorConstraintFn(const Constraint &constraint) const;
154 
155  /// Get the name of the static function used for the given region constraint.
156  /// These functions are in the form:
157  ///
158  /// LogicalResult(Operation *op, Region &region, StringRef regionName,
159  /// unsigned regionIndex);
160  ///
161  /// The region name may be empty.
162  StringRef getRegionConstraintFn(const Constraint &constraint) const;
163 
164 private:
165  /// Emit static type constraint functions.
166  void emitTypeConstraints();
167  /// Emit static attribute constraint functions.
168  void emitAttrConstraints();
169  /// Emit static property constraint functions.
170  void emitPropConstraints();
171  /// Emit static successor constraint functions.
172  void emitSuccessorConstraints();
173  /// Emit static region constraint functions.
174  void emitRegionConstraints();
175 
176  /// Emit pattern constraints.
177  void emitPatternConstraints();
178 
179  /// Collect and unique all pattern constraints.
180  void collectPatternConstraints(ArrayRef<DagLeaf> constraints);
181 
182  /// The output stream.
183  raw_ostream &os;
184 
185  /// A unique label for the file currently being generated. This is used to
186  /// ensure that the static functions have a unique name.
187  std::string uniqueOutputLabel;
188 
189  /// Use a MapVector to ensure that functions are generated deterministically.
190  using ConstraintMap = llvm::MapVector<Constraint, std::string,
192 
193  /// A generic function to emit constraints
194  void emitConstraints(const ConstraintMap &constraints, StringRef selfName,
195  const char *codeTemplate);
196 
197  /// Assign a unique name to a unique constraint.
198  std::string getUniqueName(StringRef kind, unsigned index);
199  /// Unique a constraint in the map.
200  void collectConstraint(ConstraintMap &map, StringRef kind,
201  Constraint constraint);
202 
203  /// The set of type constraints used for operand and result verification in
204  /// the current file.
205  ConstraintMap typeConstraints;
206  /// The set of attribute constraints used in the current file.
207  ConstraintMap attrConstraints;
208  /// The set of property constraints used in the current file.
209  ConstraintMap propConstraints;
210  /// The set of successor constraints used in the current file.
211  ConstraintMap successorConstraints;
212  /// The set of region constraints used in the current file.
213  ConstraintMap regionConstraints;
214 };
215 
216 /// Escape a string using C++ encoding. E.g. foo"bar -> foo\x22bar.
217 std::string escapeString(StringRef value);
218 
219 namespace detail {
220 template <typename>
221 struct stringifier {
222  template <typename T>
223  static std::string apply(T &&t) {
224  return std::string(std::forward<T>(t));
225  }
226 };
227 template <>
228 struct stringifier<Twine> {
229  static std::string apply(const Twine &twine) { return twine.str(); }
230 };
231 template <typename OptionalT>
232 struct stringifier<std::optional<OptionalT>> {
233  static std::string apply(std::optional<OptionalT> optional) {
234  return optional ? stringifier<OptionalT>::apply(*optional) : std::string();
235  }
236 };
237 } // namespace detail
238 
239 /// Generically convert a value to a std::string.
240 template <typename T>
241 std::string stringify(T &&t) {
243  apply(std::forward<T>(t));
244 }
245 
246 } // namespace tblgen
247 } // namespace mlir
248 
249 #endif // MLIR_TABLEGEN_CODEGENHELPERS_H
union mlir::linalg::@1252::ArityGroupAndKind::Kind kind
DialectNamespaceEmitter(raw_ostream &os, const Dialect &dialect)
StringRef getCppNamespace() const
Definition: Dialect.cpp:28
This class deduplicates shared operation verification code by emitting static functions alongside the...
StringRef getRegionConstraintFn(const Constraint &constraint) const
Get the name of the static function used for the given region constraint.
void emitPatternConstraints(const ArrayRef< DagLeaf > constraints)
Unique all compatible type and attribute constraints from a pattern file and emit them at the top of ...
std::optional< StringRef > getAttrConstraintFn(const Constraint &constraint) const
Get the name of the static function used for the given attribute constraint.
std::optional< StringRef > getPropConstraintFn(const Constraint &constraint) const
Get the name of the static function used for the given property constraint.
StaticVerifierFunctionEmitter(raw_ostream &os, const llvm::RecordKeeper &records, StringRef tag="")
Create a constraint uniquer with a unique prefix derived from the record keeper with an optional tag.
void collectOpConstraints(ArrayRef< const llvm::Record * > opDefs)
Collect and unique all the constraints used by operations.
StringRef getTypeConstraintFn(const Constraint &constraint) const
Get the name of the static function used for the given type constraint.
void emitOpConstraints()
Collect and unique all compatible type, attribute, successor, and region constraints from the operati...
StringRef getSuccessorConstraintFn(const Constraint &constraint) const
Get the name of the static function used for the given successor constraint.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
std::string escapeString(StringRef value)
Escape a string using C++ encoding. E.g. foo"bar -> foo\x22bar.
std::string strfmt(const char *fmt, Parameters &&...parameters)
std::string stringify(T &&t)
Generically convert a value to a std::string.
Include the generated interface declarations.
static std::string apply(const Twine &twine)
static std::string apply(std::optional< OptionalT > optional)
static std::string apply(T &&t)