@@ -86,23 +86,67 @@ unsigned mlir::detail::getDefaultTypeSizeInBits(Type type,
86
86
reportMissingDataLayout (type);
87
87
}
88
88
89
+ static DataLayoutEntryInterface
90
+ findEntryForIntegerType (IntegerType intType,
91
+ ArrayRef<DataLayoutEntryInterface> params) {
92
+ assert (!params.empty () && " expected non-empty parameter list" );
93
+ std::map<unsigned , DataLayoutEntryInterface> sortedParams;
94
+ for (DataLayoutEntryInterface entry : params) {
95
+ sortedParams.insert (std::make_pair (
96
+ entry.getKey ().get <Type>().getIntOrFloatBitWidth (), entry));
97
+ }
98
+ auto iter = sortedParams.lower_bound (intType.getWidth ());
99
+ if (iter == sortedParams.end ())
100
+ iter = std::prev (iter);
101
+
102
+ return iter->second ;
103
+ }
104
+
105
+ static unsigned extractABIAlignment (DataLayoutEntryInterface entry) {
106
+ auto values =
107
+ entry.getValue ().cast <DenseIntElementsAttr>().getValues <int32_t >();
108
+ return *values.begin () / 8u ;
109
+ }
110
+
111
+ static unsigned
112
+ getIntegerTypeABIAlignment (IntegerType intType,
113
+ ArrayRef<DataLayoutEntryInterface> params) {
114
+ if (params.empty ()) {
115
+ return intType.getWidth () < 64
116
+ ? llvm::PowerOf2Ceil (llvm::divideCeil (intType.getWidth (), 8 ))
117
+ : 4 ;
118
+ }
119
+
120
+ return extractABIAlignment (findEntryForIntegerType (intType, params));
121
+ }
122
+
123
+ static unsigned
124
+ getFloatTypeABIAlignment (FloatType fltType, const DataLayout &dataLayout,
125
+ ArrayRef<DataLayoutEntryInterface> params) {
126
+ assert (params.size () <= 1 && " at most one data layout entry is expected for "
127
+ " the singleton floating-point type" );
128
+ if (params.empty ())
129
+ return llvm::PowerOf2Ceil (dataLayout.getTypeSize (fltType));
130
+ return extractABIAlignment (params[0 ]);
131
+ }
132
+
89
133
unsigned mlir::detail::getDefaultABIAlignment (
90
134
Type type, const DataLayout &dataLayout,
91
135
ArrayRef<DataLayoutEntryInterface> params) {
92
136
// Natural alignment is the closest power-of-two number above.
93
- if (type.isa <FloatType, VectorType>())
137
+ if (type.isa <VectorType>())
94
138
return llvm::PowerOf2Ceil (dataLayout.getTypeSize (type));
95
139
140
+ if (auto fltType = type.dyn_cast <FloatType>())
141
+ return getFloatTypeABIAlignment (fltType, dataLayout, params);
142
+
96
143
// Index is an integer of some bitwidth.
97
144
if (type.isa <IndexType>())
98
145
return dataLayout.getTypeABIAlignment (
99
146
IntegerType::get (type.getContext (), getIndexBitwidth (params)));
100
147
101
- if (auto intType = type.dyn_cast <IntegerType>()) {
102
- return intType.getWidth () < 64
103
- ? llvm::PowerOf2Ceil (llvm::divideCeil (intType.getWidth (), 8 ))
104
- : 4 ;
105
- }
148
+ if (auto intType = type.dyn_cast <IntegerType>())
149
+ return getIntegerTypeABIAlignment (intType, params);
106
150
107
151
if (auto ctype = type.dyn_cast <ComplexType>())
108
152
return getDefaultABIAlignment (ctype.getElementType (), dataLayout, params);
@@ -113,17 +157,51 @@ unsigned mlir::detail::getDefaultABIAlignment(
113
157
reportMissingDataLayout (type);
114
158
}
115
159
160
+ static unsigned extractPreferredAlignment (DataLayoutEntryInterface entry) {
161
+ auto values =
162
+ entry.getValue ().cast <DenseIntElementsAttr>().getValues <int32_t >();
163
+ return *std::next (values.begin (), values.size () - 1 ) / 8u ;
164
+ }
165
+
166
+ static unsigned
167
+ getIntegerTypePreferredAlignment (IntegerType intType,
168
+ const DataLayout &dataLayout,
169
+ ArrayRef<DataLayoutEntryInterface> params) {
170
+ if (params.empty ())
171
+ return llvm::PowerOf2Ceil (dataLayout.getTypeSize (intType));
172
+
173
+ return extractPreferredAlignment (findEntryForIntegerType (intType, params));
174
+ }
175
+
176
+ static unsigned
177
+ getFloatTypePreferredAlignment (FloatType fltType, const DataLayout &dataLayout,
178
+ ArrayRef<DataLayoutEntryInterface> params) {
179
+ assert (params.size () <= 1 && " at most one data layout entry is expected for "
180
+ " the singleton floating-point type" );
181
+ if (params.empty ())
182
+ return dataLayout.getTypeABIAlignment (fltType);
183
+ return extractPreferredAlignment (params[0 ]);
184
+ }
185
+
116
186
unsigned mlir::detail::getDefaultPreferredAlignment (
117
187
Type type, const DataLayout &dataLayout,
118
188
ArrayRef<DataLayoutEntryInterface> params) {
119
189
// Preferred alignment is same as natural for floats and vectors.
120
- if (type.isa <FloatType, VectorType>())
190
+ if (type.isa <VectorType>())
121
191
return dataLayout.getTypeABIAlignment (type);
122
192
123
- // Preferred alignment is the cloest power-of-two number above for integers
193
+ if (auto fltType = type.dyn_cast <FloatType>())
194
+ return getFloatTypePreferredAlignment (fltType, dataLayout, params);
195
+
196
+ // Preferred alignment is the closest power-of-two number above for integers
124
197
// (ABI alignment may be smaller).
125
- if (type.isa <IntegerType, IndexType>())
126
- return llvm::PowerOf2Ceil (dataLayout.getTypeSize (type));
198
+ if (auto intType = type.dyn_cast <IntegerType>())
199
+ return getIntegerTypePreferredAlignment (intType, dataLayout, params);
200
+
201
+ if (type.isa <IndexType>()) {
202
+ return dataLayout.getTypePreferredAlignment (
203
+ IntegerType::get (type.getContext (), getIndexBitwidth (params)));
204
+ }
127
205
128
206
if (auto ctype = type.dyn_cast <ComplexType>())
129
207
return getDefaultPreferredAlignment (ctype.getElementType (), dataLayout,
@@ -418,6 +496,37 @@ LogicalResult mlir::detail::verifyDataLayoutSpec(DataLayoutSpecInterface spec,
418
496
continue ;
419
497
}
420
498
499
+ if (sampleType.isa <IntegerType, FloatType>()) {
500
+ for (DataLayoutEntryInterface entry : kvp.second ) {
501
+ auto value = entry.getValue ().dyn_cast <DenseIntElementsAttr>();
502
+ if (!value || !value.getElementType ().isSignlessInteger (32 )) {
503
+ emitError (loc) << " expected a dense i32 elements attribute in the "
504
+ " data layout entry "
505
+ << entry;
506
+ return failure ();
507
+ }
508
+
509
+ auto elements = llvm::to_vector<2 >(value.getValues <int32_t >());
510
+ unsigned numElements = elements.size ();
511
+ if (numElements < 1 || numElements > 2 ) {
512
+ emitError (loc) << " expected 1 or 2 elements in the data layout entry "
513
+ << entry;
514
+ return failure ();
515
+ }
516
+
517
+ int32_t abi = elements[0 ];
518
+ int32_t preferred = numElements == 2 ? elements[1 ] : abi;
519
+ if (preferred < abi) {
520
+ emitError (loc)
521
+ << " preferred alignment is expected to be greater than or equal "
522
+ " to the abi alignment in data layout entry "
523
+ << entry;
524
+ return failure ();
525
+ }
526
+ }
527
+ continue ;
528
+ }
529
+
421
530
if (isa<BuiltinDialect>(&sampleType.getDialect ()))
422
531
return emitError (loc) << " unexpected data layout for a built-in type" ;
423
532
0 commit comments