diff --git a/mlir/include/mlir/IR/DialectBase.td b/mlir/include/mlir/IR/DialectBase.td --- a/mlir/include/mlir/IR/DialectBase.td +++ b/mlir/include/mlir/IR/DialectBase.td @@ -103,6 +103,9 @@ // If this dialect can be extended at runtime with new operations or types. bit isExtensible = 0; + + // Whether inherent Attributes defined in ODS will be stored as Properties. + bit usePropertiesForAttributes = 0; } #endif // DIALECTBASE_TD diff --git a/mlir/include/mlir/IR/ExtensibleDialect.h b/mlir/include/mlir/IR/ExtensibleDialect.h --- a/mlir/include/mlir/IR/ExtensibleDialect.h +++ b/mlir/include/mlir/IR/ExtensibleDialect.h @@ -26,6 +26,8 @@ #include "mlir/IR/OpDefinition.h" #include "mlir/Support/TypeID.h" #include "llvm/ADT/StringMap.h" +#include "llvm/Support/ErrorHandling.h" +#include namespace mlir { class AsmParser; @@ -462,6 +464,29 @@ return verifyRegionFn(op); } + // Implementation for properties (unsupported right now here). + std::optional getInherentAttr(Operation *op, + StringRef name) final { + llvm::report_fatal_error("Unsupported getInherentAttr on Dynamic dialects"); + } + void setInherentAttr(Operation *op, StringAttr name, Attribute value) final { + llvm::report_fatal_error("Unsupported setInherentAttr on Dynamic dialects"); + } + void populateInherentAttrs(Operation *op, NamedAttrList &attrs) final {} + int getOpPropertyByteSize() final { return 0; } + void initProperties(OperationName opName, void *storage, void *init) final {} + void deleteProperties(void *prop) final {} + void populateDefaultProperties(OperationName opName, void *properties) final { + } + + LogicalResult setPropertiesFromAttr(Operation *op, Attribute attr, + InFlightDiagnostic *diag) final { + return failure(); + } + Attribute getPropertiesAsAttr(Operation *op) final { return {}; } + void copyProperties(void *lhs, void *rhs) final {} + llvm::hash_code hashProperties(void *prop) final { return {}; } + private: DynamicOpDefinition( StringRef name, ExtensibleDialect *dialect, diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td --- a/mlir/include/mlir/IR/OpBase.td +++ b/mlir/include/mlir/IR/OpBase.td @@ -179,6 +179,69 @@ string cppClassName = cppClassNameParam; } +// Base class for defining properties. +class Property { + // User-readable one line summary used in error reporting messages. If empty, + // a generic message will be used. + string summary = desc; + // The full description of this property. + string description = ""; + code storageType = storageTypeParam; + code interfaceType = storageTypeParam; + + // The expression to convert from the storage type to the Interface + // type. For example, an enum can be stored as an int but returned as an + // enum class. + // + // Format: + // - `$_storage` will contain the property in the storage type. + // - `$_ctx` will contain an `MLIRContext *`. + code convertFromStorage = "$_storage"; + + // The call expression to build a property storage from the interface type. + // + // Format: + // - `$_storage` will contain the property in the storage type. + // - `$_value` will contain the property in the user interface type. + code assignToStorage = "$_storage = $_value"; + + // The call expression to convert from the storage type to an attribute. + // + // Format: + // - `$_storage` is the storage type value. + // - `$_ctx` is a `MLIRContext *`. + // + // The expression must result in an Attribute. + code convertToAttribute = [{ + convertToAttribute($_ctx, $_storage) + }]; + + // The call expression to convert from an Attribute to the storage type. + // + // Format: + // - `$_storage` is the storage type value. + // - `$_attr` is the attribute. + // - `$_diag` is an optional Diagnostic pointer to emit error. + // + // The expression must return a LogicalResult + code convertFromAttribute = [{ + return convertFromAttribute($_storage, $_attr, $_diag); + }]; + + // The call expression to hash the property. + // + // Format: + // - `$_storage` is the variable to hash. + // + // The expression should define a llvm::hash_code. + code hashProperty = [{ + llvm::hash_value($_storage); + }]; + + // Default value for the property. + string defaultValue = ?; +} + // Subclass for constraints on an attribute. class AttrConstraint : Constraint; @@ -1090,6 +1153,16 @@ class DefaultValuedOptionalStrAttr : DefaultValuedOptionalAttr; +//===----------------------------------------------------------------------===// +// Primitive property kinds + +class ArrayProperty : + Property { + let interfaceType = "::llvm::ArrayRef<" # storageTypeParam # ">"; + let convertFromStorage = "$_storage"; + let assignToStorage = "::llvm::copy($_value, $_storage)"; +} + //===----------------------------------------------------------------------===// // Primitive attribute kinds diff --git a/mlir/include/mlir/IR/OpDefinition.h b/mlir/include/mlir/IR/OpDefinition.h --- a/mlir/include/mlir/IR/OpDefinition.h +++ b/mlir/include/mlir/IR/OpDefinition.h @@ -206,6 +206,13 @@ /// in generic form. static void print(Operation *op, OpAsmPrinter &p, StringRef defaultDialect); + /// Parse properties as a Attribute. + static ParseResult genericParseProperties(OpAsmParser &parser, + Attribute &result); + + /// Print the properties as a Attribute. + static void genericPrintProperties(OpAsmPrinter &p, Attribute properties); + /// Print an operation name, eliding the dialect prefix if necessary. static void printOpName(Operation *op, OpAsmPrinter &p, StringRef defaultDialect); @@ -1463,13 +1470,17 @@ /// Returns true if this given Trait ID matches the IDs of any of the provided /// trait types `Traits`. template