1010#define MLIR_DIALECT_DLTI_DLTIATTRS_TD
1111
1212include "mlir/Dialect/DLTI/DLTI.td"
13+ include "mlir/Interfaces/DataLayoutInterfaces.td"
1314include "mlir/IR/AttrTypeBase.td"
1415
1516class DLTIAttr<string name, list<Trait> traits = [],
@@ -20,13 +21,8 @@ class DLTIAttr<string name, list<Trait> traits = [],
2021// DataLayoutEntryAttr
2122//===----------------------------------------------------------------------===//
2223
23- def DataLayoutEntryTrait
24- : NativeAttrTrait<"DataLayoutEntryInterface::Trait"> {
25- let cppNamespace = "::mlir";
26- }
27-
2824def DLTI_DataLayoutEntryAttr :
29- DLTIAttr<"DataLayoutEntry", [DataLayoutEntryTrait ]> {
25+ DLTIAttr<"DataLayoutEntry", [DataLayoutEntryInterface ]> {
3026 let summary = "An attribute to represent an entry of a data layout specification.";
3127 let description = [{
3228 A data layout entry attribute is a key-value pair where the key is a type or
@@ -53,13 +49,9 @@ def DLTI_DataLayoutEntryAttr :
5349//===----------------------------------------------------------------------===//
5450// DataLayoutSpecAttr
5551//===----------------------------------------------------------------------===//
56- def DataLayoutSpecTrait
57- : NativeAttrTrait<"DataLayoutSpecInterface::Trait"> {
58- let cppNamespace = "::mlir";
59- }
6052
6153def DLTI_DataLayoutSpecAttr :
62- DLTIAttr<"DataLayoutSpec", [DataLayoutSpecTrait ]> {
54+ DLTIAttr<"DataLayoutSpec", [DataLayoutSpecInterface ]> {
6355 let summary = "An attribute to represent a data layout specification.";
6456 let description = [{
6557 A data layout specification is a list of entries that specify (partial) data
@@ -78,7 +70,7 @@ def DLTI_DataLayoutSpecAttr :
7870 /// same key as the newer entries if the entries are compatible. Returns null
7971 /// if the specifications are not compatible.
8072 DataLayoutSpecAttr combineWith(ArrayRef<DataLayoutSpecInterface> specs) const;
81-
73+
8274 /// Returns the endiannes identifier.
8375 StringAttr getEndiannessIdentifier(MLIRContext *context) const;
8476
@@ -93,20 +85,78 @@ def DLTI_DataLayoutSpecAttr :
9385
9486 /// Returns the stack alignment identifier.
9587 StringAttr getStackAlignmentIdentifier(MLIRContext *context) const;
88+
89+ /// Returns the attribute associated with the key.
90+ FailureOr<Attribute> query(DataLayoutEntryKey key) {
91+ return llvm::cast<mlir::DataLayoutSpecInterface>(*this).queryHelper(key);
92+ }
93+ }];
94+ }
95+
96+ def DLTI_MapAttr : DLTIAttr<"Map", [DLTIQueryInterface]> {
97+ let summary = "A mapping of DLTI-information by way of key-value pairs";
98+ let description = [{
99+ A Data Layout and Target Information map is a list of entries effectively
100+ encoding a dictionary, mapping DLTI-related keys to DLTI-related values.
101+
102+ This attribute's main purpose is to facilate querying IR for arbitrary
103+ key-value associations that encode DLTI. Facility functions exist to perform
104+ recursive lookups on nested DLTI-map/query interface-implementing
105+ attributes.
106+
107+ Consider the following flat encoding of a single-key dictionary
108+ ```
109+ #dlti.map<#dlti.dl_entry<"CPU::cache::L1::size_in_bytes", 65536 : i32>>
110+ ```
111+ versus nested maps, which make it possible to obtain sub-dictionaries of
112+ related information (with the following example making use of other
113+ attributes that also implement the `DLTIQueryInterface`):
114+ ```
115+ #dlti.target_system_spec<"CPU":
116+ #dlti.target_device_spec<#dlti.dl_entry<"cache",
117+ #dlti.map<#dlti.dl_entry<"L1",
118+ #dlti.map<#dlti.dl_entry<"size_in_bytes", 65536 : i32>>>,
119+ #dlti.dl_entry<"L1d",
120+ #dlti.map<#dlti.dl_entry<"size_in_bytes", 32768 : i32>>> >>>>
121+ ```
122+
123+ With the flat encoding, the implied structure of the key is ignored, that is
124+ the only successful query (as expressed in the Transform Dialect) is:
125+ `transform.dlti.query ["CPU::cache::L1::size_in_bytes"] at %op`,
126+ where `%op` is a handle to an operation which associates the flat-encoding
127+ `#dlti.map` attribute.
128+
129+ For querying nested dictionaries, the relevant keys need to be separately
130+ provided. That is, if `%op` is an handle to an op which has the nesting
131+ `#dlti.target_system_spec`-attribute from above attached, then
132+ `transform.dlti.query ["CPU","cache","L1","size_in_bytes"] at %op` gives
133+ back the first leaf value contained. To access the other leaf, we need to do
134+ `transform.dlti.query ["CPU","cache","L1d","size_in_bytes"] at %op`.
135+ ```
136+ }];
137+ let parameters = (ins
138+ ArrayRefParameter<"DataLayoutEntryInterface", "">:$entries
139+ );
140+ let mnemonic = "map";
141+ let genVerifyDecl = 1;
142+ let assemblyFormat = "`<` $entries `>`";
143+ let extraClassDeclaration = [{
144+ /// Returns the attribute associated with the key.
145+ FailureOr<Attribute> query(DataLayoutEntryKey key) {
146+ for (DataLayoutEntryInterface entry : getEntries())
147+ if (entry.getKey() == key)
148+ return entry.getValue();
149+ return ::mlir::failure();
150+ }
96151 }];
97152}
98153
99154//===----------------------------------------------------------------------===//
100155// TargetSystemSpecAttr
101156//===----------------------------------------------------------------------===//
102157
103- def TargetSystemSpecTrait
104- : NativeAttrTrait<"TargetSystemSpecInterface::Trait"> {
105- let cppNamespace = "::mlir";
106- }
107-
108158def DLTI_TargetSystemSpecAttr :
109- DLTIAttr<"TargetSystemSpec", [TargetSystemSpecTrait ]> {
159+ DLTIAttr<"TargetSystemSpec", [TargetSystemSpecInterface ]> {
110160 let summary = "An attribute to represent target system specification.";
111161 let description = [{
112162 A system specification describes the overall system containing
@@ -136,6 +186,11 @@ def DLTI_TargetSystemSpecAttr :
136186 std::optional<TargetDeviceSpecInterface>
137187 getDeviceSpecForDeviceID(
138188 TargetSystemSpecInterface::DeviceID deviceID);
189+
190+ /// Returns the attribute associated with the key.
191+ FailureOr<Attribute> query(DataLayoutEntryKey key) const {
192+ return llvm::cast<mlir::TargetSystemSpecInterface>(*this).queryHelper(key);
193+ }
139194 }];
140195 let extraClassDefinition = [{
141196 std::optional<TargetDeviceSpecInterface>
@@ -154,13 +209,8 @@ def DLTI_TargetSystemSpecAttr :
154209// TargetDeviceSpecAttr
155210//===----------------------------------------------------------------------===//
156211
157- def TargetDeviceSpecTrait
158- : NativeAttrTrait<"TargetDeviceSpecInterface::Trait"> {
159- let cppNamespace = "::mlir";
160- }
161-
162212def DLTI_TargetDeviceSpecAttr :
163- DLTIAttr<"TargetDeviceSpec", [TargetDeviceSpecTrait ]> {
213+ DLTIAttr<"TargetDeviceSpec", [TargetDeviceSpecInterface ]> {
164214 let summary = "An attribute to represent target device specification.";
165215 let description = [{
166216 Each device specification describes a single device and its
@@ -179,6 +229,13 @@ def DLTI_TargetDeviceSpecAttr :
179229 let mnemonic = "target_device_spec";
180230 let genVerifyDecl = 1;
181231 let assemblyFormat = "`<` $entries `>`";
232+
233+ let extraClassDeclaration = [{
234+ /// Returns the attribute associated with the key.
235+ FailureOr<Attribute> query(DataLayoutEntryKey key) const {
236+ return llvm::cast<mlir::TargetDeviceSpecInterface>(*this).queryHelper(key);
237+ }
238+ }];
182239}
183240
184241#endif // MLIR_DIALECT_DLTI_DLTIATTRS_TD
0 commit comments