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
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
27namespace llvm {
28class RecordKeeper;
29} // namespace llvm
30
31namespace mlir {
32namespace tblgen {
33class Constraint;
34class DagLeaf;
35
36// Format into a std::string
37template <typename... Parameters>
38std::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.
44public:
46 if (!dialect)
47 return;
48 nsEmitter.emplace(os, dialect.getCppNamespace());
49 }
50
51private:
52 std::optional<llvm::NamespaceEmitter> nsEmitter;
53};
54
55/// This class represents how an error stream string being constructed will be
56/// consumed.
57enum class ErrorStreamType {
58 // Inside a string that's streamed into an InflightDiagnostic.
60 // Inside a string inside an OpError.
62};
63
64/// This class deduplicates shared operation verification code by emitting
65/// static functions alongside the op definitions. These methods are local to
66/// the definition file, and are invoked within the operation verify methods.
67/// An example is shown below:
68///
69/// static LogicalResult localVerify(...)
70///
71/// LogicalResult OpA::verify(...) {
72/// if (failed(localVerify(...)))
73/// return failure();
74/// ...
75/// }
76///
77/// LogicalResult OpB::verify(...) {
78/// if (failed(localVerify(...)))
79/// return failure();
80/// ...
81/// }
82///
84public:
85 /// Create a constraint uniquer with a unique prefix derived from the record
86 /// keeper with an optional tag.
88 const llvm::RecordKeeper &records,
89 StringRef tag = "");
90
91 /// Collect and unique all the constraints used by operations.
93
94 /// Collect and unique all compatible type, attribute, successor, and region
95 /// constraints from the operations in the file and emit them at the top of
96 /// the generated file.
97 ///
98 /// Constraints that do not meet the restriction that they can only reference
99 /// `$_self` and `$_op` are not uniqued.
100 void emitOpConstraints();
101
102 /// Unique all compatible type and attribute constraints from a pattern file
103 /// and emit them at the top of the generated file.
104 ///
105 /// Constraints that do not meet the restriction that they can only reference
106 /// `$_self`, `$_op`, and `$_builder` are not uniqued.
107 void emitPatternConstraints(const ArrayRef<DagLeaf> constraints);
108
109 /// Get the name of the static function used for the given type constraint.
110 /// These functions are used for operand and result constraints and have the
111 /// form:
112 ///
113 /// LogicalResult(Operation *op, Type type, StringRef valueKind,
114 /// unsigned valueIndex);
115 ///
116 /// Pattern constraints have the form:
117 ///
118 /// LogicalResult(PatternRewriter &rewriter, Operation *op, Type type,
119 /// StringRef failureStr);
120 ///
121 StringRef getTypeConstraintFn(const Constraint &constraint) const;
122
123 /// Get the name of the static function used for the given attribute
124 /// constraint. These functions are in the form:
125 ///
126 /// LogicalResult(Operation *op, Attribute attr, StringRef attrName);
127 ///
128 /// If a uniqued constraint was not found, this function returns std::nullopt.
129 /// The uniqued constraints cannot be used in the context of an OpAdaptor.
130 ///
131 /// Pattern constraints have the form:
132 ///
133 /// LogicalResult(PatternRewriter &rewriter, Operation *op, Attribute attr,
134 /// StringRef failureStr);
135 ///
136 std::optional<StringRef>
137 getAttrConstraintFn(const Constraint &constraint) const;
138
139 /// Get the name of the static function used for the given property
140 /// constraint. These functions are in the form:
141 ///
142 /// LogicalResult(Operation *op, T property, StringRef propName);
143 ///
144 /// where T is the interface type specified in the constraint.
145 /// If a uniqued constraint was not found, this function returns std::nullopt.
146 /// The uniqued constraints cannot be used in the context of an OpAdaptor.
147 ///
148 /// Pattern constraints have the form:
149 ///
150 /// LogicalResult(PatternRewriter &rewriter, Operation *op, T property,
151 /// StringRef failureStr);
152 ///
153 std::optional<StringRef>
154 getPropConstraintFn(const Constraint &constraint) const;
155
156 /// Get the name of the static function used for the given successor
157 /// constraint. These functions are in the form:
158 ///
159 /// LogicalResult(Operation *op, Block *successor, StringRef successorName,
160 /// unsigned successorIndex);
161 ///
162 StringRef getSuccessorConstraintFn(const Constraint &constraint) const;
163
164 /// Get the name of the static function used for the given region constraint.
165 /// These functions are in the form:
166 ///
167 /// LogicalResult(Operation *op, Region &region, StringRef regionName,
168 /// unsigned regionIndex);
169 ///
170 /// The region name may be empty.
171 StringRef getRegionConstraintFn(const Constraint &constraint) const;
172
173private:
174 /// Emit static type constraint functions.
175 void emitTypeConstraints();
176 /// Emit static attribute constraint functions.
177 void emitAttrConstraints();
178 /// Emit static property constraint functions.
179 void emitPropConstraints();
180 /// Emit static successor constraint functions.
181 void emitSuccessorConstraints();
182 /// Emit static region constraint functions.
183 void emitRegionConstraints();
184
185 /// Emit pattern constraints.
187
188 /// Collect and unique all pattern constraints.
189 void collectPatternConstraints(ArrayRef<DagLeaf> constraints);
190
191 /// The output stream.
192 raw_ostream &os;
193
194 /// A unique label for the file currently being generated. This is used to
195 /// ensure that the static functions have a unique name.
196 std::string uniqueOutputLabel;
197
198 /// Use a MapVector to ensure that functions are generated deterministically.
199 using ConstraintMap = llvm::MapVector<Constraint, std::string,
201
202 /// A generic function to emit constraints
203 void emitConstraints(const ConstraintMap &constraints, StringRef selfName,
204 const char *codeTemplate,
205 ErrorStreamType errorStreamType);
206
207 /// Assign a unique name to a unique constraint.
208 std::string getUniqueName(StringRef kind, unsigned index);
209 /// Unique a constraint in the map.
210 void collectConstraint(ConstraintMap &map, StringRef kind,
211 Constraint constraint);
212
213 /// The set of type constraints used for operand and result verification in
214 /// the current file.
215 ConstraintMap typeConstraints;
216 /// The set of attribute constraints used in the current file.
217 ConstraintMap attrConstraints;
218 /// The set of property constraints used in the current file.
219 ConstraintMap propConstraints;
220 /// The set of successor constraints used in the current file.
221 ConstraintMap successorConstraints;
222 /// The set of region constraints used in the current file.
223 ConstraintMap regionConstraints;
224};
225
226/// Escape a string using C++ encoding. E.g. foo"bar -> foo\x22bar.
227std::string escapeString(StringRef value);
228
229namespace detail {
230template <typename>
232 template <typename T>
233 static std::string apply(T &&t) {
234 return std::string(std::forward<T>(t));
235 }
236};
237template <>
238struct stringifier<Twine> {
239 static std::string apply(const Twine &twine) { return twine.str(); }
240};
241template <typename OptionalT>
242struct stringifier<std::optional<OptionalT>> {
243 static std::string apply(std::optional<OptionalT> optional) {
244 return optional ? stringifier<OptionalT>::apply(*optional) : std::string();
245 }
246};
247} // namespace detail
248
249/// Generically convert a value to a std::string.
250template <typename T>
251std::string stringify(T &&t) {
253 apply(std::forward<T>(t));
254}
255
256/// Helper to generate a C++ streaming error message from a given message.
257/// Message can contain '{{...}}' placeholders that are substituted with
258/// C-expressions via tgfmt. It would effectively convert:
259/// "failed to verify {{foo}}"
260/// into:
261/// "failed to verify " << bar
262/// where bar is the result of evaluating 'tgfmt("foo", &ctx)' at compile
263/// time.
264std::string buildErrorStreamingString(
265 StringRef message, const FmtContext &ctx,
267
268} // namespace tblgen
269} // namespace mlir
270
271#endif // MLIR_TABLEGEN_CODEGENHELPERS_H
DialectNamespaceEmitter(raw_ostream &os, const Dialect &dialect)
StringRef getCppNamespace() const
Definition Dialect.cpp:28
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 buildErrorStreamingString(StringRef message, const FmtContext &ctx, ErrorStreamType errorStreamType=ErrorStreamType::InString)
Helper to generate a C++ streaming error message from a given message.
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)
ErrorStreamType
This class represents how an error stream string being constructed will be consumed.
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)