MLIR 23.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
16using 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)*>'.
24static 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)*>'.
47static 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
58std::unique_ptr<DynamicTypeDefinition>
59DynamicTypeDefinition::get(StringRef name, ExtensibleDialect *dialect,
60 VerifierFn &&verifier) {
61 return DynamicTypeDefinition::get(name, dialect, std::move(verifier),
63}
64
65std::unique_ptr<DynamicTypeDefinition>
66DynamicTypeDefinition::get(StringRef name, ExtensibleDialect *dialect,
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
74DynamicTypeDefinition::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
83DynamicTypeDefinition::DynamicTypeDefinition(ExtensibleDialect *dialect,
84 StringRef nameRef)
85 : name(nameRef), dialect(dialect), ctx(dialect->getContext()) {}
86
87void DynamicTypeDefinition::registerInTypeUniquer() {
89}
90
91namespace mlir {
92namespace 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
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)));
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();
143 &ctx, typeDef->getTypeID(), typeDef, params);
144}
145
147
149
151 return type.hasTrait<TypeTrait::IsDynamicType>();
152}
153
154ParseResult DynamicType::parse(AsmParser &parser,
155 DynamicTypeDefinition *typeDef,
156 DynamicType &parsedType) {
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
175std::unique_ptr<DynamicAttrDefinition>
176DynamicAttrDefinition::get(StringRef name, ExtensibleDialect *dialect,
177 VerifierFn &&verifier) {
178 return DynamicAttrDefinition::get(name, dialect, std::move(verifier),
180}
181
182std::unique_ptr<DynamicAttrDefinition>
183DynamicAttrDefinition::get(StringRef name, ExtensibleDialect *dialect,
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
191DynamicAttrDefinition::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
200DynamicAttrDefinition::DynamicAttrDefinition(ExtensibleDialect *dialect,
201 StringRef nameRef)
202 : name(nameRef), dialect(dialect), ctx(dialect->getContext()) {}
203
204void DynamicAttrDefinition::registerInAttrUniquer() {
206 getTypeID());
207}
208
209namespace mlir {
210namespace 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
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();
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
266
267ParseResult DynamicAttr::parse(AsmParser &parser,
268 DynamicAttrDefinition *attrDef,
269 DynamicAttr &parsedAttr) {
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
288DynamicOpDefinition::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 // DynamicOpDefinition doesn't support properties, so use the ID of void.
308 propertiesTypeID = TypeID();
309}
310
311std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
312 StringRef name, ExtensibleDialect *dialect,
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
330std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
331 StringRef name, ExtensibleDialect *dialect,
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
353std::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
373namespace {
374/// Interface that can only be implemented by extensible dialects.
375/// The interface is used to check if a dialect is extensible or not.
376class IsExtensibleDialect : public DialectInterface::Base<IsExtensibleDialect> {
377public:
378 IsExtensibleDialect(Dialect *dialect) : Base(dialect) {}
379
381};
382} // namespace
383
385 TypeID typeID)
386 : Dialect(name, ctx, typeID) {
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
470 return const_cast<Dialect *>(dialect)
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
522namespace {
523/// Interface that can only be implemented by extensible dialects.
524/// The interface is used to check if a dialect is extensible or not.
525class IsDynamicDialect : public DialectInterface::Base<IsDynamicDialect> {
526public:
527 IsDynamicDialect(Dialect *dialect) : Base(dialect) {}
528
530};
531} // namespace
532
538
539bool DynamicDialect::classof(const Dialect *dialect) {
540 return const_cast<Dialect *>(dialect)
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}
return success()
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.
b getContext())
#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...
detail::DialectInterfaceBase< ConcreteType, DialectInterface > Base
The base class used for all derived interface types.
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition Dialect.h:38
MLIRContext * getContext() const
Definition Dialect.h:52
void addInterfaces()
Register a set of dialect interfaces with this dialect instance.
Definition Dialect.h:196
friend class MLIRContext
Definition Dialect.h:371
StringRef getNamespace() const
Definition Dialect.h:54
void addType(TypeID typeID, AbstractType &&typeInfo)
Register a type instance with this dialect.
DialectInterface * getRegisteredInterface(TypeID interfaceID)
Lookup an interface for the given ID if one is registered, otherwise nullptr.
Definition Dialect.h:158
Dialect(StringRef name, MLIRContext *context, TypeID id)
The constructor takes a unique namespace for this dialect as well as the context to bind to.
Definition Dialect.cpp:35
void addAttribute(TypeID typeID, AbstractAttribute &&attrInfo)
Register an attribute instance with this dialect.
The definition of a dynamic attribute.
llvm::unique_function< void( AsmPrinter &printer, ArrayRef< Attribute > params) const > PrinterFn
static std::unique_ptr< DynamicAttrDefinition > get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier)
Create a new attribute definition at runtime.
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< ParseResult( AsmParser &parser, llvm::SmallVectorImpl< Attribute > &parsedAttributes) const > ParserFn
MLIRContext & getContext() const
Return the MLIRContext in which the dynamic attributes are uniqued.
llvm::unique_function< LogicalResult( function_ref< InFlightDiagnostic()>, ArrayRef< Attribute >) const > VerifierFn
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.
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.
llvm::unique_function< void( AsmPrinter &printer, ArrayRef< Attribute > params) const > PrinterFn
MLIRContext & getContext() const
Return the MLIRContext in which the dynamic types is uniqued.
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'.
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.
DynamicTypeDefinition * lookupTypeDefinition(StringRef name) const
Returns nullptr if the definition was not found.
static LogicalResult printIfDynamicType(Type type, AsmPrinter &printer)
If 'type' is a dynamic type, print it.
DynamicAttrDefinition * lookupAttrDefinition(StringRef name) const
Returns nullptr if the definition was not found.
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)
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'.
This class represents a diagnostic that is inflight and set to be reported.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
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< void(const OperationName &, NamedAttrList &) const > PopulateDefaultAttrsFn
llvm::unique_function< ParseResult(OpAsmParser &, OperationState &)> ParseAssemblyFn
llvm::unique_function< LogicalResult(Operation *) const > VerifyRegionInvariantsFn
llvm::unique_function< LogicalResult( Operation *, ArrayRef< Attribute >, SmallVectorImpl< OpFoldResult > &) const > FoldHookFn
llvm::unique_function< void(Operation *, OpAsmPrinter &, StringRef) const > PrintAssemblyFn
Operation is the basic unit of execution within MLIR.
Definition Operation.h:88
This class implements Optional functionality for ParseResult.
static void insert(Dialect &dialect)
Register a new operation in a Dialect object.
TypeID getTypeID() const
Return the TypeID owned by this object.
Definition TypeID.h:381
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
TypeStorage()
This constructor is used by derived classes as part of the TypeUniquer.
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:185
static void registerAttribute(MLIRContext *ctx)
Register an attribute instance T with the uniquer.
static std::enable_if_t< !std::is_same< typename T::ImplType, AttributeStorage >::value, T > getWithTypeID(MLIRContext *ctx, TypeID typeID, Args &&...args)
Get an uniqued instance of a parametric attribute T.
AttrTypeReplacer.
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...
Include the generated interface declarations.
StorageUniquer::StorageAllocator TypeStorageAllocator
This is a utility allocator used to allocate memory for instances of derived Types.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
StorageUniquer::StorageAllocator AttributeStorageAllocator
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
llvm::function_ref< Fn > function_ref
Definition LLVM.h:147
This represents an operation in an abstracted form, suitable for use with the builder APIs.
DynamicAttrStorage(DynamicAttrDefinition *attrDef, ArrayRef< Attribute > params)
static DynamicAttrStorage * construct(AttributeStorageAllocator &alloc, const KeyTy &key)
std::pair< DynamicAttrDefinition *, ArrayRef< Attribute > > KeyTy
static llvm::hash_code hashKey(const KeyTy &key)
bool operator==(const KeyTy &key) const
DynamicAttrDefinition * attrDef
Definition of the type.
ArrayRef< Attribute > params
The type parameters.
ArrayRef< Attribute > params
The type parameters.
std::pair< DynamicTypeDefinition *, ArrayRef< Attribute > > KeyTy
static DynamicTypeStorage * construct(TypeStorageAllocator &alloc, const KeyTy &key)
static llvm::hash_code hashKey(const KeyTy &key)
DynamicTypeDefinition * typeDef
Definition of the type.
DynamicTypeStorage(DynamicTypeDefinition *typeDef, ArrayRef< Attribute > params)
bool operator==(const KeyTy &key) const
static std::enable_if_t< !std::is_same< typename T::ImplType, TypeStorage >::value, T > getWithTypeID(MLIRContext *ctx, TypeID typeID, Args &&...args)
Get an uniqued instance of a parametric type T.
static void registerType(MLIRContext *ctx)
Register a type instance T with the uniquer.