MLIR  19.0.0git
ExtensibleDialect.cpp
Go to the documentation of this file.
1 //===- ExtensibleDialect.cpp - Extensible dialect ---------------*- C++ -*-===//
2 //
3 // This file is licensed 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 
15 
16 using namespace mlir;
17 
18 //===----------------------------------------------------------------------===//
19 // Dynamic types and attributes shared functions
20 //===----------------------------------------------------------------------===//
21 
22 /// Default parser for dynamic attribute or type parameters.
23 /// Parse in the format '(<>)?' or '<attr (,attr)*>'.
24 static LogicalResult
26  // No parameters
27  if (parser.parseOptionalLess() || !parser.parseOptionalGreater())
28  return success();
29 
30  Attribute attr;
31  if (parser.parseAttribute(attr))
32  return failure();
33  parsedParams.push_back(attr);
34 
35  while (parser.parseOptionalGreater()) {
36  Attribute attr;
37  if (parser.parseComma() || parser.parseAttribute(attr))
38  return failure();
39  parsedParams.push_back(attr);
40  }
41 
42  return success();
43 }
44 
45 /// Default printer for dynamic attribute or type parameters.
46 /// Print in the format '(<>)?' or '<attr (,attr)*>'.
47 static void typeOrAttrPrinter(AsmPrinter &printer, ArrayRef<Attribute> params) {
48  if (params.empty())
49  return;
50 
51  printer << "<";
52  interleaveComma(params, printer.getStream());
53  printer << ">";
54 }
55 
56 //===----------------------------------------------------------------------===//
57 // Dynamic type
58 //===----------------------------------------------------------------------===//
59 
60 std::unique_ptr<DynamicTypeDefinition>
62  VerifierFn &&verifier) {
63  return DynamicTypeDefinition::get(name, dialect, std::move(verifier),
65 }
66 
67 std::unique_ptr<DynamicTypeDefinition>
69  VerifierFn &&verifier, ParserFn &&parser,
70  PrinterFn &&printer) {
71  return std::unique_ptr<DynamicTypeDefinition>(
72  new DynamicTypeDefinition(name, dialect, std::move(verifier),
73  std::move(parser), std::move(printer)));
74 }
75 
76 DynamicTypeDefinition::DynamicTypeDefinition(StringRef nameRef,
77  ExtensibleDialect *dialect,
78  VerifierFn &&verifier,
79  ParserFn &&parser,
80  PrinterFn &&printer)
81  : name(nameRef), dialect(dialect), verifier(std::move(verifier)),
82  parser(std::move(parser)), printer(std::move(printer)),
83  ctx(dialect->getContext()) {}
84 
85 DynamicTypeDefinition::DynamicTypeDefinition(ExtensibleDialect *dialect,
86  StringRef nameRef)
87  : name(nameRef), dialect(dialect), ctx(dialect->getContext()) {}
88 
89 void DynamicTypeDefinition::registerInTypeUniquer() {
90  detail::TypeUniquer::registerType<DynamicType>(&getContext(), getTypeID());
91 }
92 
93 namespace mlir {
94 namespace detail {
95 /// Storage of DynamicType.
96 /// Contains a pointer to the type definition and type parameters.
98 
99  using KeyTy = std::pair<DynamicTypeDefinition *, ArrayRef<Attribute>>;
100 
103  : typeDef(typeDef), params(params) {}
104 
105  bool operator==(const KeyTy &key) const {
106  return typeDef == key.first && params == key.second;
107  }
108 
109  static llvm::hash_code hashKey(const KeyTy &key) {
110  return llvm::hash_value(key);
111  }
112 
114  const KeyTy &key) {
115  return new (alloc.allocate<DynamicTypeStorage>())
116  DynamicTypeStorage(key.first, alloc.copyInto(key.second));
117  }
118 
119  /// Definition of the type.
121 
122  /// The type parameters.
124 };
125 } // namespace detail
126 } // namespace mlir
127 
129  ArrayRef<Attribute> params) {
130  auto &ctx = typeDef->getContext();
132  assert(succeeded(typeDef->verify(emitError, params)));
133  return detail::TypeUniquer::getWithTypeID<DynamicType>(
134  &ctx, typeDef->getTypeID(), typeDef, params);
135 }
136 
139  DynamicTypeDefinition *typeDef,
140  ArrayRef<Attribute> params) {
141  if (failed(typeDef->verify(emitError, params)))
142  return {};
143  auto &ctx = typeDef->getContext();
144  return detail::TypeUniquer::getWithTypeID<DynamicType>(
145  &ctx, typeDef->getTypeID(), typeDef, params);
146 }
147 
149 
151 
153  return type.hasTrait<TypeTrait::IsDynamicType>();
154 }
155 
157  DynamicTypeDefinition *typeDef,
158  DynamicType &parsedType) {
159  SmallVector<Attribute> params;
160  if (failed(typeDef->parser(parser, params)))
161  return failure();
162  parsedType = parser.getChecked<DynamicType>(typeDef, params);
163  if (!parsedType)
164  return failure();
165  return success();
166 }
167 
169  printer << getTypeDef()->getName();
170  getTypeDef()->printer(printer, getParams());
171 }
172 
173 //===----------------------------------------------------------------------===//
174 // Dynamic attribute
175 //===----------------------------------------------------------------------===//
176 
177 std::unique_ptr<DynamicAttrDefinition>
179  VerifierFn &&verifier) {
180  return DynamicAttrDefinition::get(name, dialect, std::move(verifier),
182 }
183 
184 std::unique_ptr<DynamicAttrDefinition>
186  VerifierFn &&verifier, ParserFn &&parser,
187  PrinterFn &&printer) {
188  return std::unique_ptr<DynamicAttrDefinition>(
189  new DynamicAttrDefinition(name, dialect, std::move(verifier),
190  std::move(parser), std::move(printer)));
191 }
192 
193 DynamicAttrDefinition::DynamicAttrDefinition(StringRef nameRef,
194  ExtensibleDialect *dialect,
195  VerifierFn &&verifier,
196  ParserFn &&parser,
197  PrinterFn &&printer)
198  : name(nameRef), dialect(dialect), verifier(std::move(verifier)),
199  parser(std::move(parser)), printer(std::move(printer)),
200  ctx(dialect->getContext()) {}
201 
202 DynamicAttrDefinition::DynamicAttrDefinition(ExtensibleDialect *dialect,
203  StringRef nameRef)
204  : name(nameRef), dialect(dialect), ctx(dialect->getContext()) {}
205 
206 void DynamicAttrDefinition::registerInAttrUniquer() {
207  detail::AttributeUniquer::registerAttribute<DynamicAttr>(&getContext(),
208  getTypeID());
209 }
210 
211 namespace mlir {
212 namespace detail {
213 /// Storage of DynamicAttr.
214 /// Contains a pointer to the attribute definition and attribute parameters.
216  using KeyTy = std::pair<DynamicAttrDefinition *, ArrayRef<Attribute>>;
217 
220  : attrDef(attrDef), params(params) {}
221 
222  bool operator==(const KeyTy &key) const {
223  return attrDef == key.first && params == key.second;
224  }
225 
226  static llvm::hash_code hashKey(const KeyTy &key) {
227  return llvm::hash_value(key);
228  }
229 
231  const KeyTy &key) {
232  return new (alloc.allocate<DynamicAttrStorage>())
233  DynamicAttrStorage(key.first, alloc.copyInto(key.second));
234  }
235 
236  /// Definition of the type.
238 
239  /// The type parameters.
241 };
242 } // namespace detail
243 } // namespace mlir
244 
246  ArrayRef<Attribute> params) {
247  auto &ctx = attrDef->getContext();
248  return detail::AttributeUniquer::getWithTypeID<DynamicAttr>(
249  &ctx, attrDef->getTypeID(), attrDef, params);
250 }
251 
254  DynamicAttrDefinition *attrDef,
255  ArrayRef<Attribute> params) {
256  if (failed(attrDef->verify(emitError, params)))
257  return {};
258  return get(attrDef, params);
259 }
260 
262 
264 
267 }
268 
270  DynamicAttrDefinition *attrDef,
271  DynamicAttr &parsedAttr) {
272  SmallVector<Attribute> params;
273  if (failed(attrDef->parser(parser, params)))
274  return failure();
275  parsedAttr = parser.getChecked<DynamicAttr>(attrDef, params);
276  if (!parsedAttr)
277  return failure();
278  return success();
279 }
280 
282  printer << getAttrDef()->getName();
283  getAttrDef()->printer(printer, getParams());
284 }
285 
286 //===----------------------------------------------------------------------===//
287 // Dynamic operation
288 //===----------------------------------------------------------------------===//
289 
290 DynamicOpDefinition::DynamicOpDefinition(
291  StringRef name, ExtensibleDialect *dialect,
296  OperationName::FoldHookFn &&foldHookFn,
297  GetCanonicalizationPatternsFn &&getCanonicalizationPatternsFn,
298  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn)
299  : Impl(StringAttr::get(dialect->getContext(),
300  (dialect->getNamespace() + "." + name).str()),
301  dialect, dialect->allocateTypeID(),
302  /*interfaceMap=*/detail::InterfaceMap()),
303  verifyFn(std::move(verifyFn)), verifyRegionFn(std::move(verifyRegionFn)),
304  parseFn(std::move(parseFn)), printFn(std::move(printFn)),
305  foldHookFn(std::move(foldHookFn)),
306  getCanonicalizationPatternsFn(std::move(getCanonicalizationPatternsFn)),
307  populateDefaultAttrsFn(std::move(populateDefaultAttrsFn)) {
308  typeID = dialect->allocateTypeID();
309 }
310 
311 std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
312  StringRef name, ExtensibleDialect *dialect,
314  OperationName::VerifyRegionInvariantsFn &&verifyRegionFn) {
315  auto parseFn = [](OpAsmParser &parser, OperationState &result) {
316  return parser.emitError(
317  parser.getCurrentLocation(),
318  "dynamic operation do not define any parser function");
319  };
320 
321  auto printFn = [](Operation *op, OpAsmPrinter &printer, StringRef) {
322  printer.printGenericOp(op);
323  };
324 
325  return DynamicOpDefinition::get(name, dialect, std::move(verifyFn),
326  std::move(verifyRegionFn), std::move(parseFn),
327  std::move(printFn));
328 }
329 
330 std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
331  StringRef name, ExtensibleDialect *dialect,
335  OperationName::PrintAssemblyFn &&printFn) {
336  auto foldHookFn = [](Operation *op, ArrayRef<Attribute> operands,
338  return failure();
339  };
340 
341  auto getCanonicalizationPatternsFn = [](RewritePatternSet &, MLIRContext *) {
342  };
343 
344  auto populateDefaultAttrsFn = [](const OperationName &, NamedAttrList &) {};
345 
346  return DynamicOpDefinition::get(name, dialect, std::move(verifyFn),
347  std::move(verifyRegionFn), std::move(parseFn),
348  std::move(printFn), std::move(foldHookFn),
349  std::move(getCanonicalizationPatternsFn),
350  std::move(populateDefaultAttrsFn));
351 }
352 
353 std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
354  StringRef name, ExtensibleDialect *dialect,
356  OperationName::VerifyInvariantsFn &&verifyRegionFn,
359  OperationName::FoldHookFn &&foldHookFn,
360  GetCanonicalizationPatternsFn &&getCanonicalizationPatternsFn,
361  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn) {
362  return std::unique_ptr<DynamicOpDefinition>(new DynamicOpDefinition(
363  name, dialect, std::move(verifyFn), std::move(verifyRegionFn),
364  std::move(parseFn), std::move(printFn), std::move(foldHookFn),
365  std::move(getCanonicalizationPatternsFn),
366  std::move(populateDefaultAttrsFn)));
367 }
368 
369 //===----------------------------------------------------------------------===//
370 // Extensible dialect
371 //===----------------------------------------------------------------------===//
372 
373 namespace {
374 /// Interface that can only be implemented by extensible dialects.
375 /// The interface is used to check if a dialect is extensible or not.
376 class IsExtensibleDialect : public DialectInterface::Base<IsExtensibleDialect> {
377 public:
378  IsExtensibleDialect(Dialect *dialect) : Base(dialect) {}
379 
381 };
382 } // namespace
383 
385  TypeID typeID)
386  : Dialect(name, ctx, typeID) {
387  addInterfaces<IsExtensibleDialect>();
388 }
389 
391  std::unique_ptr<DynamicTypeDefinition> &&type) {
392  DynamicTypeDefinition *typePtr = type.get();
393  TypeID typeID = type->getTypeID();
394  StringRef name = type->getName();
395  ExtensibleDialect *dialect = type->getDialect();
396 
397  assert(dialect == this &&
398  "trying to register a dynamic type in the wrong dialect");
399 
400  // If a type with the same name is already defined, fail.
401  auto registered = dynTypes.try_emplace(typeID, std::move(type)).second;
402  (void)registered;
403  assert(registered && "type TypeID was not unique");
404 
405  registered = nameToDynTypes.insert({name, typePtr}).second;
406  (void)registered;
407  assert(registered &&
408  "Trying to create a new dynamic type with an existing name");
409 
410  // The StringAttr allocates the type name StringRef for the duration of the
411  // MLIR context.
412  MLIRContext *ctx = getContext();
413  auto nameAttr =
414  StringAttr::get(ctx, getNamespace() + "." + typePtr->getName());
415 
416  auto abstractType = AbstractType::get(
420 
421  /// Add the type to the dialect and the type uniquer.
422  addType(typeID, std::move(abstractType));
423  typePtr->registerInTypeUniquer();
424 }
425 
427  std::unique_ptr<DynamicAttrDefinition> &&attr) {
428  auto *attrPtr = attr.get();
429  auto typeID = attr->getTypeID();
430  auto name = attr->getName();
431  auto *dialect = attr->getDialect();
432 
433  assert(dialect == this &&
434  "trying to register a dynamic attribute in the wrong dialect");
435 
436  // If an attribute with the same name is already defined, fail.
437  auto registered = dynAttrs.try_emplace(typeID, std::move(attr)).second;
438  (void)registered;
439  assert(registered && "attribute TypeID was not unique");
440 
441  registered = nameToDynAttrs.insert({name, attrPtr}).second;
442  (void)registered;
443  assert(registered &&
444  "Trying to create a new dynamic attribute with an existing name");
445 
446  // The StringAttr allocates the attribute name StringRef for the duration of
447  // the MLIR context.
448  MLIRContext *ctx = getContext();
449  auto nameAttr =
450  StringAttr::get(ctx, getNamespace() + "." + attrPtr->getName());
451 
452  auto abstractAttr = AbstractAttribute::get(
456 
457  /// Add the type to the dialect and the type uniquer.
458  addAttribute(typeID, std::move(abstractAttr));
459  attrPtr->registerInAttrUniquer();
460 }
461 
463  std::unique_ptr<DynamicOpDefinition> &&op) {
464  assert(op->dialect == this &&
465  "trying to register a dynamic op in the wrong dialect");
466  RegisteredOperationName::insert(std::move(op), /*attrNames=*/{});
467 }
468 
469 bool ExtensibleDialect::classof(const Dialect *dialect) {
470  return const_cast<Dialect *>(dialect)
471  ->getRegisteredInterface<IsExtensibleDialect>();
472 }
473 
475  StringRef typeName, AsmParser &parser, Type &resultType) const {
476  DynamicTypeDefinition *typeDef = lookupTypeDefinition(typeName);
477  if (!typeDef)
478  return std::nullopt;
479 
480  DynamicType dynType;
481  if (DynamicType::parse(parser, typeDef, dynType))
482  return failure();
483  resultType = dynType;
484  return success();
485 }
486 
488  AsmPrinter &printer) {
489  if (auto dynType = llvm::dyn_cast<DynamicType>(type)) {
490  dynType.print(printer);
491  return success();
492  }
493  return failure();
494 }
495 
497  StringRef attrName, AsmParser &parser, Attribute &resultAttr) const {
498  DynamicAttrDefinition *attrDef = lookupAttrDefinition(attrName);
499  if (!attrDef)
500  return std::nullopt;
501 
502  DynamicAttr dynAttr;
503  if (DynamicAttr::parse(parser, attrDef, dynAttr))
504  return failure();
505  resultAttr = dynAttr;
506  return success();
507 }
508 
510  AsmPrinter &printer) {
511  if (auto dynAttr = llvm::dyn_cast<DynamicAttr>(attribute)) {
512  dynAttr.print(printer);
513  return success();
514  }
515  return failure();
516 }
517 
518 //===----------------------------------------------------------------------===//
519 // Dynamic dialect
520 //===----------------------------------------------------------------------===//
521 
522 namespace {
523 /// Interface that can only be implemented by extensible dialects.
524 /// The interface is used to check if a dialect is extensible or not.
525 class IsDynamicDialect : public DialectInterface::Base<IsDynamicDialect> {
526 public:
527  IsDynamicDialect(Dialect *dialect) : Base(dialect) {}
528 
530 };
531 } // namespace
532 
534  : SelfOwningTypeID(),
535  ExtensibleDialect(name, ctx, SelfOwningTypeID::getTypeID()) {
536  addInterfaces<IsDynamicDialect>();
537 }
538 
539 bool DynamicDialect::classof(const Dialect *dialect) {
540  return const_cast<Dialect *>(dialect)
541  ->getRegisteredInterface<IsDynamicDialect>();
542 }
543 
545  auto loc = parser.getCurrentLocation();
546  StringRef typeTag;
547  if (failed(parser.parseKeyword(&typeTag)))
548  return Type();
549 
550  {
551  Type dynType;
552  auto parseResult = parseOptionalDynamicType(typeTag, parser, dynType);
553  if (parseResult.has_value()) {
554  if (succeeded(parseResult.value()))
555  return dynType;
556  return Type();
557  }
558  }
559 
560  parser.emitError(loc, "expected dynamic type");
561  return Type();
562 }
563 
565  auto wasDynamic = printIfDynamicType(type, printer);
566  (void)wasDynamic;
567  assert(succeeded(wasDynamic) &&
568  "non-dynamic type defined in dynamic dialect");
569 }
570 
572  Type type) const {
573  auto loc = parser.getCurrentLocation();
574  StringRef typeTag;
575  if (failed(parser.parseKeyword(&typeTag)))
576  return Attribute();
577 
578  {
579  Attribute dynAttr;
580  auto parseResult = parseOptionalDynamicAttr(typeTag, parser, dynAttr);
581  if (parseResult.has_value()) {
582  if (succeeded(parseResult.value()))
583  return dynAttr;
584  return Attribute();
585  }
586  }
587 
588  parser.emitError(loc, "expected dynamic attribute");
589  return Attribute();
590 }
592  DialectAsmPrinter &printer) const {
593  auto wasDynamic = printIfDynamicAttr(attr, printer);
594  (void)wasDynamic;
595  assert(succeeded(wasDynamic) &&
596  "non-dynamic attribute defined in dynamic dialect");
597 }
static LogicalResult typeOrAttrParser(AsmParser &parser, SmallVectorImpl< Attribute > &parsedParams)
Default parser for dynamic attribute or type parameters.
static void typeOrAttrPrinter(AsmPrinter &printer, ArrayRef< Attribute > params)
Default printer for dynamic attribute or type parameters.
static MLIRContext * getContext(OpFoldResult val)
#define MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(CLASS_NAME)
Definition: TypeID.h:274
static AbstractAttribute get(Dialect &dialect)
This method is used by Dialect objects when they register the list of attributes they contain.
static AbstractType get(Dialect &dialect)
This method is used by Dialect objects when they register the list of types they contain.
Definition: TypeSupport.h:50
This base class exposes generic asm parser hooks, usable across the various derived parsers.
virtual InFlightDiagnostic emitError(SMLoc loc, const Twine &message={})=0
Emit a diagnostic at the specified location and return failure.
virtual ParseResult parseOptionalGreater()=0
Parse a '>' token if present.
virtual SMLoc getCurrentLocation()=0
Get the location of the next token and store it into the argument.
auto getChecked(SMLoc loc, ParamsT &&...params)
Invoke the getChecked method of the given Attribute or Type class, using the provided location to emi...
virtual ParseResult parseOptionalLess()=0
Parse a '<' token if present.
virtual ParseResult parseComma()=0
Parse a , token.
ParseResult parseKeyword(StringRef keyword)
Parse a given keyword.
virtual ParseResult parseAttribute(Attribute &result, Type type={})=0
Parse an arbitrary attribute of a given type and return it in result.
This base class exposes generic asm printer hooks, usable across the various derived printers.
virtual raw_ostream & getStream() const
Return the raw output stream used by this printer.
Base storage class appearing in an attribute.
Attributes are known-constant values of operations.
Definition: Attributes.h:25
bool hasTrait()
Returns true if the type was registered with a particular trait.
Definition: Attributes.h:110
The DialectAsmParser has methods for interacting with the asm parser when parsing attributes and type...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:41
StringRef getNamespace() const
Definition: Dialect.h:57
void addType(TypeID typeID, AbstractType &&typeInfo)
Register a type instance with this dialect.
MLIRContext * getContext() const
Definition: Dialect.h:55
void addAttribute(TypeID typeID, AbstractAttribute &&attrInfo)
Register an attribute instance with this dialect.
The definition of a dynamic attribute.
static std::unique_ptr< DynamicAttrDefinition > get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier)
Create a new attribute definition at runtime.
llvm::unique_function< void(AsmPrinter &printer, ArrayRef< Attribute > params) const > PrinterFn
MLIRContext & getContext() const
Return the MLIRContext in which the dynamic attributes are uniqued.
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, ArrayRef< Attribute > params) const
Check that the attribute parameters are valid.
StringRef getName() const
Return the name of the attribute, in the format 'attrname' and not 'dialectname.attrname'.
llvm::unique_function< LogicalResult(function_ref< InFlightDiagnostic()>, ArrayRef< Attribute >) const > VerifierFn
llvm::unique_function< ParseResult(AsmParser &parser, llvm::SmallVectorImpl< Attribute > &parsedAttributes) const > ParserFn
A dynamic attribute instance.
static DynamicAttr getChecked(function_ref< InFlightDiagnostic()> emitError, DynamicAttrDefinition *attrDef, ArrayRef< Attribute > params={})
Return an instance of a dynamic attribute given a dynamic attribute definition and attribute paramete...
ArrayRef< Attribute > getParams()
Return the attribute parameters.
static DynamicAttr get(DynamicAttrDefinition *attrDef, ArrayRef< Attribute > params={})
Return an instance of a dynamic attribute given a dynamic attribute definition and attribute paramete...
void print(AsmPrinter &printer)
Print the dynamic attribute with the format 'attrname' if there is no parameters, or 'attrname<attr (...
static bool classof(Attribute attr)
Check if an attribute is a dynamic attribute.
static ParseResult parse(AsmParser &parser, DynamicAttrDefinition *attrDef, DynamicAttr &parsedAttr)
Parse the dynamic attribute parameters and construct the attribute.
DynamicAttrDefinition * getAttrDef()
Return the attribute definition of the concrete attribute.
virtual void printAttribute(Attribute attr, DialectAsmPrinter &printer) const override
Print an attribute registered to this dialect.
DynamicDialect(StringRef name, MLIRContext *ctx)
virtual Attribute parseAttribute(DialectAsmParser &parser, Type type) const override
Parse an attribute registered to this dialect.
virtual void printType(Type type, DialectAsmPrinter &printer) const override
Print a type registered to this dialect.
static bool classof(const Dialect *dialect)
Check if the dialect is an extensible dialect.
virtual Type parseType(DialectAsmParser &parser) const override
Parse a type registered to this dialect.
The definition of a dynamic op.
static std::unique_ptr< DynamicOpDefinition > get(StringRef name, ExtensibleDialect *dialect, OperationName::VerifyInvariantsFn &&verifyFn, OperationName::VerifyRegionInvariantsFn &&verifyRegionFn)
Create a new op at runtime.
llvm::unique_function< void(RewritePatternSet &, MLIRContext *) const > GetCanonicalizationPatternsFn
The definition of a dynamic type.
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, ArrayRef< Attribute > params) const
Check that the type parameters are valid.
StringRef getName() const
Return the name of the type, in the format 'typename' and not 'dialectname.typename'.
MLIRContext & getContext() const
Return the MLIRContext in which the dynamic types is uniqued.
llvm::unique_function< void(AsmPrinter &printer, ArrayRef< Attribute > params) const > PrinterFn
llvm::unique_function< ParseResult(AsmParser &parser, llvm::SmallVectorImpl< Attribute > &parsedAttributes) const > ParserFn
llvm::unique_function< LogicalResult(function_ref< InFlightDiagnostic()>, ArrayRef< Attribute >) const > VerifierFn
static std::unique_ptr< DynamicTypeDefinition > get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier)
Create a new dynamic type definition.
A dynamic type instance.
static DynamicType getChecked(function_ref< InFlightDiagnostic()> emitError, DynamicTypeDefinition *typeDef, ArrayRef< Attribute > params={})
Return an instance of a dynamic type given a dynamic type definition and type parameters.
ArrayRef< Attribute > getParams()
Return the type parameters.
void print(AsmPrinter &printer)
Print the dynamic type with the format 'type' or 'type<>' if there is no parameters,...
DynamicTypeDefinition * getTypeDef()
Return the type definition of the concrete type.
static DynamicType get(DynamicTypeDefinition *typeDef, ArrayRef< Attribute > params={})
Return an instance of a dynamic type given a dynamic type definition and type parameters.
static ParseResult parse(AsmParser &parser, DynamicTypeDefinition *typeDef, DynamicType &parsedType)
Parse the dynamic type parameters and construct the type.
static bool classof(Type type)
Check if a type is a dynamic type.
A dialect that can be extended with new operations/types/attributes at runtime.
static bool classof(const Dialect *dialect)
Check if the dialect is an extensible dialect.
void registerDynamicOp(std::unique_ptr< DynamicOpDefinition > &&type)
Add a new operation defined at runtime to the dialect.
static LogicalResult printIfDynamicType(Type type, AsmPrinter &printer)
If 'type' is a dynamic type, print it.
void registerDynamicType(std::unique_ptr< DynamicTypeDefinition > &&type)
Add a new type defined at runtime to the dialect.
static LogicalResult printIfDynamicAttr(Attribute attr, AsmPrinter &printer)
If 'attr' is a dynamic attribute, print it.
OptionalParseResult parseOptionalDynamicAttr(StringRef attrName, AsmParser &parser, Attribute &resultAttr) const
Parse the dynamic attribute 'attrName' in the dialect 'dialect'.
ExtensibleDialect(StringRef name, MLIRContext *ctx, TypeID typeID)
DynamicAttrDefinition * lookupAttrDefinition(StringRef name) const
Returns nullptr if the definition was not found.
void registerDynamicAttr(std::unique_ptr< DynamicAttrDefinition > &&attr)
Add a new attribute defined at runtime to the dialect.
OptionalParseResult parseOptionalDynamicType(StringRef typeName, AsmParser &parser, Type &resultType) const
Parse the dynamic type 'typeName' in the dialect 'dialect'.
DynamicTypeDefinition * lookupTypeDefinition(StringRef name) const
Returns nullptr if the definition was not found.
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:308
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
StringAttr name
The name of the operation.
Dialect * dialect
The following fields are only populated when the operation is registered.
llvm::unique_function< LogicalResult(Operation *) const > VerifyInvariantsFn
llvm::unique_function< ParseResult(OpAsmParser &, OperationState &)> ParseAssemblyFn
llvm::unique_function< LogicalResult(Operation *) const > VerifyRegionInvariantsFn
llvm::unique_function< void(Operation *, OpAsmPrinter &, StringRef) const > PrintAssemblyFn
llvm::unique_function< LogicalResult(Operation *, ArrayRef< Attribute >, SmallVectorImpl< OpFoldResult > &) const > FoldHookFn
llvm::unique_function< void(const OperationName &, NamedAttrList &) const > PopulateDefaultAttrsFn
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
This class implements Optional functionality for ParseResult.
Definition: OpDefinition.h:39
This class represents success/failure for parsing-like operations that find it important to chain tog...
static void insert(Dialect &dialect)
Register a new operation in a Dialect object.
Defines a TypeID for each instance of this class by using a pointer to the instance.
Definition: TypeID.h:312
TypeID getTypeID() const
Return the TypeID owned by this object.
Definition: TypeID.h:324
This is a utility allocator used to allocate memory for instances of derived types.
ArrayRef< T > copyInto(ArrayRef< T > elements)
Copy the specified array of elements into memory managed by our bump pointer allocator.
T * allocate()
Allocate an instance of the provided type.
This class provides an efficient unique identifier for a specific C++ type.
Definition: TypeID.h:104
Base storage class appearing in a Type.
Definition: TypeSupport.h:166
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
bool hasTrait()
Returns true if the type was registered with a particular trait.
Definition: Types.h:200
The base class used for all derived interface types.
static HasTraitFn getHasTraitFn()
Returns the function that returns true if the given Trait ID matches the IDs of any of the traits def...
ImplType * getImpl() const
Utility for easy access to the storage instance.
static auto getWalkImmediateSubElementsFn()
Returns a function that walks immediate sub elements of a given instance of the storage user.
static detail::InterfaceMap getInterfaceMap()
Returns an interface map for the interfaces registered to this storage user.
static auto getReplaceImmediateSubElementsFn()
Returns a function that replaces immediate sub elements of a given instance of the storage user.
llvm::unique_function< InFlightDiagnostic()> getDefaultDiagnosticEmitFn(MLIRContext *ctx)
Utility method to generate a callback that can be used to generate a diagnostic when checking the con...
inline ::llvm::hash_code hash_value(const PolynomialBase< D, T > &arg)
Definition: Polynomial.h:263
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
Definition: LogicalResult.h:68
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
Definition: LogicalResult.h:72
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
This represents an operation in an abstracted form, suitable for use with the builder APIs.
DynamicAttrStorage(DynamicAttrDefinition *attrDef, ArrayRef< Attribute > params)
static llvm::hash_code hashKey(const KeyTy &key)
bool operator==(const KeyTy &key) const
DynamicAttrDefinition * attrDef
Definition of the type.
std::pair< DynamicAttrDefinition *, ArrayRef< Attribute > > KeyTy
ArrayRef< Attribute > params
The type parameters.
static DynamicAttrStorage * construct(AttributeStorageAllocator &alloc, const KeyTy &key)
ArrayRef< Attribute > params
The type parameters.
static llvm::hash_code hashKey(const KeyTy &key)
std::pair< DynamicTypeDefinition *, ArrayRef< Attribute > > KeyTy
DynamicTypeDefinition * typeDef
Definition of the type.
static DynamicTypeStorage * construct(TypeStorageAllocator &alloc, const KeyTy &key)
DynamicTypeStorage(DynamicTypeDefinition *typeDef, ArrayRef< Attribute > params)
bool operator==(const KeyTy &key) const