17 #include "llvm/Support/FormatVariadic.h"
18 #include "llvm/Support/Path.h"
19 #include "llvm/TableGen/CodeGenHelpers.h"
20 #include "llvm/TableGen/Record.h"
31 StringRef inputFilename = records.getInputFilename();
34 StringRef nameRef = sys::path::filename(inputFilename);
35 nameRef.consume_back(
".td");
38 std::string uniqueName(tag);
39 for (
char c : nameRef) {
40 if (isAlnum(c) || c ==
'_')
41 uniqueName.push_back(c);
43 uniqueName.append(utohexstr((
unsigned char)c));
48 StaticVerifierFunctionEmitter::StaticVerifierFunctionEmitter(
49 raw_ostream &os,
const RecordKeeper &records, StringRef tag)
54 NamespaceEmitter namespaceEmitter(os,
Operator(*opDefs[0]).getCppNamespace());
55 emitTypeConstraints();
56 emitAttrConstraints();
57 emitPropConstraints();
58 emitSuccessorConstraints();
59 emitRegionConstraints();
62 void StaticVerifierFunctionEmitter::emitPatternConstraints(
64 collectPatternConstraints(constraints);
74 const auto *it = typeConstraints.find(constraint);
75 assert(it != typeConstraints.end() &&
"expected to find a type constraint");
83 const auto *it = attrConstraints.find(constraint);
84 return it == attrConstraints.end() ? std::optional<StringRef>()
85 : StringRef(it->second);
92 const auto *it = propConstraints.find(constraint);
93 return it == propConstraints.end() ? std::optional<StringRef>()
94 : StringRef(it->second);
99 const auto *it = successorConstraints.find(constraint);
100 assert(it != successorConstraints.end() &&
101 "expected to find a sucessor constraint");
107 const auto *it = regionConstraints.find(constraint);
108 assert(it != regionConstraints.end() &&
109 "expected to find a region constraint");
127 static ::llvm::LogicalResult {0}(
128 ::mlir::Operation *op, ::mlir::Type type, ::llvm::StringRef valueKind,
129 unsigned valueIndex) {
131 return op->emitOpError(valueKind) << " #" << valueIndex
132 << " must be {2}, but got " << type;
134 return ::mlir::success();
145 static ::llvm::LogicalResult {0}(
146 ::mlir::Attribute attr, ::llvm::StringRef attrName, llvm::function_ref<::mlir::InFlightDiagnostic()> emitError) {{
148 return emitError() << "attribute '" << attrName
149 << "' failed to satisfy constraint: {2}";
150 return ::mlir::success();
152 static ::llvm::LogicalResult {0}(
153 ::mlir::Operation *op, ::mlir::Attribute attr, ::llvm::StringRef attrName) {{
154 return {0}(attr, attrName, [op]() {{
155 return op->emitOpError();
164 static ::llvm::LogicalResult {0}(
165 {3} prop, ::llvm::StringRef propName, llvm::function_ref<::mlir::InFlightDiagnostic()> emitError) {{
167 return emitError() << "property '" << propName
168 << "' failed to satisfy constraint: {2}";
169 return ::mlir::success();
171 static ::llvm::LogicalResult {0}(
172 ::mlir::Operation *op, {3} prop, ::llvm::StringRef propName) {{
173 return {0}(prop, propName, [op]() {{
174 return op->emitOpError();
181 static ::llvm::LogicalResult {0}(
182 ::mlir::Operation *op, ::mlir::Block *successor,
183 ::llvm::StringRef successorName, unsigned successorIndex) {
185 return op->emitOpError("successor #") << successorIndex << " ('"
186 << successorName << ")' failed to verify constraint: {2}";
188 return ::mlir::success();
195 static ::llvm::LogicalResult {0}(
196 ::mlir::Operation *op, ::mlir::Region ®ion, ::llvm::StringRef regionName,
197 unsigned regionIndex) {
199 return op->emitOpError("region #") << regionIndex
200 << (regionName.empty() ? " " : " ('" + regionName + "') ")
201 << "failed to verify constraint: {2}";
203 return ::mlir::success();
215 static ::llvm::LogicalResult {0}(
216 ::mlir::PatternRewriter &rewriter, ::mlir::Operation *op, {3},
217 ::llvm::StringRef failureStr) {
219 return rewriter.notifyMatchFailure(op, [&](::mlir::Diagnostic &diag) {
220 diag << failureStr << ": {2}";
223 return ::mlir::success();
227 void StaticVerifierFunctionEmitter::emitConstraints(
228 const ConstraintMap &constraints, StringRef selfName,
229 const char *
const codeTemplate) {
232 for (
auto &it : constraints) {
233 os << formatv(codeTemplate, it.second,
234 tgfmt(it.first.getConditionTemplate(), &ctx),
239 void StaticVerifierFunctionEmitter::emitTypeConstraints() {
243 void StaticVerifierFunctionEmitter::emitAttrConstraints() {
249 void StaticVerifierFunctionEmitter::emitPropConstraints() {
252 for (
auto &it : propConstraints) {
253 auto propConstraint = cast<PropConstraint>(it.first);
255 tgfmt(propConstraint.getConditionTemplate(), &ctx),
257 propConstraint.getInterfaceType());
261 void StaticVerifierFunctionEmitter::emitSuccessorConstraints() {
265 void StaticVerifierFunctionEmitter::emitRegionConstraints() {
269 void StaticVerifierFunctionEmitter::emitPatternConstraints() {
272 for (
auto &it : typeConstraints) {
274 tgfmt(it.first.getConditionTemplate(), &ctx),
275 escapeString(it.first.getSummary()),
"::mlir::Type type");
278 for (
auto &it : attrConstraints) {
280 tgfmt(it.first.getConditionTemplate(), &ctx),
282 "::mlir::Attribute attr");
285 for (
auto &it : propConstraints) {
290 if (interfaceType.empty()) {
292 os <<
"template <typename T>";
297 Twine(interfaceType) +
" prop");
312 auto test =
tgfmt(attr.getConditionTemplate(),
315 return !StringRef(test).contains(
"<no-subst-found>");
328 return !StringRef(test).contains(
"<no-subst-found>") && test !=
"true" &&
332 std::string StaticVerifierFunctionEmitter::getUniqueName(StringRef
kind,
334 return (
"__mlir_ods_local_" +
kind +
"_constraint_" + uniqueOutputLabel +
339 void StaticVerifierFunctionEmitter::collectConstraint(ConstraintMap &map,
342 auto [it, inserted] = map.try_emplace(constraint);
344 it->second = getUniqueName(
kind, map.size());
351 if (value.hasPredicate())
352 collectConstraint(typeConstraints,
"type", value.constraint);
355 for (
const Record *def : opDefs) {
362 if (!namedAttr.attr.getPredicate().isNull() &&
363 !namedAttr.attr.isDerivedAttr() &&
365 collectConstraint(attrConstraints,
"attr", namedAttr.attr);
369 if (!namedProp.prop.getPredicate().isNull() &&
371 collectConstraint(propConstraints,
"prop", namedProp.prop);
376 if (!successor.constraint.getPredicate().isNull()) {
377 collectConstraint(successorConstraints,
"successor",
378 successor.constraint);
383 if (!region.constraint.getPredicate().isNull())
384 collectConstraint(regionConstraints,
"region", region.constraint);
388 void StaticVerifierFunctionEmitter::collectPatternConstraints(
390 for (
auto &leaf : constraints) {
391 assert(leaf.isOperandMatcher() || leaf.isAttrMatcher() ||
392 leaf.isPropMatcher());
393 Constraint constraint = leaf.getAsConstraint();
394 if (leaf.isOperandMatcher())
395 collectConstraint(typeConstraints,
"type", constraint);
396 else if (leaf.isAttrMatcher())
397 collectConstraint(attrConstraints,
"attr", constraint);
398 else if (leaf.isPropMatcher())
399 collectConstraint(propConstraints,
"prop", constraint);
409 raw_string_ostream os(ret);
410 os.write_escaped(value);
static const char *const successorConstraintCode
Code for a successor constraint.
static const char *const patternConstraintCode
Code for a pattern type or attribute constraint.
static const char *const regionConstraintCode
Code for a region constraint.
static const char *const typeConstraintCode
Code templates for emitting type, attribute, successor, and region constraints.
static std::string getUniqueOutputLabel(const RecordKeeper &records, StringRef tag)
Generate a unique label based on the current file name to prevent name collisions if multiple generat...
static const char *const propConstraintCode
Code for a property constraint.
static bool canUniqueAttrConstraint(Attribute attr)
An attribute constraint that references anything other than itself and the current op cannot be gener...
static bool canUniquePropConstraint(Property prop)
A property constraint that references anything other than itself and the current op cannot be generic...
static const char *const attrConstraintCode
Code for an attribute constraint.
union mlir::linalg::@1252::ArityGroupAndKind::Kind kind
Attributes are known-constant values of operations.
StringRef getSummary() const
std::string getConditionTemplate() const
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 ...
llvm::iterator_range< const_region_iterator > getRegions() const
const_value_range getResults() const
const_value_range getOperands() const
llvm::iterator_range< const_attribute_iterator > getAttributes() const
llvm::iterator_range< const_successor_iterator > getSuccessors() const
llvm::iterator_range< const_property_iterator > getProperties() const
StringRef getInterfaceType() const
StringRef getInterfaceType() const
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.
void emitOpConstraints(ArrayRef< const llvm::Record * > opDefs)
Collect and unique all compatible type, attribute, successor, and region constraints from the operati...
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.
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.
auto tgfmt(StringRef fmt, const FmtContext *ctx, Ts &&...vals) -> FmtObject< decltype(std::make_tuple(llvm::support::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.