17 #include "llvm/Support/FormatVariadic.h"
18 #include "llvm/Support/Path.h"
19 #include "llvm/TableGen/Record.h"
29 std::string inputFilename = records.getInputFilename();
32 StringRef nameRef = llvm::sys::path::filename(inputFilename);
33 nameRef.consume_back(
".td");
36 std::string uniqueName;
37 for (
char c : nameRef) {
38 if (llvm::isAlnum(c) || c ==
'_')
39 uniqueName.push_back(c);
41 uniqueName.append(llvm::utohexstr((
unsigned char)c));
46 StaticVerifierFunctionEmitter::StaticVerifierFunctionEmitter(
47 raw_ostream &os,
const llvm::RecordKeeper &records)
52 collectOpConstraints(opDefs);
57 emitTypeConstraints();
58 emitAttrConstraints();
59 emitSuccessorConstraints();
60 emitRegionConstraints();
63 void StaticVerifierFunctionEmitter::emitPatternConstraints(
65 collectPatternConstraints(constraints);
74 auto it = typeConstraints.find(constraint);
75 assert(it != typeConstraints.end() &&
"expected to find a type constraint");
83 auto it = attrConstraints.find(constraint);
84 return it == attrConstraints.end() ? std::optional<StringRef>()
85 : StringRef(it->second);
90 auto it = successorConstraints.find(constraint);
91 assert(it != successorConstraints.end() &&
92 "expected to find a sucessor constraint");
98 auto it = regionConstraints.find(constraint);
99 assert(it != regionConstraints.end() &&
100 "expected to find a region constraint");
117 static ::mlir::LogicalResult {0}(
118 ::mlir::Operation *op, ::mlir::Type type, ::llvm::StringRef valueKind,
119 unsigned valueIndex) {
121 return op->emitOpError(valueKind) << " #" << valueIndex
122 << " must be {2}, but got " << type;
124 return ::mlir::success();
135 static ::mlir::LogicalResult {0}(
136 ::mlir::Attribute attr, ::llvm::StringRef attrName, llvm::function_ref<::mlir::InFlightDiagnostic()> emitError) {{
138 return emitError() << "attribute '" << attrName
139 << "' failed to satisfy constraint: {2}";
140 return ::mlir::success();
142 static ::mlir::LogicalResult {0}(
143 ::mlir::Operation *op, ::mlir::Attribute attr, ::llvm::StringRef attrName) {{
144 return {0}(attr, attrName, [op]() {{
145 return op->emitOpError();
152 static ::mlir::LogicalResult {0}(
153 ::mlir::Operation *op, ::mlir::Block *successor,
154 ::llvm::StringRef successorName, unsigned successorIndex) {
156 return op->emitOpError("successor #") << successorIndex << " ('"
157 << successorName << ")' failed to verify constraint: {2}";
159 return ::mlir::success();
166 static ::mlir::LogicalResult {0}(
167 ::mlir::Operation *op, ::mlir::Region ®ion, ::llvm::StringRef regionName,
168 unsigned regionIndex) {
170 return op->emitOpError("region #") << regionIndex
171 << (regionName.empty() ? " " : " ('" + regionName + "') ")
172 << "failed to verify constraint: {2}";
174 return ::mlir::success();
182 static ::mlir::LogicalResult {0}(
183 ::mlir::PatternRewriter &rewriter, ::mlir::Operation *op, ::mlir::{3},
184 ::llvm::StringRef failureStr) {
186 return rewriter.notifyMatchFailure(op, [&](::mlir::Diagnostic &diag) {
187 diag << failureStr << ": {2}";
190 return ::mlir::success();
194 void StaticVerifierFunctionEmitter::emitConstraints(
195 const ConstraintMap &constraints, StringRef selfName,
196 const char *
const codeTemplate) {
199 for (
auto &it : constraints) {
200 os << formatv(codeTemplate, it.second,
201 tgfmt(it.first.getConditionTemplate(), &ctx),
206 void StaticVerifierFunctionEmitter::emitTypeConstraints() {
210 void StaticVerifierFunctionEmitter::emitAttrConstraints() {
214 void StaticVerifierFunctionEmitter::emitSuccessorConstraints() {
218 void StaticVerifierFunctionEmitter::emitRegionConstraints() {
222 void StaticVerifierFunctionEmitter::emitPatternConstraints() {
225 for (
auto &it : typeConstraints) {
227 tgfmt(it.first.getConditionTemplate(), &ctx),
231 for (
auto &it : attrConstraints) {
233 tgfmt(it.first.getConditionTemplate(), &ctx),
248 auto test =
tgfmt(attr.getConditionTemplate(),
251 return !StringRef(test).contains(
"<no-subst-found>");
254 std::string StaticVerifierFunctionEmitter::getUniqueName(StringRef kind,
256 return (
"__mlir_ods_local_" + kind +
"_constraint_" + uniqueOutputLabel +
261 void StaticVerifierFunctionEmitter::collectConstraint(ConstraintMap &map,
264 auto it = map.find(constraint);
266 map.insert({constraint, getUniqueName(kind, map.size())});
269 void StaticVerifierFunctionEmitter::collectOpConstraints(
273 if (value.hasPredicate())
274 collectConstraint(typeConstraints,
"type", value.constraint);
277 for (Record *def : opDefs) {
284 if (!namedAttr.attr.getPredicate().isNull() &&
285 !namedAttr.attr.isDerivedAttr() &&
287 collectConstraint(attrConstraints,
"attr", namedAttr.attr);
291 if (!successor.constraint.getPredicate().isNull()) {
292 collectConstraint(successorConstraints,
"successor",
293 successor.constraint);
298 if (!region.constraint.getPredicate().isNull())
299 collectConstraint(regionConstraints,
"region", region.constraint);
303 void StaticVerifierFunctionEmitter::collectPatternConstraints(
305 for (
auto &leaf : constraints) {
306 assert(leaf.isOperandMatcher() || leaf.isAttrMatcher());
308 leaf.isOperandMatcher() ? typeConstraints : attrConstraints,
309 leaf.isOperandMatcher() ?
"type" :
"attr", leaf.getAsConstraint());
319 llvm::raw_string_ostream os(ret);
320 os.write_escaped(value);
static const char *const successorConstraintCode
Code for a successor constraint.
static const char *const regionConstraintCode
Code for a region constraint.
static std::string getUniqueOutputLabel(const llvm::RecordKeeper &records)
Generate a unique label based on the current file name to prevent name collisions if multiple generat...
static const char *const typeConstraintCode
Code templates for emitting type, attribute, successor, and region constraints.
static const char *const patternAttrOrTypeConstraintCode
Code for a pattern type or attribute constraint.
static bool canUniqueAttrConstraint(Attribute attr)
An attribute constraint that references anything other than itself and the current op cannot be gener...
static const char *const attrConstraintCode
Code for an attribute constraint.
Attributes are known-constant values of operations.
NamedAttribute represents a combination of a name and an Attribute value.
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
operand_range getOperands()
Returns an iterator on the underlying Value's.
SuccessorRange getSuccessors()
result_range getResults()
Format context containing substitutions for special placeholders.
FmtContext & withBuilder(Twine subst)
FmtContext & withSelf(Twine subst)
FmtContext & addSubst(StringRef placeholder, const Twine &subst)
Wrapper class that contains a MLIR op's information (e.g., operands, attributes) defined in TableGen ...
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 ...
void emitOpConstraints(ArrayRef< llvm::Record * > opDefs, bool emitDecl)
Collect and unique all compatible type, attribute, successor, and region constraints from the operati...
std::optional< StringRef > getAttrConstraintFn(const Constraint &constraint) const
Get the name of the static function used for the given attribute constraint.
StringRef getTypeConstraintFn(const Constraint &constraint) const
Get the name of the static function used for the given type constraint.
StringRef getSuccessorConstraintFn(const Constraint &constraint) const
Get the name of the static function used for the given successor constraint.
Include the generated interface declarations.
auto tgfmt(StringRef fmt, const FmtContext *ctx, Ts &&...vals) -> FmtObject< decltype(std::make_tuple(llvm::detail::build_format_adapter(std::forward< Ts >(vals))...))>
Formats text by substituting placeholders in format string with replacement parameters.
std::string escapeString(StringRef value)
Escape a string using C++ encoding. E.g. foo"bar -> foo\x22bar.
Include the generated interface declarations.