MLIR  21.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 
14 #include "llvm/Support/InterleavedRange.h"
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 << "<" << llvm::interleaved(params) << ">";
52 }
53 
54 //===----------------------------------------------------------------------===//
55 // Dynamic type
56 //===----------------------------------------------------------------------===//
57 
58 std::unique_ptr<DynamicTypeDefinition>
60  VerifierFn &&verifier) {
61  return DynamicTypeDefinition::get(name, dialect, std::move(verifier),
63 }
64 
65 std::unique_ptr<DynamicTypeDefinition>
67  VerifierFn &&verifier, ParserFn &&parser,
68  PrinterFn &&printer) {
69  return std::unique_ptr<DynamicTypeDefinition>(
70  new DynamicTypeDefinition(name, dialect, std::move(verifier),
71  std::move(parser), std::move(printer)));
72 }
73 
74 DynamicTypeDefinition::DynamicTypeDefinition(StringRef nameRef,
75  ExtensibleDialect *dialect,
76  VerifierFn &&verifier,
77  ParserFn &&parser,
78  PrinterFn &&printer)
79  : name(nameRef), dialect(dialect), verifier(std::move(verifier)),
80  parser(std::move(parser)), printer(std::move(printer)),
81  ctx(dialect->getContext()) {}
82 
83 DynamicTypeDefinition::DynamicTypeDefinition(ExtensibleDialect *dialect,
84  StringRef nameRef)
85  : name(nameRef), dialect(dialect), ctx(dialect->getContext()) {}
86 
87 void DynamicTypeDefinition::registerInTypeUniquer() {
88  detail::TypeUniquer::registerType<DynamicType>(&getContext(), getTypeID());
89 }
90 
91 namespace mlir {
92 namespace detail {
93 /// Storage of DynamicType.
94 /// Contains a pointer to the type definition and type parameters.
96 
97  using KeyTy = std::pair<DynamicTypeDefinition *, ArrayRef<Attribute>>;
98 
101  : typeDef(typeDef), params(params) {}
102 
103  bool operator==(const KeyTy &key) const {
104  return typeDef == key.first && params == key.second;
105  }
106 
107  static llvm::hash_code hashKey(const KeyTy &key) {
108  return llvm::hash_value(key);
109  }
110 
112  const KeyTy &key) {
113  return new (alloc.allocate<DynamicTypeStorage>())
114  DynamicTypeStorage(key.first, alloc.copyInto(key.second));
115  }
116 
117  /// Definition of the type.
119 
120  /// The type parameters.
122 };
123 } // namespace detail
124 } // namespace mlir
125 
127  ArrayRef<Attribute> params) {
128  auto &ctx = typeDef->getContext();
130  assert(succeeded(typeDef->verify(emitError, params)));
131  return detail::TypeUniquer::getWithTypeID<DynamicType>(
132  &ctx, typeDef->getTypeID(), typeDef, params);
133 }
134 
137  DynamicTypeDefinition *typeDef,
138  ArrayRef<Attribute> params) {
139  if (failed(typeDef->verify(emitError, params)))
140  return {};
141  auto &ctx = typeDef->getContext();
142  return detail::TypeUniquer::getWithTypeID<DynamicType>(
143  &ctx, typeDef->getTypeID(), typeDef, params);
144 }
145 
147 
149 
151  return type.hasTrait<TypeTrait::IsDynamicType>();
152 }
153 
154 ParseResult DynamicType::parse(AsmParser &parser,
155  DynamicTypeDefinition *typeDef,
156  DynamicType &parsedType) {
157  SmallVector<Attribute> params;
158  if (failed(typeDef->parser(parser, params)))
159  return failure();
160  parsedType = parser.getChecked<DynamicType>(typeDef, params);
161  if (!parsedType)
162  return failure();
163  return success();
164 }
165 
167  printer << getTypeDef()->getName();
168  getTypeDef()->printer(printer, getParams());
169 }
170 
171 //===----------------------------------------------------------------------===//
172 // Dynamic attribute
173 //===----------------------------------------------------------------------===//
174 
175 std::unique_ptr<DynamicAttrDefinition>
177  VerifierFn &&verifier) {
178  return DynamicAttrDefinition::get(name, dialect, std::move(verifier),
180 }
181 
182 std::unique_ptr<DynamicAttrDefinition>
184  VerifierFn &&verifier, ParserFn &&parser,
185  PrinterFn &&printer) {
186  return std::unique_ptr<DynamicAttrDefinition>(
187  new DynamicAttrDefinition(name, dialect, std::move(verifier),
188  std::move(parser), std::move(printer)));
189 }
190 
191 DynamicAttrDefinition::DynamicAttrDefinition(StringRef nameRef,
192  ExtensibleDialect *dialect,
193  VerifierFn &&verifier,
194  ParserFn &&parser,
195  PrinterFn &&printer)
196  : name(nameRef), dialect(dialect), verifier(std::move(verifier)),
197  parser(std::move(parser)), printer(std::move(printer)),
198  ctx(dialect->getContext()) {}
199 
200 DynamicAttrDefinition::DynamicAttrDefinition(ExtensibleDialect *dialect,
201  StringRef nameRef)
202  : name(nameRef), dialect(dialect), ctx(dialect->getContext()) {}
203 
204 void DynamicAttrDefinition::registerInAttrUniquer() {
205  detail::AttributeUniquer::registerAttribute<DynamicAttr>(&getContext(),
206  getTypeID());
207 }
208 
209 namespace mlir {
210 namespace detail {
211 /// Storage of DynamicAttr.
212 /// Contains a pointer to the attribute definition and attribute parameters.
214  using KeyTy = std::pair<DynamicAttrDefinition *, ArrayRef<Attribute>>;
215 
218  : attrDef(attrDef), params(params) {}
219 
220  bool operator==(const KeyTy &key) const {
221  return attrDef == key.first && params == key.second;
222  }
223 
224  static llvm::hash_code hashKey(const KeyTy &key) {
225  return llvm::hash_value(key);
226  }
227 
229  const KeyTy &key) {
230  return new (alloc.allocate<DynamicAttrStorage>())
231  DynamicAttrStorage(key.first, alloc.copyInto(key.second));
232  }
233 
234  /// Definition of the type.
236 
237  /// The type parameters.
239 };
240 } // namespace detail
241 } // namespace mlir
242 
244  ArrayRef<Attribute> params) {
245  auto &ctx = attrDef->getContext();
246  return detail::AttributeUniquer::getWithTypeID<DynamicAttr>(
247  &ctx, attrDef->getTypeID(), attrDef, params);
248 }
249 
252  DynamicAttrDefinition *attrDef,
253  ArrayRef<Attribute> params) {
254  if (failed(attrDef->verify(emitError, params)))
255  return {};
256  return get(attrDef, params);
257 }
258 
260 
262 
265 }
266 
267 ParseResult DynamicAttr::parse(AsmParser &parser,
268  DynamicAttrDefinition *attrDef,
269  DynamicAttr &parsedAttr) {
270  SmallVector<Attribute> params;
271  if (failed(attrDef->parser(parser, params)))
272  return failure();
273  parsedAttr = parser.getChecked<DynamicAttr>(attrDef, params);
274  if (!parsedAttr)
275  return failure();
276  return success();
277 }
278 
280  printer << getAttrDef()->getName();
281  getAttrDef()->printer(printer, getParams());
282 }
283 
284 //===----------------------------------------------------------------------===//
285 // Dynamic operation
286 //===----------------------------------------------------------------------===//
287 
288 DynamicOpDefinition::DynamicOpDefinition(
289  StringRef name, ExtensibleDialect *dialect,
294  OperationName::FoldHookFn &&foldHookFn,
295  GetCanonicalizationPatternsFn &&getCanonicalizationPatternsFn,
296  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn)
297  : Impl(StringAttr::get(dialect->getContext(),
298  (dialect->getNamespace() + "." + name).str()),
299  dialect, dialect->allocateTypeID(),
300  /*interfaceMap=*/detail::InterfaceMap()),
301  verifyFn(std::move(verifyFn)), verifyRegionFn(std::move(verifyRegionFn)),
302  parseFn(std::move(parseFn)), printFn(std::move(printFn)),
303  foldHookFn(std::move(foldHookFn)),
304  getCanonicalizationPatternsFn(std::move(getCanonicalizationPatternsFn)),
305  populateDefaultAttrsFn(std::move(populateDefaultAttrsFn)) {
306  typeID = dialect->allocateTypeID();
307 }
308 
309 std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
310  StringRef name, ExtensibleDialect *dialect,
312  OperationName::VerifyRegionInvariantsFn &&verifyRegionFn) {
313  auto parseFn = [](OpAsmParser &parser, OperationState &result) {
314  return parser.emitError(
315  parser.getCurrentLocation(),
316  "dynamic operation do not define any parser function");
317  };
318 
319  auto printFn = [](Operation *op, OpAsmPrinter &printer, StringRef) {
320  printer.printGenericOp(op);
321  };
322 
323  return DynamicOpDefinition::get(name, dialect, std::move(verifyFn),
324  std::move(verifyRegionFn), std::move(parseFn),
325  std::move(printFn));
326 }
327 
328 std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
329  StringRef name, ExtensibleDialect *dialect,
333  OperationName::PrintAssemblyFn &&printFn) {
334  auto foldHookFn = [](Operation *op, ArrayRef<Attribute> operands,
336  return failure();
337  };
338 
339  auto getCanonicalizationPatternsFn = [](RewritePatternSet &, MLIRContext *) {
340  };
341 
342  auto populateDefaultAttrsFn = [](const OperationName &, NamedAttrList &) {};
343 
344  return DynamicOpDefinition::get(name, dialect, std::move(verifyFn),
345  std::move(verifyRegionFn), std::move(parseFn),
346  std::move(printFn), std::move(foldHookFn),
347  std::move(getCanonicalizationPatternsFn),
348  std::move(populateDefaultAttrsFn));
349 }
350 
351 std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
352  StringRef name, ExtensibleDialect *dialect,
354  OperationName::VerifyInvariantsFn &&verifyRegionFn,
357  OperationName::FoldHookFn &&foldHookFn,
358  GetCanonicalizationPatternsFn &&getCanonicalizationPatternsFn,
359  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn) {
360  return std::unique_ptr<DynamicOpDefinition>(new DynamicOpDefinition(
361  name, dialect, std::move(verifyFn), std::move(verifyRegionFn),
362  std::move(parseFn), std::move(printFn), std::move(foldHookFn),
363  std::move(getCanonicalizationPatternsFn),
364  std::move(populateDefaultAttrsFn)));
365 }
366 
367 //===----------------------------------------------------------------------===//
368 // Extensible dialect
369 //===----------------------------------------------------------------------===//
370 
371 namespace {
372 /// Interface that can only be implemented by extensible dialects.
373 /// The interface is used to check if a dialect is extensible or not.
374 class IsExtensibleDialect : public DialectInterface::Base<IsExtensibleDialect> {
375 public:
376  IsExtensibleDialect(Dialect *dialect) : Base(dialect) {}
377 
379 };
380 } // namespace
381 
383  TypeID typeID)
384  : Dialect(name, ctx, typeID) {
385  addInterfaces<IsExtensibleDialect>();
386 }
387 
389  std::unique_ptr<DynamicTypeDefinition> &&type) {
390  DynamicTypeDefinition *typePtr = type.get();
391  TypeID typeID = type->getTypeID();
392  StringRef name = type->getName();
393  ExtensibleDialect *dialect = type->getDialect();
394 
395  assert(dialect == this &&
396  "trying to register a dynamic type in the wrong dialect");
397 
398  // If a type with the same name is already defined, fail.
399  auto registered = dynTypes.try_emplace(typeID, std::move(type)).second;
400  (void)registered;
401  assert(registered && "type TypeID was not unique");
402 
403  registered = nameToDynTypes.insert({name, typePtr}).second;
404  (void)registered;
405  assert(registered &&
406  "Trying to create a new dynamic type with an existing name");
407 
408  // The StringAttr allocates the type name StringRef for the duration of the
409  // MLIR context.
410  MLIRContext *ctx = getContext();
411  auto nameAttr =
412  StringAttr::get(ctx, getNamespace() + "." + typePtr->getName());
413 
414  auto abstractType = AbstractType::get(
418 
419  /// Add the type to the dialect and the type uniquer.
420  addType(typeID, std::move(abstractType));
421  typePtr->registerInTypeUniquer();
422 }
423 
425  std::unique_ptr<DynamicAttrDefinition> &&attr) {
426  auto *attrPtr = attr.get();
427  auto typeID = attr->getTypeID();
428  auto name = attr->getName();
429  auto *dialect = attr->getDialect();
430 
431  assert(dialect == this &&
432  "trying to register a dynamic attribute in the wrong dialect");
433 
434  // If an attribute with the same name is already defined, fail.
435  auto registered = dynAttrs.try_emplace(typeID, std::move(attr)).second;
436  (void)registered;
437  assert(registered && "attribute TypeID was not unique");
438 
439  registered = nameToDynAttrs.insert({name, attrPtr}).second;
440  (void)registered;
441  assert(registered &&
442  "Trying to create a new dynamic attribute with an existing name");
443 
444  // The StringAttr allocates the attribute name StringRef for the duration of
445  // the MLIR context.
446  MLIRContext *ctx = getContext();
447  auto nameAttr =
448  StringAttr::get(ctx, getNamespace() + "." + attrPtr->getName());
449 
450  auto abstractAttr = AbstractAttribute::get(
454 
455  /// Add the type to the dialect and the type uniquer.
456  addAttribute(typeID, std::move(abstractAttr));
457  attrPtr->registerInAttrUniquer();
458 }
459 
461  std::unique_ptr<DynamicOpDefinition> &&op) {
462  assert(op->dialect == this &&
463  "trying to register a dynamic op in the wrong dialect");
464  RegisteredOperationName::insert(std::move(op), /*attrNames=*/{});
465 }
466 
467 bool ExtensibleDialect::classof(const Dialect *dialect) {
468  return const_cast<Dialect *>(dialect)
469  ->getRegisteredInterface<IsExtensibleDialect>();
470 }
471 
473  StringRef typeName, AsmParser &parser, Type &resultType) const {
474  DynamicTypeDefinition *typeDef = lookupTypeDefinition(typeName);
475  if (!typeDef)
476  return std::nullopt;
477 
478  DynamicType dynType;
479  if (DynamicType::parse(parser, typeDef, dynType))
480  return failure();
481  resultType = dynType;
482  return success();
483 }
484 
486  AsmPrinter &printer) {
487  if (auto dynType = llvm::dyn_cast<DynamicType>(type)) {
488  dynType.print(printer);
489  return success();
490  }
491  return failure();
492 }
493 
495  StringRef attrName, AsmParser &parser, Attribute &resultAttr) const {
496  DynamicAttrDefinition *attrDef = lookupAttrDefinition(attrName);
497  if (!attrDef)
498  return std::nullopt;
499 
500  DynamicAttr dynAttr;
501  if (DynamicAttr::parse(parser, attrDef, dynAttr))
502  return failure();
503  resultAttr = dynAttr;
504  return success();
505 }
506 
508  AsmPrinter &printer) {
509  if (auto dynAttr = llvm::dyn_cast<DynamicAttr>(attribute)) {
510  dynAttr.print(printer);
511  return success();
512  }
513  return failure();
514 }
515 
516 //===----------------------------------------------------------------------===//
517 // Dynamic dialect
518 //===----------------------------------------------------------------------===//
519 
520 namespace {
521 /// Interface that can only be implemented by extensible dialects.
522 /// The interface is used to check if a dialect is extensible or not.
523 class IsDynamicDialect : public DialectInterface::Base<IsDynamicDialect> {
524 public:
525  IsDynamicDialect(Dialect *dialect) : Base(dialect) {}
526 
528 };
529 } // namespace
530 
532  : SelfOwningTypeID(),
533  ExtensibleDialect(name, ctx, SelfOwningTypeID::getTypeID()) {
534  addInterfaces<IsDynamicDialect>();
535 }
536 
537 bool DynamicDialect::classof(const Dialect *dialect) {
538  return const_cast<Dialect *>(dialect)
539  ->getRegisteredInterface<IsDynamicDialect>();
540 }
541 
543  auto loc = parser.getCurrentLocation();
544  StringRef typeTag;
545  if (failed(parser.parseKeyword(&typeTag)))
546  return Type();
547 
548  {
549  Type dynType;
550  auto parseResult = parseOptionalDynamicType(typeTag, parser, dynType);
551  if (parseResult.has_value()) {
552  if (succeeded(parseResult.value()))
553  return dynType;
554  return Type();
555  }
556  }
557 
558  parser.emitError(loc, "expected dynamic type");
559  return Type();
560 }
561 
563  auto wasDynamic = printIfDynamicType(type, printer);
564  (void)wasDynamic;
565  assert(succeeded(wasDynamic) &&
566  "non-dynamic type defined in dynamic dialect");
567 }
568 
570  Type type) const {
571  auto loc = parser.getCurrentLocation();
572  StringRef typeTag;
573  if (failed(parser.parseKeyword(&typeTag)))
574  return Attribute();
575 
576  {
577  Attribute dynAttr;
578  auto parseResult = parseOptionalDynamicAttr(typeTag, parser, dynAttr);
579  if (parseResult.has_value()) {
580  if (succeeded(parseResult.value()))
581  return dynAttr;
582  return Attribute();
583  }
584  }
585 
586  parser.emitError(loc, "expected dynamic attribute");
587  return Attribute();
588 }
590  DialectAsmPrinter &printer) const {
591  auto wasDynamic = printIfDynamicAttr(attr, printer);
592  (void)wasDynamic;
593  assert(succeeded(wasDynamic) &&
594  "non-dynamic attribute defined in dynamic dialect");
595 }
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:331
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.
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:92
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:38
StringRef getNamespace() const
Definition: Dialect.h:54
void addType(TypeID typeID, AbstractType &&typeInfo)
Register a type instance with this dialect.
MLIRContext * getContext() const
Definition: Dialect.h:52
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:314
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
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:369
TypeID getTypeID() const
Return the TypeID owned by this object.
Definition: TypeID.h:381
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:107
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:182
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...
llvm::hash_code hash_value(const StructType::MemberDecorationInfo &memberDecorationInfo)
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
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