MLIR  20.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 
15 using namespace mlir;
16 
17 //===----------------------------------------------------------------------===//
18 // Dynamic types and attributes shared functions
19 //===----------------------------------------------------------------------===//
20 
21 /// Default parser for dynamic attribute or type parameters.
22 /// Parse in the format '(<>)?' or '<attr (,attr)*>'.
23 static LogicalResult
25  // No parameters
26  if (parser.parseOptionalLess() || !parser.parseOptionalGreater())
27  return success();
28 
29  Attribute attr;
30  if (parser.parseAttribute(attr))
31  return failure();
32  parsedParams.push_back(attr);
33 
34  while (parser.parseOptionalGreater()) {
35  Attribute attr;
36  if (parser.parseComma() || parser.parseAttribute(attr))
37  return failure();
38  parsedParams.push_back(attr);
39  }
40 
41  return success();
42 }
43 
44 /// Default printer for dynamic attribute or type parameters.
45 /// Print in the format '(<>)?' or '<attr (,attr)*>'.
46 static void typeOrAttrPrinter(AsmPrinter &printer, ArrayRef<Attribute> params) {
47  if (params.empty())
48  return;
49 
50  printer << "<";
51  interleaveComma(params, printer.getStream());
52  printer << ">";
53 }
54 
55 //===----------------------------------------------------------------------===//
56 // Dynamic type
57 //===----------------------------------------------------------------------===//
58 
59 std::unique_ptr<DynamicTypeDefinition>
61  VerifierFn &&verifier) {
62  return DynamicTypeDefinition::get(name, dialect, std::move(verifier),
64 }
65 
66 std::unique_ptr<DynamicTypeDefinition>
68  VerifierFn &&verifier, ParserFn &&parser,
69  PrinterFn &&printer) {
70  return std::unique_ptr<DynamicTypeDefinition>(
71  new DynamicTypeDefinition(name, dialect, std::move(verifier),
72  std::move(parser), std::move(printer)));
73 }
74 
75 DynamicTypeDefinition::DynamicTypeDefinition(StringRef nameRef,
76  ExtensibleDialect *dialect,
77  VerifierFn &&verifier,
78  ParserFn &&parser,
79  PrinterFn &&printer)
80  : name(nameRef), dialect(dialect), verifier(std::move(verifier)),
81  parser(std::move(parser)), printer(std::move(printer)),
82  ctx(dialect->getContext()) {}
83 
84 DynamicTypeDefinition::DynamicTypeDefinition(ExtensibleDialect *dialect,
85  StringRef nameRef)
86  : name(nameRef), dialect(dialect), ctx(dialect->getContext()) {}
87 
88 void DynamicTypeDefinition::registerInTypeUniquer() {
89  detail::TypeUniquer::registerType<DynamicType>(&getContext(), getTypeID());
90 }
91 
92 namespace mlir {
93 namespace detail {
94 /// Storage of DynamicType.
95 /// Contains a pointer to the type definition and type parameters.
97 
98  using KeyTy = std::pair<DynamicTypeDefinition *, ArrayRef<Attribute>>;
99 
102  : typeDef(typeDef), params(params) {}
103 
104  bool operator==(const KeyTy &key) const {
105  return typeDef == key.first && params == key.second;
106  }
107 
108  static llvm::hash_code hashKey(const KeyTy &key) {
109  return llvm::hash_value(key);
110  }
111 
113  const KeyTy &key) {
114  return new (alloc.allocate<DynamicTypeStorage>())
115  DynamicTypeStorage(key.first, alloc.copyInto(key.second));
116  }
117 
118  /// Definition of the type.
120 
121  /// The type parameters.
123 };
124 } // namespace detail
125 } // namespace mlir
126 
128  ArrayRef<Attribute> params) {
129  auto &ctx = typeDef->getContext();
131  assert(succeeded(typeDef->verify(emitError, params)));
132  return detail::TypeUniquer::getWithTypeID<DynamicType>(
133  &ctx, typeDef->getTypeID(), typeDef, params);
134 }
135 
138  DynamicTypeDefinition *typeDef,
139  ArrayRef<Attribute> params) {
140  if (failed(typeDef->verify(emitError, params)))
141  return {};
142  auto &ctx = typeDef->getContext();
143  return detail::TypeUniquer::getWithTypeID<DynamicType>(
144  &ctx, typeDef->getTypeID(), typeDef, params);
145 }
146 
148 
150 
152  return type.hasTrait<TypeTrait::IsDynamicType>();
153 }
154 
155 ParseResult DynamicType::parse(AsmParser &parser,
156  DynamicTypeDefinition *typeDef,
157  DynamicType &parsedType) {
158  SmallVector<Attribute> params;
159  if (failed(typeDef->parser(parser, params)))
160  return failure();
161  parsedType = parser.getChecked<DynamicType>(typeDef, params);
162  if (!parsedType)
163  return failure();
164  return success();
165 }
166 
168  printer << getTypeDef()->getName();
169  getTypeDef()->printer(printer, getParams());
170 }
171 
172 //===----------------------------------------------------------------------===//
173 // Dynamic attribute
174 //===----------------------------------------------------------------------===//
175 
176 std::unique_ptr<DynamicAttrDefinition>
178  VerifierFn &&verifier) {
179  return DynamicAttrDefinition::get(name, dialect, std::move(verifier),
181 }
182 
183 std::unique_ptr<DynamicAttrDefinition>
185  VerifierFn &&verifier, ParserFn &&parser,
186  PrinterFn &&printer) {
187  return std::unique_ptr<DynamicAttrDefinition>(
188  new DynamicAttrDefinition(name, dialect, std::move(verifier),
189  std::move(parser), std::move(printer)));
190 }
191 
192 DynamicAttrDefinition::DynamicAttrDefinition(StringRef nameRef,
193  ExtensibleDialect *dialect,
194  VerifierFn &&verifier,
195  ParserFn &&parser,
196  PrinterFn &&printer)
197  : name(nameRef), dialect(dialect), verifier(std::move(verifier)),
198  parser(std::move(parser)), printer(std::move(printer)),
199  ctx(dialect->getContext()) {}
200 
201 DynamicAttrDefinition::DynamicAttrDefinition(ExtensibleDialect *dialect,
202  StringRef nameRef)
203  : name(nameRef), dialect(dialect), ctx(dialect->getContext()) {}
204 
205 void DynamicAttrDefinition::registerInAttrUniquer() {
206  detail::AttributeUniquer::registerAttribute<DynamicAttr>(&getContext(),
207  getTypeID());
208 }
209 
210 namespace mlir {
211 namespace detail {
212 /// Storage of DynamicAttr.
213 /// Contains a pointer to the attribute definition and attribute parameters.
215  using KeyTy = std::pair<DynamicAttrDefinition *, ArrayRef<Attribute>>;
216 
219  : attrDef(attrDef), params(params) {}
220 
221  bool operator==(const KeyTy &key) const {
222  return attrDef == key.first && params == key.second;
223  }
224 
225  static llvm::hash_code hashKey(const KeyTy &key) {
226  return llvm::hash_value(key);
227  }
228 
230  const KeyTy &key) {
231  return new (alloc.allocate<DynamicAttrStorage>())
232  DynamicAttrStorage(key.first, alloc.copyInto(key.second));
233  }
234 
235  /// Definition of the type.
237 
238  /// The type parameters.
240 };
241 } // namespace detail
242 } // namespace mlir
243 
245  ArrayRef<Attribute> params) {
246  auto &ctx = attrDef->getContext();
247  return detail::AttributeUniquer::getWithTypeID<DynamicAttr>(
248  &ctx, attrDef->getTypeID(), attrDef, params);
249 }
250 
253  DynamicAttrDefinition *attrDef,
254  ArrayRef<Attribute> params) {
255  if (failed(attrDef->verify(emitError, params)))
256  return {};
257  return get(attrDef, params);
258 }
259 
261 
263 
266 }
267 
268 ParseResult DynamicAttr::parse(AsmParser &parser,
269  DynamicAttrDefinition *attrDef,
270  DynamicAttr &parsedAttr) {
271  SmallVector<Attribute> params;
272  if (failed(attrDef->parser(parser, params)))
273  return failure();
274  parsedAttr = parser.getChecked<DynamicAttr>(attrDef, params);
275  if (!parsedAttr)
276  return failure();
277  return success();
278 }
279 
281  printer << getAttrDef()->getName();
282  getAttrDef()->printer(printer, getParams());
283 }
284 
285 //===----------------------------------------------------------------------===//
286 // Dynamic operation
287 //===----------------------------------------------------------------------===//
288 
289 DynamicOpDefinition::DynamicOpDefinition(
290  StringRef name, ExtensibleDialect *dialect,
295  OperationName::FoldHookFn &&foldHookFn,
296  GetCanonicalizationPatternsFn &&getCanonicalizationPatternsFn,
297  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn)
298  : Impl(StringAttr::get(dialect->getContext(),
299  (dialect->getNamespace() + "." + name).str()),
300  dialect, dialect->allocateTypeID(),
301  /*interfaceMap=*/detail::InterfaceMap()),
302  verifyFn(std::move(verifyFn)), verifyRegionFn(std::move(verifyRegionFn)),
303  parseFn(std::move(parseFn)), printFn(std::move(printFn)),
304  foldHookFn(std::move(foldHookFn)),
305  getCanonicalizationPatternsFn(std::move(getCanonicalizationPatternsFn)),
306  populateDefaultAttrsFn(std::move(populateDefaultAttrsFn)) {
307  typeID = dialect->allocateTypeID();
308 }
309 
310 std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
311  StringRef name, ExtensibleDialect *dialect,
313  OperationName::VerifyRegionInvariantsFn &&verifyRegionFn) {
314  auto parseFn = [](OpAsmParser &parser, OperationState &result) {
315  return parser.emitError(
316  parser.getCurrentLocation(),
317  "dynamic operation do not define any parser function");
318  };
319 
320  auto printFn = [](Operation *op, OpAsmPrinter &printer, StringRef) {
321  printer.printGenericOp(op);
322  };
323 
324  return DynamicOpDefinition::get(name, dialect, std::move(verifyFn),
325  std::move(verifyRegionFn), std::move(parseFn),
326  std::move(printFn));
327 }
328 
329 std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
330  StringRef name, ExtensibleDialect *dialect,
334  OperationName::PrintAssemblyFn &&printFn) {
335  auto foldHookFn = [](Operation *op, ArrayRef<Attribute> operands,
337  return failure();
338  };
339 
340  auto getCanonicalizationPatternsFn = [](RewritePatternSet &, MLIRContext *) {
341  };
342 
343  auto populateDefaultAttrsFn = [](const OperationName &, NamedAttrList &) {};
344 
345  return DynamicOpDefinition::get(name, dialect, std::move(verifyFn),
346  std::move(verifyRegionFn), std::move(parseFn),
347  std::move(printFn), std::move(foldHookFn),
348  std::move(getCanonicalizationPatternsFn),
349  std::move(populateDefaultAttrsFn));
350 }
351 
352 std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
353  StringRef name, ExtensibleDialect *dialect,
355  OperationName::VerifyInvariantsFn &&verifyRegionFn,
358  OperationName::FoldHookFn &&foldHookFn,
359  GetCanonicalizationPatternsFn &&getCanonicalizationPatternsFn,
360  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn) {
361  return std::unique_ptr<DynamicOpDefinition>(new DynamicOpDefinition(
362  name, dialect, std::move(verifyFn), std::move(verifyRegionFn),
363  std::move(parseFn), std::move(printFn), std::move(foldHookFn),
364  std::move(getCanonicalizationPatternsFn),
365  std::move(populateDefaultAttrsFn)));
366 }
367 
368 //===----------------------------------------------------------------------===//
369 // Extensible dialect
370 //===----------------------------------------------------------------------===//
371 
372 namespace {
373 /// Interface that can only be implemented by extensible dialects.
374 /// The interface is used to check if a dialect is extensible or not.
375 class IsExtensibleDialect : public DialectInterface::Base<IsExtensibleDialect> {
376 public:
377  IsExtensibleDialect(Dialect *dialect) : Base(dialect) {}
378 
380 };
381 } // namespace
382 
384  TypeID typeID)
385  : Dialect(name, ctx, typeID) {
386  addInterfaces<IsExtensibleDialect>();
387 }
388 
390  std::unique_ptr<DynamicTypeDefinition> &&type) {
391  DynamicTypeDefinition *typePtr = type.get();
392  TypeID typeID = type->getTypeID();
393  StringRef name = type->getName();
394  ExtensibleDialect *dialect = type->getDialect();
395 
396  assert(dialect == this &&
397  "trying to register a dynamic type in the wrong dialect");
398 
399  // If a type with the same name is already defined, fail.
400  auto registered = dynTypes.try_emplace(typeID, std::move(type)).second;
401  (void)registered;
402  assert(registered && "type TypeID was not unique");
403 
404  registered = nameToDynTypes.insert({name, typePtr}).second;
405  (void)registered;
406  assert(registered &&
407  "Trying to create a new dynamic type with an existing name");
408 
409  // The StringAttr allocates the type name StringRef for the duration of the
410  // MLIR context.
411  MLIRContext *ctx = getContext();
412  auto nameAttr =
413  StringAttr::get(ctx, getNamespace() + "." + typePtr->getName());
414 
415  auto abstractType = AbstractType::get(
419 
420  /// Add the type to the dialect and the type uniquer.
421  addType(typeID, std::move(abstractType));
422  typePtr->registerInTypeUniquer();
423 }
424 
426  std::unique_ptr<DynamicAttrDefinition> &&attr) {
427  auto *attrPtr = attr.get();
428  auto typeID = attr->getTypeID();
429  auto name = attr->getName();
430  auto *dialect = attr->getDialect();
431 
432  assert(dialect == this &&
433  "trying to register a dynamic attribute in the wrong dialect");
434 
435  // If an attribute with the same name is already defined, fail.
436  auto registered = dynAttrs.try_emplace(typeID, std::move(attr)).second;
437  (void)registered;
438  assert(registered && "attribute TypeID was not unique");
439 
440  registered = nameToDynAttrs.insert({name, attrPtr}).second;
441  (void)registered;
442  assert(registered &&
443  "Trying to create a new dynamic attribute with an existing name");
444 
445  // The StringAttr allocates the attribute name StringRef for the duration of
446  // the MLIR context.
447  MLIRContext *ctx = getContext();
448  auto nameAttr =
449  StringAttr::get(ctx, getNamespace() + "." + attrPtr->getName());
450 
451  auto abstractAttr = AbstractAttribute::get(
455 
456  /// Add the type to the dialect and the type uniquer.
457  addAttribute(typeID, std::move(abstractAttr));
458  attrPtr->registerInAttrUniquer();
459 }
460 
462  std::unique_ptr<DynamicOpDefinition> &&op) {
463  assert(op->dialect == this &&
464  "trying to register a dynamic op in the wrong dialect");
465  RegisteredOperationName::insert(std::move(op), /*attrNames=*/{});
466 }
467 
468 bool ExtensibleDialect::classof(const Dialect *dialect) {
469  return const_cast<Dialect *>(dialect)
470  ->getRegisteredInterface<IsExtensibleDialect>();
471 }
472 
474  StringRef typeName, AsmParser &parser, Type &resultType) const {
475  DynamicTypeDefinition *typeDef = lookupTypeDefinition(typeName);
476  if (!typeDef)
477  return std::nullopt;
478 
479  DynamicType dynType;
480  if (DynamicType::parse(parser, typeDef, dynType))
481  return failure();
482  resultType = dynType;
483  return success();
484 }
485 
487  AsmPrinter &printer) {
488  if (auto dynType = llvm::dyn_cast<DynamicType>(type)) {
489  dynType.print(printer);
490  return success();
491  }
492  return failure();
493 }
494 
496  StringRef attrName, AsmParser &parser, Attribute &resultAttr) const {
497  DynamicAttrDefinition *attrDef = lookupAttrDefinition(attrName);
498  if (!attrDef)
499  return std::nullopt;
500 
501  DynamicAttr dynAttr;
502  if (DynamicAttr::parse(parser, attrDef, dynAttr))
503  return failure();
504  resultAttr = dynAttr;
505  return success();
506 }
507 
509  AsmPrinter &printer) {
510  if (auto dynAttr = llvm::dyn_cast<DynamicAttr>(attribute)) {
511  dynAttr.print(printer);
512  return success();
513  }
514  return failure();
515 }
516 
517 //===----------------------------------------------------------------------===//
518 // Dynamic dialect
519 //===----------------------------------------------------------------------===//
520 
521 namespace {
522 /// Interface that can only be implemented by extensible dialects.
523 /// The interface is used to check if a dialect is extensible or not.
524 class IsDynamicDialect : public DialectInterface::Base<IsDynamicDialect> {
525 public:
526  IsDynamicDialect(Dialect *dialect) : Base(dialect) {}
527 
529 };
530 } // namespace
531 
533  : SelfOwningTypeID(),
534  ExtensibleDialect(name, ctx, SelfOwningTypeID::getTypeID()) {
535  addInterfaces<IsDynamicDialect>();
536 }
537 
538 bool DynamicDialect::classof(const Dialect *dialect) {
539  return const_cast<Dialect *>(dialect)
540  ->getRegisteredInterface<IsDynamicDialect>();
541 }
542 
544  auto loc = parser.getCurrentLocation();
545  StringRef typeTag;
546  if (failed(parser.parseKeyword(&typeTag)))
547  return Type();
548 
549  {
550  Type dynType;
551  auto parseResult = parseOptionalDynamicType(typeTag, parser, dynType);
552  if (parseResult.has_value()) {
553  if (succeeded(parseResult.value()))
554  return dynType;
555  return Type();
556  }
557  }
558 
559  parser.emitError(loc, "expected dynamic type");
560  return Type();
561 }
562 
564  auto wasDynamic = printIfDynamicType(type, printer);
565  (void)wasDynamic;
566  assert(succeeded(wasDynamic) &&
567  "non-dynamic type defined in dynamic dialect");
568 }
569 
571  Type type) const {
572  auto loc = parser.getCurrentLocation();
573  StringRef typeTag;
574  if (failed(parser.parseKeyword(&typeTag)))
575  return Attribute();
576 
577  {
578  Attribute dynAttr;
579  auto parseResult = parseOptionalDynamicAttr(typeTag, parser, dynAttr);
580  if (parseResult.has_value()) {
581  if (succeeded(parseResult.value()))
582  return dynAttr;
583  return Attribute();
584  }
585  }
586 
587  parser.emitError(loc, "expected dynamic attribute");
588  return Attribute();
589 }
591  DialectAsmPrinter &printer) const {
592  auto wasDynamic = printIfDynamicAttr(attr, printer);
593  (void)wasDynamic;
594  assert(succeeded(wasDynamic) &&
595  "non-dynamic attribute defined in dynamic dialect");
596 }
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: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:313
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: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:201
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:262
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