17 #include "llvm/Support/FormatVariadic.h"
18 #include "llvm/Support/Path.h"
19 #include "llvm/TableGen/Record.h"
30 std::string inputFilename = records.getInputFilename();
33 StringRef nameRef = llvm::sys::path::filename(inputFilename);
34 nameRef.consume_back(
".td");
37 std::string uniqueName(tag);
38 for (
char c : nameRef) {
39 if (llvm::isAlnum(c) || c ==
'_')
40 uniqueName.push_back(c);
42 uniqueName.append(llvm::utohexstr((
unsigned char)c));
47 StaticVerifierFunctionEmitter::StaticVerifierFunctionEmitter(
48 raw_ostream &os,
const llvm::RecordKeeper &records, StringRef tag)
54 emitTypeConstraints();
55 emitAttrConstraints();
56 emitSuccessorConstraints();
57 emitRegionConstraints();
60 void StaticVerifierFunctionEmitter::emitPatternConstraints(
62 collectPatternConstraints(constraints);
71 const auto *it = typeConstraints.find(constraint);
72 assert(it != typeConstraints.end() &&
"expected to find a type constraint");
80 const auto *it = attrConstraints.find(constraint);
81 return it == attrConstraints.end() ? std::optional<StringRef>()
82 : StringRef(it->second);
87 const auto *it = successorConstraints.find(constraint);
88 assert(it != successorConstraints.end() &&
89 "expected to find a sucessor constraint");
95 const auto *it = regionConstraints.find(constraint);
96 assert(it != regionConstraints.end() &&
97 "expected to find a region constraint");
114 static ::llvm::LogicalResult {0}(
115 ::mlir::Operation *op, ::mlir::Type type, ::llvm::StringRef valueKind,
116 unsigned valueIndex) {
118 return op->emitOpError(valueKind) << " #" << valueIndex
119 << " must be {2}, but got " << type;
121 return ::mlir::success();
132 static ::llvm::LogicalResult {0}(
133 ::mlir::Attribute attr, ::llvm::StringRef attrName, llvm::function_ref<::mlir::InFlightDiagnostic()> emitError) {{
135 return emitError() << "attribute '" << attrName
136 << "' failed to satisfy constraint: {2}";
137 return ::mlir::success();
139 static ::llvm::LogicalResult {0}(
140 ::mlir::Operation *op, ::mlir::Attribute attr, ::llvm::StringRef attrName) {{
141 return {0}(attr, attrName, [op]() {{
142 return op->emitOpError();
149 static ::llvm::LogicalResult {0}(
150 ::mlir::Operation *op, ::mlir::Block *successor,
151 ::llvm::StringRef successorName, unsigned successorIndex) {
153 return op->emitOpError("successor #") << successorIndex << " ('"
154 << successorName << ")' failed to verify constraint: {2}";
156 return ::mlir::success();
163 static ::llvm::LogicalResult {0}(
164 ::mlir::Operation *op, ::mlir::Region ®ion, ::llvm::StringRef regionName,
165 unsigned regionIndex) {
167 return op->emitOpError("region #") << regionIndex
168 << (regionName.empty() ? " " : " ('" + regionName + "') ")
169 << "failed to verify constraint: {2}";
171 return ::mlir::success();
179 static ::llvm::LogicalResult {0}(
180 ::mlir::PatternRewriter &rewriter, ::mlir::Operation *op, ::mlir::{3},
181 ::llvm::StringRef failureStr) {
183 return rewriter.notifyMatchFailure(op, [&](::mlir::Diagnostic &diag) {
184 diag << failureStr << ": {2}";
187 return ::mlir::success();
191 void StaticVerifierFunctionEmitter::emitConstraints(
192 const ConstraintMap &constraints, StringRef selfName,
193 const char *
const codeTemplate) {
196 for (
auto &it : constraints) {
197 os << formatv(codeTemplate, it.second,
198 tgfmt(it.first.getConditionTemplate(), &ctx),
203 void StaticVerifierFunctionEmitter::emitTypeConstraints() {
207 void StaticVerifierFunctionEmitter::emitAttrConstraints() {
211 void StaticVerifierFunctionEmitter::emitSuccessorConstraints() {
215 void StaticVerifierFunctionEmitter::emitRegionConstraints() {
219 void StaticVerifierFunctionEmitter::emitPatternConstraints() {
222 for (
auto &it : typeConstraints) {
224 tgfmt(it.first.getConditionTemplate(), &ctx),
228 for (
auto &it : attrConstraints) {
230 tgfmt(it.first.getConditionTemplate(), &ctx),
245 auto test =
tgfmt(attr.getConditionTemplate(),
248 return !StringRef(test).contains(
"<no-subst-found>");
251 std::string StaticVerifierFunctionEmitter::getUniqueName(StringRef kind,
253 return (
"__mlir_ods_local_" + kind +
"_constraint_" + uniqueOutputLabel +
258 void StaticVerifierFunctionEmitter::collectConstraint(ConstraintMap &map,
261 auto *it = map.find(constraint);
263 map.insert({constraint, getUniqueName(kind, map.size())});
270 if (value.hasPredicate())
271 collectConstraint(typeConstraints,
"type", value.constraint);
274 for (Record *def : opDefs) {
281 if (!namedAttr.attr.getPredicate().isNull() &&
282 !namedAttr.attr.isDerivedAttr() &&
284 collectConstraint(attrConstraints,
"attr", namedAttr.attr);
288 if (!successor.constraint.getPredicate().isNull()) {
289 collectConstraint(successorConstraints,
"successor",
290 successor.constraint);
295 if (!region.constraint.getPredicate().isNull())
296 collectConstraint(regionConstraints,
"region", region.constraint);
300 void StaticVerifierFunctionEmitter::collectPatternConstraints(
302 for (
auto &leaf : constraints) {
303 assert(leaf.isOperandMatcher() || leaf.isAttrMatcher());
305 leaf.isOperandMatcher() ? typeConstraints : attrConstraints,
306 leaf.isOperandMatcher() ?
"type" :
"attr", leaf.getAsConstraint());
316 llvm::raw_string_ostream os(ret);
317 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 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 std::string getUniqueOutputLabel(const llvm::RecordKeeper &records, StringRef tag)
Generate a unique label based on the current file name to prevent name collisions if multiple generat...
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.
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 collectOpConstraints(ArrayRef< llvm::Record * > opDefs)
Collect and unique all the constraints used by operations.
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.
void emitOpConstraints(ArrayRef< llvm::Record * > opDefs)
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.
Include the generated interface declarations.
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.