MLIR  16.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 
102  ArrayRef<Attribute> params)
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 
148 DynamicTypeDefinition *DynamicType::getTypeDef() { return getImpl()->typeDef; }
149 
150 ArrayRef<Attribute> DynamicType::getParams() { return getImpl()->params; }
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 
219  ArrayRef<Attribute> params)
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 
261 DynamicAttrDefinition *DynamicAttr::getAttrDef() { return getImpl()->attrDef; }
262 
263 ArrayRef<Attribute> DynamicAttr::getParams() { return getImpl()->params; }
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,
298  &&getCanonicalizationPatternsFn,
299  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn)
300  : typeID(dialect->allocateTypeID()),
301  name((dialect->getNamespace() + "." + name).str()), dialect(dialect),
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 
308 std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
309  StringRef name, ExtensibleDialect *dialect,
311  OperationName::VerifyRegionInvariantsFn &&verifyRegionFn) {
312  auto parseFn = [](OpAsmParser &parser, OperationState &result) {
313  return parser.emitError(
314  parser.getCurrentLocation(),
315  "dynamic operation do not define any parser function");
316  };
317 
318  auto printFn = [](Operation *op, OpAsmPrinter &printer, StringRef) {
319  printer.printGenericOp(op);
320  };
321 
322  return DynamicOpDefinition::get(name, dialect, std::move(verifyFn),
323  std::move(verifyRegionFn), std::move(parseFn),
324  std::move(printFn));
325 }
326 
327 std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
328  StringRef name, ExtensibleDialect *dialect,
332  OperationName::PrintAssemblyFn &&printFn) {
333  auto foldHookFn = [](Operation *op, ArrayRef<Attribute> operands,
335  return failure();
336  };
337 
338  auto getCanonicalizationPatternsFn = [](RewritePatternSet &, MLIRContext *) {
339  };
340 
341  auto populateDefaultAttrsFn = [](const RegisteredOperationName &,
342  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,
359  &&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  auto abstractType =
411  DynamicType::getHasTraitFn(), typeID);
412 
413  /// Add the type to the dialect and the type uniquer.
414  addType(typeID, std::move(abstractType));
415  typePtr->registerInTypeUniquer();
416 }
417 
419  std::unique_ptr<DynamicAttrDefinition> &&attr) {
420  auto *attrPtr = attr.get();
421  auto typeID = attr->getTypeID();
422  auto name = attr->getName();
423  auto *dialect = attr->getDialect();
424 
425  assert(dialect == this &&
426  "trying to register a dynamic attribute in the wrong dialect");
427 
428  // If an attribute with the same name is already defined, fail.
429  auto registered = dynAttrs.try_emplace(typeID, std::move(attr)).second;
430  (void)registered;
431  assert(registered && "attribute TypeID was not unique");
432 
433  registered = nameToDynAttrs.insert({name, attrPtr}).second;
434  (void)registered;
435  assert(registered &&
436  "Trying to create a new dynamic attribute with an existing name");
437 
438  auto abstractAttr =
440  DynamicAttr::getHasTraitFn(), typeID);
441 
442  /// Add the type to the dialect and the type uniquer.
443  addAttribute(typeID, std::move(abstractAttr));
444  attrPtr->registerInAttrUniquer();
445 }
446 
448  std::unique_ptr<DynamicOpDefinition> &&op) {
449  assert(op->dialect == this &&
450  "trying to register a dynamic op in the wrong dialect");
451  auto hasTraitFn = [](TypeID traitId) { return false; };
452 
454  op->name, *op->dialect, op->typeID, std::move(op->parseFn),
455  std::move(op->printFn), std::move(op->verifyFn),
456  std::move(op->verifyRegionFn), std::move(op->foldHookFn),
457  std::move(op->getCanonicalizationPatternsFn),
458  detail::InterfaceMap::get<>(), std::move(hasTraitFn), {},
459  std::move(op->populateDefaultAttrsFn));
460 }
461 
462 bool ExtensibleDialect::classof(const Dialect *dialect) {
463  return const_cast<Dialect *>(dialect)
464  ->getRegisteredInterface<IsExtensibleDialect>();
465 }
466 
468  StringRef typeName, AsmParser &parser, Type &resultType) const {
469  DynamicTypeDefinition *typeDef = lookupTypeDefinition(typeName);
470  if (!typeDef)
471  return llvm::None;
472 
473  DynamicType dynType;
474  if (DynamicType::parse(parser, typeDef, dynType))
475  return failure();
476  resultType = dynType;
477  return success();
478 }
479 
481  AsmPrinter &printer) {
482  if (auto dynType = type.dyn_cast<DynamicType>()) {
483  dynType.print(printer);
484  return success();
485  }
486  return failure();
487 }
488 
490  StringRef attrName, AsmParser &parser, Attribute &resultAttr) const {
491  DynamicAttrDefinition *attrDef = lookupAttrDefinition(attrName);
492  if (!attrDef)
493  return llvm::None;
494 
495  DynamicAttr dynAttr;
496  if (DynamicAttr::parse(parser, attrDef, dynAttr))
497  return failure();
498  resultAttr = dynAttr;
499  return success();
500 }
501 
503  AsmPrinter &printer) {
504  if (auto dynAttr = attribute.dyn_cast<DynamicAttr>()) {
505  dynAttr.print(printer);
506  return success();
507  }
508  return failure();
509 }
static ParseResult parse(AsmParser &parser, DynamicTypeDefinition *typeDef, DynamicType &parsedType)
Parse the dynamic type parameters and construct the type.
Include the generated interface declarations.
static LogicalResult typeOrAttrParser(AsmParser &parser, SmallVectorImpl< Attribute > &parsedParams)
Default parser for dynamic attribute or type parameters.
virtual raw_ostream & getStream() const
Return the raw output stream used by this printer.
DynamicTypeDefinition * lookupTypeDefinition(StringRef name) const
Returns nullptr if the definition was not found.
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
The base class used for all derived interface types.
virtual SMLoc getCurrentLocation()=0
Get the location of the next token and store it into the argument.
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:310
static DynamicTypeStorage * construct(TypeStorageAllocator &alloc, const KeyTy &key)
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, ArrayRef< Attribute > params) const
Check that the attribute parameters are valid.
static bool classof(Attribute attr)
Check if an attribute is a dynamic attribute.
Base storage class appearing in a Type.
Definition: TypeSupport.h:122
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
Definition: LogicalResult.h:72
This is a utility allocator used to allocate memory for instances of derived types.
#define MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(CLASS_NAME)
Definition: TypeID.h:274
bool operator==(const KeyTy &key) const
bool operator==(const KeyTy &key) const
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value...
Definition: LogicalResult.h:68
ArrayRef< Attribute > params
The type parameters.
The OpAsmParser has methods for interacting with the asm parser: parsing things from it...
static ParseResult parse(AsmParser &parser, DynamicAttrDefinition *attrDef, DynamicAttr &parsedAttr)
Parse the dynamic attribute parameters and construct the attribute.
llvm::unique_function< ParseResult(AsmParser &parser, llvm::SmallVectorImpl< Attribute > &parsedAttributes) const > ParserFn
llvm::hash_code hash_value(const MPInt &x)
Redeclarations of friend declaration above to make it discoverable by lookups.
Definition: MPInt.cpp:15
static llvm::hash_code hashKey(const KeyTy &key)
llvm::unique_function< ParseResult(OpAsmParser &, OperationState &) const > ParseAssemblyFn
virtual ParseResult parseComma()=0
Parse a , token.
static AbstractType get(Dialect &dialect)
This method is used by Dialect objects when they register the list of types they contain.
Definition: TypeSupport.h:41
std::pair< DynamicTypeDefinition *, ArrayRef< Attribute > > KeyTy
This class provides an efficient unique identifier for a specific C++ type.
Definition: TypeID.h:104
DynamicTypeDefinition * getTypeDef()
Return the type definition of the concrete type.
void registerDynamicOp(std::unique_ptr< DynamicOpDefinition > &&type)
Add a new operation defined at runtime to the dialect.
DynamicTypeStorage(DynamicTypeDefinition *typeDef, ArrayRef< Attribute > params)
llvm::unique_function< LogicalResult(function_ref< InFlightDiagnostic()>, ArrayRef< Attribute >) const > VerifierFn
static DynamicType get(DynamicTypeDefinition *typeDef, ArrayRef< Attribute > params={})
Return an instance of a dynamic type given a dynamic type definition and type parameters.
void addAttribute(TypeID typeID, AbstractAttribute &&attrInfo)
Register an attribute instance with this dialect.
static LogicalResult printIfDynamicAttr(Attribute attr, AsmPrinter &printer)
If &#39;attr&#39; is a dynamic attribute, print it.
A dynamic type instance.
T * allocate()
Allocate an instance of the provided type.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
static std::unique_ptr< DynamicAttrDefinition > get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier)
Create a new attribute definition at runtime.
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
static DynamicAttrStorage * construct(AttributeStorageAllocator &alloc, const KeyTy &key)
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
virtual InFlightDiagnostic emitError(SMLoc loc, const Twine &message={})=0
Emit a diagnostic at the specified location and return failure.
virtual ParseResult parseOptionalLess()=0
Parse a &#39;<&#39; token if present.
llvm::unique_function< LogicalResult(Operation *) const > VerifyInvariantsFn
void print(AsmPrinter &printer)
Print the dynamic attribute with the format &#39;attrname&#39; if there is no parameters, or &#39;attrname<attr (...
llvm::unique_function< void(AsmPrinter &printer, ArrayRef< Attribute > params) const > PrinterFn
llvm::unique_function< LogicalResult(function_ref< InFlightDiagnostic()>, ArrayRef< Attribute >) const > VerifierFn
llvm::unique_function< void(Operation *, OpAsmPrinter &, StringRef) const > PrintAssemblyFn
static HasTraitFn getHasTraitFn()
Returns the function that returns true if the given Trait ID matches the IDs of any of the traits def...
DynamicTypeDefinition * typeDef
Definition of the type.
U dyn_cast() const
Definition: Types.h:270
static LogicalResult printIfDynamicType(Type type, AsmPrinter &printer)
If &#39;type&#39; is a dynamic type, print it.
Attributes are known-constant values of operations.
Definition: Attributes.h:24
static std::unique_ptr< DynamicOpDefinition > get(StringRef name, ExtensibleDialect *dialect, OperationName::VerifyInvariantsFn &&verifyFn, OperationName::VerifyRegionInvariantsFn &&verifyRegionFn)
Create a new op at runtime.
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.
The definition of a dynamic type.
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:41
ArrayRef< Attribute > params
The type parameters.
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
This represents an operation in an abstracted form, suitable for use with the builder APIs...
OptionalParseResult parseOptionalDynamicAttr(StringRef attrName, AsmParser &parser, Attribute &resultAttr) const
Parse the dynamic attribute &#39;attrName&#39; in the dialect &#39;dialect&#39;.
llvm::unique_function< void(const RegisteredOperationName &, NamedAttrList &) const > PopulateDefaultAttrsFn
static std::unique_ptr< DynamicTypeDefinition > get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier)
Create a new dynamic type definition.
MLIRContext * getContext() const
Definition: Dialect.h:55
A dynamic attribute instance.
llvm::unique_function< void(AsmPrinter &printer, ArrayRef< Attribute > params) const > PrinterFn
llvm::unique_function< void(RewritePatternSet &, MLIRContext *) const > GetCanonicalizationPatternsFn
This base class exposes generic asm parser hooks, usable across the various derived parsers...
static AbstractAttribute get(Dialect &dialect)
This method is used by Dialect objects when they register the list of attributes they contain...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
static DynamicAttr get(DynamicAttrDefinition *attrDef, ArrayRef< Attribute > params={})
Return an instance of a dynamic attribute given a dynamic attribute definition and attribute paramete...
The definition of a dynamic op.
static detail::InterfaceMap getInterfaceMap()
Returns an interface map for the interfaces registered to this 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...
This class implements Optional functionality for ParseResult.
Definition: OpDefinition.h:37
static llvm::hash_code hashKey(const KeyTy &key)
A dialect that can be extended with new operations/types/attributes at runtime.
static bool classof(Type type)
Check if a type is a dynamic type.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
virtual ParseResult parseOptionalGreater()=0
Parse a &#39;>&#39; token if present.
llvm::unique_function< LogicalResult(Operation *) const > VerifyRegionInvariantsFn
ArrayRef< Attribute > getParams()
Return the attribute parameters.
std::pair< DynamicAttrDefinition *, ArrayRef< Attribute > > KeyTy
void print(AsmPrinter &printer)
Print the dynamic type with the format &#39;type&#39; or &#39;type<>&#39; if there is no parameters, or &#39;type<attr (,attr)*>&#39;.
The definition of a dynamic attribute.
StringRef getNamespace() const
Definition: Dialect.h:57
U dyn_cast() const
Definition: Attributes.h:127
static void insert(Dialect &dialect)
Register a new operation in a Dialect object.
DynamicAttrDefinition * getAttrDef()
Return the attribute definition of the concrete attribute.
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 &#39;typeName&#39; in the dialect &#39;dialect&#39;.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:55
DynamicAttrDefinition * attrDef
Definition of the type.
Base storage class appearing in an attribute.
ExtensibleDialect(StringRef name, MLIRContext *ctx, TypeID typeID)
llvm::unique_function< LogicalResult(Operation *, ArrayRef< Attribute >, SmallVectorImpl< OpFoldResult > &) const > FoldHookFn
This base class exposes generic asm printer hooks, usable across the various derived printers...
ArrayRef< T > copyInto(ArrayRef< T > elements)
Copy the specified array of elements into memory managed by our bump pointer allocator.
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, ArrayRef< Attribute > params) const
Check that the type parameters are valid.
static void typeOrAttrPrinter(AsmPrinter &printer, ArrayRef< Attribute > params)
Default printer for dynamic attribute or type parameters.
This is a "type erased" representation of a registered operation.
bool hasTrait()
Returns true if the type was registered with a particular trait.
Definition: Types.h:181
MLIRContext & getContext() const
Return the MLIRContext in which the dynamic types is uniqued.
MLIRContext & getContext() const
Return the MLIRContext in which the dynamic attributes are uniqued.
void addType(TypeID typeID, AbstractType &&typeInfo)
Register a type instance with this dialect.
ArrayRef< Attribute > getParams()
Return the type parameters.
DynamicAttrDefinition * lookupAttrDefinition(StringRef name) const
Returns nullptr if the definition was not found.
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...
This class represents success/failure for parsing-like operations that find it important to chain tog...
virtual ParseResult parseAttribute(Attribute &result, Type type={})=0
Parse an arbitrary attribute of a given type and return it in result.
TypeID getTypeID() const
Return the TypeID owned by this object.
Definition: TypeID.h:324
llvm::unique_function< ParseResult(AsmParser &parser, llvm::SmallVectorImpl< Attribute > &parsedAttributes) const > ParserFn
DynamicAttrStorage(DynamicAttrDefinition *attrDef, ArrayRef< Attribute > params)
auto getChecked(SMLoc loc, ParamsT &&...params)
Invoke the getChecked method of the given Attribute or Type class, using the provided location to emi...
static bool classof(const Dialect *dialect)
Check if the dialect is an extensible dialect.
bool hasTrait()
Returns true if the type was registered with a particular trait.
Definition: Attributes.h:92
void registerDynamicType(std::unique_ptr< DynamicTypeDefinition > &&type)
Add a new type defined at runtime to the dialect.