10
10
#define MLIR_DIALECT_DLTI_DLTIATTRS_TD
11
11
12
12
include "mlir/Dialect/DLTI/DLTI.td"
13
+ include "mlir/Interfaces/DataLayoutInterfaces.td"
13
14
include "mlir/IR/AttrTypeBase.td"
14
15
15
16
class DLTIAttr<string name, list<Trait> traits = [],
@@ -20,13 +21,8 @@ class DLTIAttr<string name, list<Trait> traits = [],
20
21
// DataLayoutEntryAttr
21
22
//===----------------------------------------------------------------------===//
22
23
23
- def DataLayoutEntryTrait
24
- : NativeAttrTrait<"DataLayoutEntryInterface::Trait"> {
25
- let cppNamespace = "::mlir";
26
- }
27
-
28
24
def DLTI_DataLayoutEntryAttr :
29
- DLTIAttr<"DataLayoutEntry", [DataLayoutEntryTrait ]> {
25
+ DLTIAttr<"DataLayoutEntry", [DataLayoutEntryInterface ]> {
30
26
let summary = "An attribute to represent an entry of a data layout specification.";
31
27
let description = [{
32
28
A data layout entry attribute is a key-value pair where the key is a type or
@@ -53,13 +49,9 @@ def DLTI_DataLayoutEntryAttr :
53
49
//===----------------------------------------------------------------------===//
54
50
// DataLayoutSpecAttr
55
51
//===----------------------------------------------------------------------===//
56
- def DataLayoutSpecTrait
57
- : NativeAttrTrait<"DataLayoutSpecInterface::Trait"> {
58
- let cppNamespace = "::mlir";
59
- }
60
52
61
53
def DLTI_DataLayoutSpecAttr :
62
- DLTIAttr<"DataLayoutSpec", [DataLayoutSpecTrait ]> {
54
+ DLTIAttr<"DataLayoutSpec", [DataLayoutSpecInterface ]> {
63
55
let summary = "An attribute to represent a data layout specification.";
64
56
let description = [{
65
57
A data layout specification is a list of entries that specify (partial) data
@@ -78,7 +70,7 @@ def DLTI_DataLayoutSpecAttr :
78
70
/// same key as the newer entries if the entries are compatible. Returns null
79
71
/// if the specifications are not compatible.
80
72
DataLayoutSpecAttr combineWith(ArrayRef<DataLayoutSpecInterface> specs) const;
81
-
73
+
82
74
/// Returns the endiannes identifier.
83
75
StringAttr getEndiannessIdentifier(MLIRContext *context) const;
84
76
@@ -93,20 +85,78 @@ def DLTI_DataLayoutSpecAttr :
93
85
94
86
/// Returns the stack alignment identifier.
95
87
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
+ }
96
151
}];
97
152
}
98
153
99
154
//===----------------------------------------------------------------------===//
100
155
// TargetSystemSpecAttr
101
156
//===----------------------------------------------------------------------===//
102
157
103
- def TargetSystemSpecTrait
104
- : NativeAttrTrait<"TargetSystemSpecInterface::Trait"> {
105
- let cppNamespace = "::mlir";
106
- }
107
-
108
158
def DLTI_TargetSystemSpecAttr :
109
- DLTIAttr<"TargetSystemSpec", [TargetSystemSpecTrait ]> {
159
+ DLTIAttr<"TargetSystemSpec", [TargetSystemSpecInterface ]> {
110
160
let summary = "An attribute to represent target system specification.";
111
161
let description = [{
112
162
A system specification describes the overall system containing
@@ -136,6 +186,11 @@ def DLTI_TargetSystemSpecAttr :
136
186
std::optional<TargetDeviceSpecInterface>
137
187
getDeviceSpecForDeviceID(
138
188
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
+ }
139
194
}];
140
195
let extraClassDefinition = [{
141
196
std::optional<TargetDeviceSpecInterface>
@@ -154,13 +209,8 @@ def DLTI_TargetSystemSpecAttr :
154
209
// TargetDeviceSpecAttr
155
210
//===----------------------------------------------------------------------===//
156
211
157
- def TargetDeviceSpecTrait
158
- : NativeAttrTrait<"TargetDeviceSpecInterface::Trait"> {
159
- let cppNamespace = "::mlir";
160
- }
161
-
162
212
def DLTI_TargetDeviceSpecAttr :
163
- DLTIAttr<"TargetDeviceSpec", [TargetDeviceSpecTrait ]> {
213
+ DLTIAttr<"TargetDeviceSpec", [TargetDeviceSpecInterface ]> {
164
214
let summary = "An attribute to represent target device specification.";
165
215
let description = [{
166
216
Each device specification describes a single device and its
@@ -179,6 +229,13 @@ def DLTI_TargetDeviceSpecAttr :
179
229
let mnemonic = "target_device_spec";
180
230
let genVerifyDecl = 1;
181
231
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
+ }];
182
239
}
183
240
184
241
#endif // MLIR_DIALECT_DLTI_DLTIATTRS_TD
0 commit comments