llvm-project/mlir/lib/TableGen/Property.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

111 lines
4.4 KiB
C++
Raw Normal View History

Introduce MLIR Op Properties This new features enabled to dedicate custom storage inline within operations. This storage can be used as an alternative to attributes to store data that is specific to an operation. Attribute can also be stored inside the properties storage if desired, but any kind of data can be present as well. This offers a way to store and mutate data without uniquing in the Context like Attribute. See the OpPropertiesTest.cpp for an example where a struct with a std::vector<> is attached to an operation and mutated in-place: struct TestProperties { int a = -1; float b = -1.; std::vector<int64_t> array = {-33}; }; More complex scheme (including reference-counting) are also possible. The only constraint to enable storing a C++ object as "properties" on an operation is to implement three functions: - convert from the candidate object to an Attribute - convert from the Attribute to the candidate object - hash the object Optional the parsing and printing can also be customized with 2 extra functions. A new options is introduced to ODS to allow dialects to specify: let usePropertiesForAttributes = 1; When set to true, the inherent attributes for all the ops in this dialect will be using properties instead of being stored alongside discardable attributes. The TestDialect showcases this feature. Another change is that we introduce new APIs on the Operation class to access separately the inherent attributes from the discardable ones. We envision deprecating and removing the `getAttr()`, `getAttrsDictionary()`, and other similar method which don't make the distinction explicit, leading to an entirely separate namespace for discardable attributes. Recommit d572cd1b067f after fixing python bindings build. Differential Revision: https://reviews.llvm.org/D141742
2023-02-26 10:46:01 -05:00
//===- Property.cpp - Property wrapper class ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Property wrapper to simplify using TableGen Record defining a MLIR
// Property.
//
//===----------------------------------------------------------------------===//
#include "mlir/TableGen/Property.h"
#include "mlir/TableGen/Format.h"
#include "mlir/TableGen/Operator.h"
#include "mlir/TableGen/Predicate.h"
Introduce MLIR Op Properties This new features enabled to dedicate custom storage inline within operations. This storage can be used as an alternative to attributes to store data that is specific to an operation. Attribute can also be stored inside the properties storage if desired, but any kind of data can be present as well. This offers a way to store and mutate data without uniquing in the Context like Attribute. See the OpPropertiesTest.cpp for an example where a struct with a std::vector<> is attached to an operation and mutated in-place: struct TestProperties { int a = -1; float b = -1.; std::vector<int64_t> array = {-33}; }; More complex scheme (including reference-counting) are also possible. The only constraint to enable storing a C++ object as "properties" on an operation is to implement three functions: - convert from the candidate object to an Attribute - convert from the Attribute to the candidate object - hash the object Optional the parsing and printing can also be customized with 2 extra functions. A new options is introduced to ODS to allow dialects to specify: let usePropertiesForAttributes = 1; When set to true, the inherent attributes for all the ops in this dialect will be using properties instead of being stored alongside discardable attributes. The TestDialect showcases this feature. Another change is that we introduce new APIs on the Operation class to access separately the inherent attributes from the discardable ones. We envision deprecating and removing the `getAttr()`, `getAttrsDictionary()`, and other similar method which don't make the distinction explicit, leading to an entirely separate namespace for discardable attributes. Recommit d572cd1b067f after fixing python bindings build. Differential Revision: https://reviews.llvm.org/D141742
2023-02-26 10:46:01 -05:00
#include "llvm/TableGen/Record.h"
using namespace mlir;
using namespace mlir::tblgen;
using llvm::DefInit;
using llvm::Init;
using llvm::Record;
using llvm::StringInit;
// Returns the initializer's value as string if the given TableGen initializer
// is a code or string initializer. Returns the empty StringRef otherwise.
static StringRef getValueAsString(const Init *init) {
if (const auto *str = dyn_cast<StringInit>(init))
return str->getValue().trim();
return {};
}
Property::Property(const Record *def)
[mlir] Add property combinators, initial ODS support (#94732) While we have had a Properties.td that allowed for defining non-attribute-backed properties, such properties were not plumbed through the basic autogeneration facilities available to attributes, forcing those who want to migrate to the new system to write such code by hand. ## Potentially breaking changes - The `setFoo()` methods on `Properties` struct no longer take their inputs by const reference. Those wishing to pass non-owned values of a property by reference to constructors and setters should set the interface type to `const [storageType]&` - Adapters and operations now define getters and setters for properties listed in ODS, which may conflict with custom getters. - Builders now include properties listed in ODS specifications, potentially conflicting with custom builders with the same type signature. ## Extensions to the `Property` class This commit adds several fields to the `Property` class, including: - `parser`, `optionalParser`, and `printer` (for parsing/printing properties of a given type in ODS syntax) - `storageTypeValueOverride`, an extension of `defaultValue` to allow the storage and interface type defaults to differ - `baseProperty` (allowing for classes like `DefaultValuedProperty`) Existing fields have also had their documentation comments updated. This commit does not add a `PropertyConstraint` analogous to `AttrConstraint`, but this is a natural evolution of the work here. This commit also adds the concrete property kinds `I32Property`, `I64Property`, `UnitProperty` (and special handling for it like for UnitAttr), and `BoolProperty`. ## Property combinators `Properties.td` also now includes several ways to combine properties. One is `ArrayProperty<Property elem>`, which now stores a variable-length array of some property as `SmallVector<elem.storageType>` and uses `ArrayRef<elem.storageType>` as its interface type. It has `IntArrayProperty` subclasses that change its conversion to attributes to use `DenseI[N]Attr`s instead of an `ArrayAttr`. Similarly, `OptionalProperty<Property p>` wraps a property's storage in `std::optional<>` and adds a `std::nullopt` default value. In the case where the underlying property can be parsed optionally but doesn't have its own default value, `OptionalProperty` can piggyback off the optional parser to produce a cleaner syntax, as opposed to its general form, which is either `none` or `some<[value]>`. (Note that `OptionalProperty` can be nested if desired). ## Autogeneration changes Operations and adaptors now support getters and setters for properties like those for attributes. Unlike for attributes, there aren't separate value and attribute forms, since there is no `FooAttr()` available for a `getFooAttr()` to return. The largest change is to operation formats. Previously, properties could only be used in custom directives. Now, they can be used anywhere an attribute could be used, and have parsers and printers defined in their tablegen records. These updates include special `UnitProperty` logic like that used for `UnitAttr`. ## Misc. Some attempt has been made to test the new functionality. This commit takes tentative steps towards updating the documentation to account for properties. A full update will be in order once any followup work has been completed and the interfaces have stabilized. --------- Co-authored-by: Mehdi Amini <joker.eph@gmail.com> Co-authored-by: Christian Ulmann <christianulmann@gmail.com>
2024-07-26 09:35:06 -05:00
: Property(
getValueAsString(def->getValueInit("summary")),
getValueAsString(def->getValueInit("description")),
getValueAsString(def->getValueInit("storageType")),
getValueAsString(def->getValueInit("interfaceType")),
getValueAsString(def->getValueInit("convertFromStorage")),
getValueAsString(def->getValueInit("assignToStorage")),
getValueAsString(def->getValueInit("convertToAttribute")),
getValueAsString(def->getValueInit("convertFromAttribute")),
getValueAsString(def->getValueInit("parser")),
getValueAsString(def->getValueInit("optionalParser")),
getValueAsString(def->getValueInit("printer")),
getValueAsString(def->getValueInit("readFromMlirBytecode")),
getValueAsString(def->getValueInit("writeToMlirBytecode")),
getValueAsString(def->getValueInit("hashProperty")),
getValueAsString(def->getValueInit("defaultValue")),
getValueAsString(def->getValueInit("storageTypeValueOverride"))) {
this->def = def;
assert((def->isSubClassOf("Property") || def->isSubClassOf("Attr")) &&
Introduce MLIR Op Properties This new features enabled to dedicate custom storage inline within operations. This storage can be used as an alternative to attributes to store data that is specific to an operation. Attribute can also be stored inside the properties storage if desired, but any kind of data can be present as well. This offers a way to store and mutate data without uniquing in the Context like Attribute. See the OpPropertiesTest.cpp for an example where a struct with a std::vector<> is attached to an operation and mutated in-place: struct TestProperties { int a = -1; float b = -1.; std::vector<int64_t> array = {-33}; }; More complex scheme (including reference-counting) are also possible. The only constraint to enable storing a C++ object as "properties" on an operation is to implement three functions: - convert from the candidate object to an Attribute - convert from the Attribute to the candidate object - hash the object Optional the parsing and printing can also be customized with 2 extra functions. A new options is introduced to ODS to allow dialects to specify: let usePropertiesForAttributes = 1; When set to true, the inherent attributes for all the ops in this dialect will be using properties instead of being stored alongside discardable attributes. The TestDialect showcases this feature. Another change is that we introduce new APIs on the Operation class to access separately the inherent attributes from the discardable ones. We envision deprecating and removing the `getAttr()`, `getAttrsDictionary()`, and other similar method which don't make the distinction explicit, leading to an entirely separate namespace for discardable attributes. Recommit d572cd1b067f after fixing python bindings build. Differential Revision: https://reviews.llvm.org/D141742
2023-02-26 10:46:01 -05:00
"must be subclass of TableGen 'Property' class");
}
Property::Property(const DefInit *init) : Property(init->getDef()) {}
[mlir] Add property combinators, initial ODS support (#94732) While we have had a Properties.td that allowed for defining non-attribute-backed properties, such properties were not plumbed through the basic autogeneration facilities available to attributes, forcing those who want to migrate to the new system to write such code by hand. ## Potentially breaking changes - The `setFoo()` methods on `Properties` struct no longer take their inputs by const reference. Those wishing to pass non-owned values of a property by reference to constructors and setters should set the interface type to `const [storageType]&` - Adapters and operations now define getters and setters for properties listed in ODS, which may conflict with custom getters. - Builders now include properties listed in ODS specifications, potentially conflicting with custom builders with the same type signature. ## Extensions to the `Property` class This commit adds several fields to the `Property` class, including: - `parser`, `optionalParser`, and `printer` (for parsing/printing properties of a given type in ODS syntax) - `storageTypeValueOverride`, an extension of `defaultValue` to allow the storage and interface type defaults to differ - `baseProperty` (allowing for classes like `DefaultValuedProperty`) Existing fields have also had their documentation comments updated. This commit does not add a `PropertyConstraint` analogous to `AttrConstraint`, but this is a natural evolution of the work here. This commit also adds the concrete property kinds `I32Property`, `I64Property`, `UnitProperty` (and special handling for it like for UnitAttr), and `BoolProperty`. ## Property combinators `Properties.td` also now includes several ways to combine properties. One is `ArrayProperty<Property elem>`, which now stores a variable-length array of some property as `SmallVector<elem.storageType>` and uses `ArrayRef<elem.storageType>` as its interface type. It has `IntArrayProperty` subclasses that change its conversion to attributes to use `DenseI[N]Attr`s instead of an `ArrayAttr`. Similarly, `OptionalProperty<Property p>` wraps a property's storage in `std::optional<>` and adds a `std::nullopt` default value. In the case where the underlying property can be parsed optionally but doesn't have its own default value, `OptionalProperty` can piggyback off the optional parser to produce a cleaner syntax, as opposed to its general form, which is either `none` or `some<[value]>`. (Note that `OptionalProperty` can be nested if desired). ## Autogeneration changes Operations and adaptors now support getters and setters for properties like those for attributes. Unlike for attributes, there aren't separate value and attribute forms, since there is no `FooAttr()` available for a `getFooAttr()` to return. The largest change is to operation formats. Previously, properties could only be used in custom directives. Now, they can be used anywhere an attribute could be used, and have parsers and printers defined in their tablegen records. These updates include special `UnitProperty` logic like that used for `UnitAttr`. ## Misc. Some attempt has been made to test the new functionality. This commit takes tentative steps towards updating the documentation to account for properties. A full update will be in order once any followup work has been completed and the interfaces have stabilized. --------- Co-authored-by: Mehdi Amini <joker.eph@gmail.com> Co-authored-by: Christian Ulmann <christianulmann@gmail.com>
2024-07-26 09:35:06 -05:00
Property::Property(StringRef summary, StringRef description,
StringRef storageType, StringRef interfaceType,
StringRef convertFromStorageCall,
StringRef assignToStorageCall,
StringRef convertToAttributeCall,
[mlir] Add property combinators, initial ODS support (#94732) While we have had a Properties.td that allowed for defining non-attribute-backed properties, such properties were not plumbed through the basic autogeneration facilities available to attributes, forcing those who want to migrate to the new system to write such code by hand. ## Potentially breaking changes - The `setFoo()` methods on `Properties` struct no longer take their inputs by const reference. Those wishing to pass non-owned values of a property by reference to constructors and setters should set the interface type to `const [storageType]&` - Adapters and operations now define getters and setters for properties listed in ODS, which may conflict with custom getters. - Builders now include properties listed in ODS specifications, potentially conflicting with custom builders with the same type signature. ## Extensions to the `Property` class This commit adds several fields to the `Property` class, including: - `parser`, `optionalParser`, and `printer` (for parsing/printing properties of a given type in ODS syntax) - `storageTypeValueOverride`, an extension of `defaultValue` to allow the storage and interface type defaults to differ - `baseProperty` (allowing for classes like `DefaultValuedProperty`) Existing fields have also had their documentation comments updated. This commit does not add a `PropertyConstraint` analogous to `AttrConstraint`, but this is a natural evolution of the work here. This commit also adds the concrete property kinds `I32Property`, `I64Property`, `UnitProperty` (and special handling for it like for UnitAttr), and `BoolProperty`. ## Property combinators `Properties.td` also now includes several ways to combine properties. One is `ArrayProperty<Property elem>`, which now stores a variable-length array of some property as `SmallVector<elem.storageType>` and uses `ArrayRef<elem.storageType>` as its interface type. It has `IntArrayProperty` subclasses that change its conversion to attributes to use `DenseI[N]Attr`s instead of an `ArrayAttr`. Similarly, `OptionalProperty<Property p>` wraps a property's storage in `std::optional<>` and adds a `std::nullopt` default value. In the case where the underlying property can be parsed optionally but doesn't have its own default value, `OptionalProperty` can piggyback off the optional parser to produce a cleaner syntax, as opposed to its general form, which is either `none` or `some<[value]>`. (Note that `OptionalProperty` can be nested if desired). ## Autogeneration changes Operations and adaptors now support getters and setters for properties like those for attributes. Unlike for attributes, there aren't separate value and attribute forms, since there is no `FooAttr()` available for a `getFooAttr()` to return. The largest change is to operation formats. Previously, properties could only be used in custom directives. Now, they can be used anywhere an attribute could be used, and have parsers and printers defined in their tablegen records. These updates include special `UnitProperty` logic like that used for `UnitAttr`. ## Misc. Some attempt has been made to test the new functionality. This commit takes tentative steps towards updating the documentation to account for properties. A full update will be in order once any followup work has been completed and the interfaces have stabilized. --------- Co-authored-by: Mehdi Amini <joker.eph@gmail.com> Co-authored-by: Christian Ulmann <christianulmann@gmail.com>
2024-07-26 09:35:06 -05:00
StringRef convertFromAttributeCall, StringRef parserCall,
StringRef optionalParserCall, StringRef printerCall,
StringRef readFromMlirBytecodeCall,
StringRef writeToMlirBytecodeCall,
[mlir] Add property combinators, initial ODS support (#94732) While we have had a Properties.td that allowed for defining non-attribute-backed properties, such properties were not plumbed through the basic autogeneration facilities available to attributes, forcing those who want to migrate to the new system to write such code by hand. ## Potentially breaking changes - The `setFoo()` methods on `Properties` struct no longer take their inputs by const reference. Those wishing to pass non-owned values of a property by reference to constructors and setters should set the interface type to `const [storageType]&` - Adapters and operations now define getters and setters for properties listed in ODS, which may conflict with custom getters. - Builders now include properties listed in ODS specifications, potentially conflicting with custom builders with the same type signature. ## Extensions to the `Property` class This commit adds several fields to the `Property` class, including: - `parser`, `optionalParser`, and `printer` (for parsing/printing properties of a given type in ODS syntax) - `storageTypeValueOverride`, an extension of `defaultValue` to allow the storage and interface type defaults to differ - `baseProperty` (allowing for classes like `DefaultValuedProperty`) Existing fields have also had their documentation comments updated. This commit does not add a `PropertyConstraint` analogous to `AttrConstraint`, but this is a natural evolution of the work here. This commit also adds the concrete property kinds `I32Property`, `I64Property`, `UnitProperty` (and special handling for it like for UnitAttr), and `BoolProperty`. ## Property combinators `Properties.td` also now includes several ways to combine properties. One is `ArrayProperty<Property elem>`, which now stores a variable-length array of some property as `SmallVector<elem.storageType>` and uses `ArrayRef<elem.storageType>` as its interface type. It has `IntArrayProperty` subclasses that change its conversion to attributes to use `DenseI[N]Attr`s instead of an `ArrayAttr`. Similarly, `OptionalProperty<Property p>` wraps a property's storage in `std::optional<>` and adds a `std::nullopt` default value. In the case where the underlying property can be parsed optionally but doesn't have its own default value, `OptionalProperty` can piggyback off the optional parser to produce a cleaner syntax, as opposed to its general form, which is either `none` or `some<[value]>`. (Note that `OptionalProperty` can be nested if desired). ## Autogeneration changes Operations and adaptors now support getters and setters for properties like those for attributes. Unlike for attributes, there aren't separate value and attribute forms, since there is no `FooAttr()` available for a `getFooAttr()` to return. The largest change is to operation formats. Previously, properties could only be used in custom directives. Now, they can be used anywhere an attribute could be used, and have parsers and printers defined in their tablegen records. These updates include special `UnitProperty` logic like that used for `UnitAttr`. ## Misc. Some attempt has been made to test the new functionality. This commit takes tentative steps towards updating the documentation to account for properties. A full update will be in order once any followup work has been completed and the interfaces have stabilized. --------- Co-authored-by: Mehdi Amini <joker.eph@gmail.com> Co-authored-by: Christian Ulmann <christianulmann@gmail.com>
2024-07-26 09:35:06 -05:00
StringRef hashPropertyCall, StringRef defaultValue,
StringRef storageTypeValueOverride)
: def(nullptr), summary(summary), description(description),
storageType(storageType), interfaceType(interfaceType),
convertFromStorageCall(convertFromStorageCall),
assignToStorageCall(assignToStorageCall),
convertToAttributeCall(convertToAttributeCall),
convertFromAttributeCall(convertFromAttributeCall),
[mlir] Add property combinators, initial ODS support (#94732) While we have had a Properties.td that allowed for defining non-attribute-backed properties, such properties were not plumbed through the basic autogeneration facilities available to attributes, forcing those who want to migrate to the new system to write such code by hand. ## Potentially breaking changes - The `setFoo()` methods on `Properties` struct no longer take their inputs by const reference. Those wishing to pass non-owned values of a property by reference to constructors and setters should set the interface type to `const [storageType]&` - Adapters and operations now define getters and setters for properties listed in ODS, which may conflict with custom getters. - Builders now include properties listed in ODS specifications, potentially conflicting with custom builders with the same type signature. ## Extensions to the `Property` class This commit adds several fields to the `Property` class, including: - `parser`, `optionalParser`, and `printer` (for parsing/printing properties of a given type in ODS syntax) - `storageTypeValueOverride`, an extension of `defaultValue` to allow the storage and interface type defaults to differ - `baseProperty` (allowing for classes like `DefaultValuedProperty`) Existing fields have also had their documentation comments updated. This commit does not add a `PropertyConstraint` analogous to `AttrConstraint`, but this is a natural evolution of the work here. This commit also adds the concrete property kinds `I32Property`, `I64Property`, `UnitProperty` (and special handling for it like for UnitAttr), and `BoolProperty`. ## Property combinators `Properties.td` also now includes several ways to combine properties. One is `ArrayProperty<Property elem>`, which now stores a variable-length array of some property as `SmallVector<elem.storageType>` and uses `ArrayRef<elem.storageType>` as its interface type. It has `IntArrayProperty` subclasses that change its conversion to attributes to use `DenseI[N]Attr`s instead of an `ArrayAttr`. Similarly, `OptionalProperty<Property p>` wraps a property's storage in `std::optional<>` and adds a `std::nullopt` default value. In the case where the underlying property can be parsed optionally but doesn't have its own default value, `OptionalProperty` can piggyback off the optional parser to produce a cleaner syntax, as opposed to its general form, which is either `none` or `some<[value]>`. (Note that `OptionalProperty` can be nested if desired). ## Autogeneration changes Operations and adaptors now support getters and setters for properties like those for attributes. Unlike for attributes, there aren't separate value and attribute forms, since there is no `FooAttr()` available for a `getFooAttr()` to return. The largest change is to operation formats. Previously, properties could only be used in custom directives. Now, they can be used anywhere an attribute could be used, and have parsers and printers defined in their tablegen records. These updates include special `UnitProperty` logic like that used for `UnitAttr`. ## Misc. Some attempt has been made to test the new functionality. This commit takes tentative steps towards updating the documentation to account for properties. A full update will be in order once any followup work has been completed and the interfaces have stabilized. --------- Co-authored-by: Mehdi Amini <joker.eph@gmail.com> Co-authored-by: Christian Ulmann <christianulmann@gmail.com>
2024-07-26 09:35:06 -05:00
parserCall(parserCall), optionalParserCall(optionalParserCall),
printerCall(printerCall),
readFromMlirBytecodeCall(readFromMlirBytecodeCall),
writeToMlirBytecodeCall(writeToMlirBytecodeCall),
[mlir] Add property combinators, initial ODS support (#94732) While we have had a Properties.td that allowed for defining non-attribute-backed properties, such properties were not plumbed through the basic autogeneration facilities available to attributes, forcing those who want to migrate to the new system to write such code by hand. ## Potentially breaking changes - The `setFoo()` methods on `Properties` struct no longer take their inputs by const reference. Those wishing to pass non-owned values of a property by reference to constructors and setters should set the interface type to `const [storageType]&` - Adapters and operations now define getters and setters for properties listed in ODS, which may conflict with custom getters. - Builders now include properties listed in ODS specifications, potentially conflicting with custom builders with the same type signature. ## Extensions to the `Property` class This commit adds several fields to the `Property` class, including: - `parser`, `optionalParser`, and `printer` (for parsing/printing properties of a given type in ODS syntax) - `storageTypeValueOverride`, an extension of `defaultValue` to allow the storage and interface type defaults to differ - `baseProperty` (allowing for classes like `DefaultValuedProperty`) Existing fields have also had their documentation comments updated. This commit does not add a `PropertyConstraint` analogous to `AttrConstraint`, but this is a natural evolution of the work here. This commit also adds the concrete property kinds `I32Property`, `I64Property`, `UnitProperty` (and special handling for it like for UnitAttr), and `BoolProperty`. ## Property combinators `Properties.td` also now includes several ways to combine properties. One is `ArrayProperty<Property elem>`, which now stores a variable-length array of some property as `SmallVector<elem.storageType>` and uses `ArrayRef<elem.storageType>` as its interface type. It has `IntArrayProperty` subclasses that change its conversion to attributes to use `DenseI[N]Attr`s instead of an `ArrayAttr`. Similarly, `OptionalProperty<Property p>` wraps a property's storage in `std::optional<>` and adds a `std::nullopt` default value. In the case where the underlying property can be parsed optionally but doesn't have its own default value, `OptionalProperty` can piggyback off the optional parser to produce a cleaner syntax, as opposed to its general form, which is either `none` or `some<[value]>`. (Note that `OptionalProperty` can be nested if desired). ## Autogeneration changes Operations and adaptors now support getters and setters for properties like those for attributes. Unlike for attributes, there aren't separate value and attribute forms, since there is no `FooAttr()` available for a `getFooAttr()` to return. The largest change is to operation formats. Previously, properties could only be used in custom directives. Now, they can be used anywhere an attribute could be used, and have parsers and printers defined in their tablegen records. These updates include special `UnitProperty` logic like that used for `UnitAttr`. ## Misc. Some attempt has been made to test the new functionality. This commit takes tentative steps towards updating the documentation to account for properties. A full update will be in order once any followup work has been completed and the interfaces have stabilized. --------- Co-authored-by: Mehdi Amini <joker.eph@gmail.com> Co-authored-by: Christian Ulmann <christianulmann@gmail.com>
2024-07-26 09:35:06 -05:00
hashPropertyCall(hashPropertyCall), defaultValue(defaultValue),
storageTypeValueOverride(storageTypeValueOverride) {
if (storageType.empty())
storageType = "Property";
Introduce MLIR Op Properties This new features enabled to dedicate custom storage inline within operations. This storage can be used as an alternative to attributes to store data that is specific to an operation. Attribute can also be stored inside the properties storage if desired, but any kind of data can be present as well. This offers a way to store and mutate data without uniquing in the Context like Attribute. See the OpPropertiesTest.cpp for an example where a struct with a std::vector<> is attached to an operation and mutated in-place: struct TestProperties { int a = -1; float b = -1.; std::vector<int64_t> array = {-33}; }; More complex scheme (including reference-counting) are also possible. The only constraint to enable storing a C++ object as "properties" on an operation is to implement three functions: - convert from the candidate object to an Attribute - convert from the Attribute to the candidate object - hash the object Optional the parsing and printing can also be customized with 2 extra functions. A new options is introduced to ODS to allow dialects to specify: let usePropertiesForAttributes = 1; When set to true, the inherent attributes for all the ops in this dialect will be using properties instead of being stored alongside discardable attributes. The TestDialect showcases this feature. Another change is that we introduce new APIs on the Operation class to access separately the inherent attributes from the discardable ones. We envision deprecating and removing the `getAttr()`, `getAttrsDictionary()`, and other similar method which don't make the distinction explicit, leading to an entirely separate namespace for discardable attributes. Recommit d572cd1b067f after fixing python bindings build. Differential Revision: https://reviews.llvm.org/D141742
2023-02-26 10:46:01 -05:00
}
[mlir] Add property combinators, initial ODS support (#94732) While we have had a Properties.td that allowed for defining non-attribute-backed properties, such properties were not plumbed through the basic autogeneration facilities available to attributes, forcing those who want to migrate to the new system to write such code by hand. ## Potentially breaking changes - The `setFoo()` methods on `Properties` struct no longer take their inputs by const reference. Those wishing to pass non-owned values of a property by reference to constructors and setters should set the interface type to `const [storageType]&` - Adapters and operations now define getters and setters for properties listed in ODS, which may conflict with custom getters. - Builders now include properties listed in ODS specifications, potentially conflicting with custom builders with the same type signature. ## Extensions to the `Property` class This commit adds several fields to the `Property` class, including: - `parser`, `optionalParser`, and `printer` (for parsing/printing properties of a given type in ODS syntax) - `storageTypeValueOverride`, an extension of `defaultValue` to allow the storage and interface type defaults to differ - `baseProperty` (allowing for classes like `DefaultValuedProperty`) Existing fields have also had their documentation comments updated. This commit does not add a `PropertyConstraint` analogous to `AttrConstraint`, but this is a natural evolution of the work here. This commit also adds the concrete property kinds `I32Property`, `I64Property`, `UnitProperty` (and special handling for it like for UnitAttr), and `BoolProperty`. ## Property combinators `Properties.td` also now includes several ways to combine properties. One is `ArrayProperty<Property elem>`, which now stores a variable-length array of some property as `SmallVector<elem.storageType>` and uses `ArrayRef<elem.storageType>` as its interface type. It has `IntArrayProperty` subclasses that change its conversion to attributes to use `DenseI[N]Attr`s instead of an `ArrayAttr`. Similarly, `OptionalProperty<Property p>` wraps a property's storage in `std::optional<>` and adds a `std::nullopt` default value. In the case where the underlying property can be parsed optionally but doesn't have its own default value, `OptionalProperty` can piggyback off the optional parser to produce a cleaner syntax, as opposed to its general form, which is either `none` or `some<[value]>`. (Note that `OptionalProperty` can be nested if desired). ## Autogeneration changes Operations and adaptors now support getters and setters for properties like those for attributes. Unlike for attributes, there aren't separate value and attribute forms, since there is no `FooAttr()` available for a `getFooAttr()` to return. The largest change is to operation formats. Previously, properties could only be used in custom directives. Now, they can be used anywhere an attribute could be used, and have parsers and printers defined in their tablegen records. These updates include special `UnitProperty` logic like that used for `UnitAttr`. ## Misc. Some attempt has been made to test the new functionality. This commit takes tentative steps towards updating the documentation to account for properties. A full update will be in order once any followup work has been completed and the interfaces have stabilized. --------- Co-authored-by: Mehdi Amini <joker.eph@gmail.com> Co-authored-by: Christian Ulmann <christianulmann@gmail.com>
2024-07-26 09:35:06 -05:00
StringRef Property::getPropertyDefName() const {
if (def->isAnonymous()) {
return getBaseProperty().def->getName();
}
return def->getName();
}
Pred Property::getPredicate() const {
if (!def)
return Pred();
const llvm::RecordVal *maybePred = def->getValue("predicate");
if (!maybePred || !maybePred->getValue())
return Pred();
return Pred(maybePred->getValue());
}
[mlir] Add property combinators, initial ODS support (#94732) While we have had a Properties.td that allowed for defining non-attribute-backed properties, such properties were not plumbed through the basic autogeneration facilities available to attributes, forcing those who want to migrate to the new system to write such code by hand. ## Potentially breaking changes - The `setFoo()` methods on `Properties` struct no longer take their inputs by const reference. Those wishing to pass non-owned values of a property by reference to constructors and setters should set the interface type to `const [storageType]&` - Adapters and operations now define getters and setters for properties listed in ODS, which may conflict with custom getters. - Builders now include properties listed in ODS specifications, potentially conflicting with custom builders with the same type signature. ## Extensions to the `Property` class This commit adds several fields to the `Property` class, including: - `parser`, `optionalParser`, and `printer` (for parsing/printing properties of a given type in ODS syntax) - `storageTypeValueOverride`, an extension of `defaultValue` to allow the storage and interface type defaults to differ - `baseProperty` (allowing for classes like `DefaultValuedProperty`) Existing fields have also had their documentation comments updated. This commit does not add a `PropertyConstraint` analogous to `AttrConstraint`, but this is a natural evolution of the work here. This commit also adds the concrete property kinds `I32Property`, `I64Property`, `UnitProperty` (and special handling for it like for UnitAttr), and `BoolProperty`. ## Property combinators `Properties.td` also now includes several ways to combine properties. One is `ArrayProperty<Property elem>`, which now stores a variable-length array of some property as `SmallVector<elem.storageType>` and uses `ArrayRef<elem.storageType>` as its interface type. It has `IntArrayProperty` subclasses that change its conversion to attributes to use `DenseI[N]Attr`s instead of an `ArrayAttr`. Similarly, `OptionalProperty<Property p>` wraps a property's storage in `std::optional<>` and adds a `std::nullopt` default value. In the case where the underlying property can be parsed optionally but doesn't have its own default value, `OptionalProperty` can piggyback off the optional parser to produce a cleaner syntax, as opposed to its general form, which is either `none` or `some<[value]>`. (Note that `OptionalProperty` can be nested if desired). ## Autogeneration changes Operations and adaptors now support getters and setters for properties like those for attributes. Unlike for attributes, there aren't separate value and attribute forms, since there is no `FooAttr()` available for a `getFooAttr()` to return. The largest change is to operation formats. Previously, properties could only be used in custom directives. Now, they can be used anywhere an attribute could be used, and have parsers and printers defined in their tablegen records. These updates include special `UnitProperty` logic like that used for `UnitAttr`. ## Misc. Some attempt has been made to test the new functionality. This commit takes tentative steps towards updating the documentation to account for properties. A full update will be in order once any followup work has been completed and the interfaces have stabilized. --------- Co-authored-by: Mehdi Amini <joker.eph@gmail.com> Co-authored-by: Christian Ulmann <christianulmann@gmail.com>
2024-07-26 09:35:06 -05:00
Property Property::getBaseProperty() const {
if (const auto *defInit =
llvm::dyn_cast<llvm::DefInit>(def->getValueInit("baseProperty"))) {
return Property(defInit).getBaseProperty();
}
return *this;
}