33 parsedParams.push_back(attr);
39 parsedParams.push_back(attr);
52 interleaveComma(params, printer.
getStream());
60 std::unique_ptr<DynamicTypeDefinition>
67 std::unique_ptr<DynamicTypeDefinition>
71 return std::unique_ptr<DynamicTypeDefinition>(
73 std::move(parser), std::move(printer)));
76 DynamicTypeDefinition::DynamicTypeDefinition(StringRef nameRef,
78 VerifierFn &&verifier,
81 : name(nameRef), dialect(dialect), verifier(std::move(verifier)),
82 parser(std::move(parser)), printer(std::move(printer)),
87 : name(nameRef), dialect(dialect), ctx(dialect->
getContext()) {}
89 void DynamicTypeDefinition::registerInTypeUniquer() {
99 using KeyTy = std::pair<DynamicTypeDefinition *, ArrayRef<Attribute>>;
133 return detail::TypeUniquer::getWithTypeID<DynamicType>(
134 &ctx, typeDef->
getTypeID(), typeDef, params);
144 return detail::TypeUniquer::getWithTypeID<DynamicType>(
145 &ctx, typeDef->
getTypeID(), typeDef, params);
160 if (
failed(typeDef->parser(parser, params)))
177 std::unique_ptr<DynamicAttrDefinition>
184 std::unique_ptr<DynamicAttrDefinition>
188 return std::unique_ptr<DynamicAttrDefinition>(
190 std::move(parser), std::move(printer)));
193 DynamicAttrDefinition::DynamicAttrDefinition(StringRef nameRef,
195 VerifierFn &&verifier,
198 : name(nameRef), dialect(dialect), verifier(std::move(verifier)),
199 parser(std::move(parser)), printer(std::move(printer)),
204 : name(nameRef), dialect(dialect), ctx(dialect->
getContext()) {}
206 void DynamicAttrDefinition::registerInAttrUniquer() {
207 detail::AttributeUniquer::registerAttribute<DynamicAttr>(&
getContext(),
216 using KeyTy = std::pair<DynamicAttrDefinition *, ArrayRef<Attribute>>;
248 return detail::AttributeUniquer::getWithTypeID<DynamicAttr>(
249 &ctx, attrDef->
getTypeID(), attrDef, params);
258 return get(attrDef, params);
273 if (
failed(attrDef->parser(parser, params)))
290 DynamicOpDefinition::DynamicOpDefinition(
297 GetCanonicalizationPatternsFn &&getCanonicalizationPatternsFn,
300 (dialect->getNamespace() +
"." + name).str()),
301 dialect, dialect->allocateTypeID(),
302 detail::InterfaceMap()),
303 verifyFn(std::move(verifyFn)), verifyRegionFn(std::move(verifyRegionFn)),
304 parseFn(std::move(parseFn)), printFn(std::move(printFn)),
305 foldHookFn(std::move(foldHookFn)),
306 getCanonicalizationPatternsFn(std::move(getCanonicalizationPatternsFn)),
307 populateDefaultAttrsFn(std::move(populateDefaultAttrsFn)) {
308 typeID = dialect->allocateTypeID();
318 "dynamic operation do not define any parser function");
322 printer.printGenericOp(op);
326 std::move(verifyRegionFn), std::move(parseFn),
347 std::move(verifyRegionFn), std::move(parseFn),
348 std::move(printFn), std::move(foldHookFn),
349 std::move(getCanonicalizationPatternsFn),
350 std::move(populateDefaultAttrsFn));
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)));
378 IsExtensibleDialect(
Dialect *dialect) : Base(dialect) {}
387 addInterfaces<IsExtensibleDialect>();
391 std::unique_ptr<DynamicTypeDefinition> &&type) {
393 TypeID typeID = type->getTypeID();
394 StringRef name = type->getName();
397 assert(dialect ==
this &&
398 "trying to register a dynamic type in the wrong dialect");
401 auto registered = dynTypes.try_emplace(typeID, std::move(type)).second;
403 assert(registered &&
"type TypeID was not unique");
405 registered = nameToDynTypes.insert({name, typePtr}).second;
408 "Trying to create a new dynamic type with an existing name");
416 addType(typeID, std::move(abstractType));
417 typePtr->registerInTypeUniquer();
421 std::unique_ptr<DynamicAttrDefinition> &&attr) {
422 auto *attrPtr = attr.get();
423 auto typeID = attr->getTypeID();
424 auto name = attr->getName();
425 auto *dialect = attr->getDialect();
427 assert(dialect ==
this &&
428 "trying to register a dynamic attribute in the wrong dialect");
431 auto registered = dynAttrs.try_emplace(typeID, std::move(attr)).second;
433 assert(registered &&
"attribute TypeID was not unique");
435 registered = nameToDynAttrs.insert({name, attrPtr}).second;
438 "Trying to create a new dynamic attribute with an existing name");
447 attrPtr->registerInAttrUniquer();
451 std::unique_ptr<DynamicOpDefinition> &&op) {
452 assert(op->dialect ==
this &&
453 "trying to register a dynamic op in the wrong dialect");
458 return const_cast<Dialect *
>(dialect)
459 ->getRegisteredInterface<IsExtensibleDialect>();
463 StringRef typeName,
AsmParser &parser,
Type &resultType)
const {
471 resultType = dynType;
477 if (
auto dynType = llvm::dyn_cast<DynamicType>(type)) {
478 dynType.print(printer);
493 resultAttr = dynAttr;
499 if (
auto dynAttr = llvm::dyn_cast<DynamicAttr>(attribute)) {
500 dynAttr.print(printer);
515 IsDynamicDialect(
Dialect *dialect) : Base(dialect) {}
524 addInterfaces<IsDynamicDialect>();
528 return const_cast<Dialect *
>(dialect)
529 ->getRegisteredInterface<IsDynamicDialect>();
541 if (parseResult.has_value()) {
548 parser.
emitError(loc,
"expected dynamic type");
556 "non-dynamic type defined in dynamic dialect");
569 if (parseResult.has_value()) {
576 parser.
emitError(loc,
"expected dynamic attribute");
584 "non-dynamic attribute defined in dynamic dialect");
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)
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.
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.
bool hasTrait()
Returns true if the type was registered with a particular trait.
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...
void addType(TypeID typeID, AbstractType &&typeInfo)
Register a type instance with this dialect.
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.
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.
MLIRContext is the top-level object for a collection of MLIR operations.
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.
This class implements Optional functionality for ParseResult.
This class represents success/failure for parsing-like operations that find it important to chain tog...
static void insert(Dialect &dialect)
Register a new operation in a Dialect object.
Defines a TypeID for each instance of this class by using a pointer to the instance.
TypeID getTypeID() const
Return the TypeID owned by this object.
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.
Base storage class appearing in a Type.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
bool hasTrait()
Returns true if the type was registered with a particular trait.
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 MPInt &x)
Redeclarations of friend declaration above to make it discoverable by lookups.
This header declares functions that assist transformations in the MemRef dialect.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
This class represents an efficient way to signal success or failure.
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