17#include "llvm/IR/DataLayout.h"
25 "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-"
26 "f16:16:16-f64:64:64-f128:128:128";
32 return Float16Type::get(context);
34 return Float32Type::get(context);
36 return Float64Type::get(context);
38 return Float80Type::get(context);
40 return Float128Type::get(context);
47DataLayoutImporter::tryToParseAlphaPrefix(StringRef &token)
const {
51 StringRef prefix = token.take_while(isalpha);
55 token.consume_front(prefix);
59FailureOr<uint64_t> DataLayoutImporter::tryToParseInt(StringRef &token)
const {
61 if (token.consumeInteger(10, parameter))
69 token.consume_front(
":");
70 token.split(tokens,
':');
74 for (
auto [
result, token] : llvm::zip(results, tokens))
75 if (token.getAsInteger(10,
result))
80FailureOr<SmallVector<uint64_t>>
81DataLayoutImporter::tryToParseIntList(StringRef token)
const {
85FailureOr<DenseIntElementsAttr>
86DataLayoutImporter::tryToParseAlignment(StringRef token)
const {
87 FailureOr<SmallVector<uint64_t>> alignment = tryToParseIntList(token);
90 if (alignment->empty() || alignment->size() > 2)
97 uint64_t minimal = (*alignment)[0];
98 uint64_t preferred = alignment->size() == 1 ? minimal : (*alignment)[1];
100 VectorType::get({2}, IntegerType::get(context, 64)),
101 {minimal, preferred});
104FailureOr<DenseIntElementsAttr>
105DataLayoutImporter::tryToParsePointerAlignment(StringRef token)
const {
106 FailureOr<SmallVector<uint64_t>> alignment = tryToParseIntList(token);
109 if (alignment->size() < 2 || alignment->size() > 4)
118 uint64_t size = (*alignment)[0];
119 uint64_t minimal = (*alignment)[1];
120 uint64_t preferred = alignment->size() < 3 ? minimal : (*alignment)[2];
121 uint64_t idx = alignment->size() < 4 ? size : (*alignment)[3];
123 VectorType::get({4}, IntegerType::get(context, 64)),
124 {size, minimal, preferred, idx});
127LogicalResult DataLayoutImporter::tryToEmplaceAlignmentEntry(Type type,
129 auto key = TypeAttr::get(type);
130 if (typeEntries.count(key))
133 FailureOr<DenseIntElementsAttr> params = tryToParseAlignment(token);
137 typeEntries.try_emplace(key, DataLayoutEntryAttr::get(type, *params));
142DataLayoutImporter::tryToEmplacePointerAlignmentEntry(LLVMPointerType type,
144 auto key = TypeAttr::get(type);
145 if (typeEntries.count(key))
148 FailureOr<DenseIntElementsAttr> params = tryToParsePointerAlignment(token);
152 typeEntries.try_emplace(key, DataLayoutEntryAttr::get(type, *params));
157DataLayoutImporter::tryToEmplaceEndiannessEntry(StringRef endianness,
159 auto key = StringAttr::get(context, DLTIDialect::kDataLayoutEndiannessKey);
160 if (keyEntries.count(key))
166 keyEntries.try_emplace(
167 key, DataLayoutEntryAttr::get(key, StringAttr::get(context, endianness)));
171LogicalResult DataLayoutImporter::tryToEmplaceManglingModeEntry(
172 StringRef token, llvm::StringLiteral manglingKey) {
173 auto key = StringAttr::get(context, manglingKey);
174 if (keyEntries.count(key))
177 token.consume_front(
":");
181 keyEntries.try_emplace(
182 key, DataLayoutEntryAttr::get(key, StringAttr::get(context, token)));
187DataLayoutImporter::tryToEmplaceAddrSpaceEntry(StringRef token,
188 llvm::StringLiteral spaceKey) {
189 auto key = StringAttr::get(context, spaceKey);
190 if (keyEntries.count(key))
193 FailureOr<uint64_t> space = tryToParseInt(token);
200 OpBuilder builder(context);
201 keyEntries.try_emplace(
203 DataLayoutEntryAttr::get(
204 key, builder.getIntegerAttr(
205 builder.getIntegerType(64,
false), *space)));
210DataLayoutImporter::tryToEmplaceStackAlignmentEntry(StringRef token) {
212 StringAttr::get(context, DLTIDialect::kDataLayoutStackAlignmentKey);
213 if (keyEntries.count(key))
216 FailureOr<uint64_t> alignment = tryToParseInt(token);
223 OpBuilder builder(context);
224 keyEntries.try_emplace(key, DataLayoutEntryAttr::get(
225 key, builder.getI64IntegerAttr(*alignment)));
229LogicalResult DataLayoutImporter::tryToEmplaceFunctionPointerAlignmentEntry(
230 StringRef fnPtrString, StringRef token) {
231 auto key = StringAttr::get(
232 context, DLTIDialect::kDataLayoutFunctionPointerAlignmentKey);
233 if (keyEntries.count(key))
242 bool functionDependent =
false;
243 if (fnPtrString ==
"n")
244 functionDependent =
true;
245 else if (fnPtrString !=
"i")
248 FailureOr<uint64_t> alignment = tryToParseInt(token);
252 keyEntries.try_emplace(
253 key, DataLayoutEntryAttr::get(
254 key, FunctionPointerAlignmentAttr::get(
255 key.getContext(), *alignment, functionDependent)));
260DataLayoutImporter::tryToEmplaceLegalIntWidthsEntry(StringRef token) {
262 StringAttr::get(context, DLTIDialect::kDataLayoutLegalIntWidthsKey);
263 if (keyEntries.count(key))
266 FailureOr<SmallVector<int32_t>> intWidths =
268 if (
failed(intWidths) || intWidths->empty())
271 OpBuilder builder(context);
272 keyEntries.try_emplace(
274 DataLayoutEntryAttr::get(key, builder.getDenseI32ArrayAttr(*intWidths)));
278DataLayoutSpecInterface DataLayoutImporter::dataLayoutSpecFromDataLayoutStr() {
279 if (!dataLayoutStr.empty())
280 dataLayoutStr +=
"-";
284 SmallVector<StringRef> tokens;
285 StringRef(dataLayoutStr).split(tokens,
'-');
287 for (StringRef token : tokens) {
289 FailureOr<StringRef> prefix = tryToParseAlphaPrefix(token);
294 if (*prefix ==
"e") {
295 if (
failed(tryToEmplaceEndiannessEntry(
296 DLTIDialect::kDataLayoutEndiannessLittle, token)))
300 if (*prefix ==
"E") {
301 if (
failed(tryToEmplaceEndiannessEntry(
302 DLTIDialect::kDataLayoutEndiannessBig, token)))
307 if (*prefix ==
"P") {
308 if (
failed(tryToEmplaceAddrSpaceEntry(
309 token, DLTIDialect::kDataLayoutProgramMemorySpaceKey)))
314 if (*prefix ==
"m") {
315 if (
failed(tryToEmplaceManglingModeEntry(
316 token, DLTIDialect::kDataLayoutManglingModeKey)))
321 if (*prefix ==
"G") {
322 if (
failed(tryToEmplaceAddrSpaceEntry(
323 token, DLTIDialect::kDataLayoutGlobalMemorySpaceKey)))
328 if (*prefix ==
"A") {
329 if (
failed(tryToEmplaceAddrSpaceEntry(
330 token, DLTIDialect::kDataLayoutAllocaMemorySpaceKey)))
335 if (*prefix ==
"S") {
336 if (
failed(tryToEmplaceStackAlignmentEntry(token)))
341 if (*prefix ==
"i") {
342 FailureOr<uint64_t> width = tryToParseInt(token);
346 Type type = IntegerType::get(context, *width);
347 if (
failed(tryToEmplaceAlignmentEntry(type, token)))
352 if (*prefix ==
"f") {
353 FailureOr<uint64_t> width = tryToParseInt(token);
358 if (
failed(tryToEmplaceAlignmentEntry(type, token)))
363 if (*prefix ==
"p") {
364 FailureOr<uint64_t> space =
365 token.starts_with(
":") ? 0 : tryToParseInt(token);
369 auto type = LLVMPointerType::get(context, *space);
370 if (
failed(tryToEmplacePointerAlignmentEntry(type, token)))
375 if (*prefix ==
"n") {
376 if (
failed(tryToEmplaceLegalIntWidthsEntry(token)))
382 if (prefix->starts_with(
"F")) {
383 StringRef nextPrefix = prefix->drop_front(1);
384 if (
failed(tryToEmplaceFunctionPointerAlignmentEntry(nextPrefix, token)))
390 unhandledTokens.push_back(lastToken);
394 SmallVector<DataLayoutEntryInterface> entries;
395 entries.reserve(typeEntries.size() + keyEntries.size());
396 for (
const auto &it : typeEntries)
397 entries.push_back(it.second);
398 for (
const auto &it : keyEntries)
399 entries.push_back(it.second);
400 return DataLayoutSpecAttr::get(context, entries);
403DataLayoutSpecInterface
static FailureOr< SmallVector< T > > tryToParseIntListImpl(StringRef token)
static constexpr StringRef kDefaultDataLayout
The default data layout used during the translation.
static DenseIntElementsAttr get(const ShapedType &type, Arg &&arg)
Get an instance of a DenseIntElementsAttr with the given arguments.
Helper class that translates an LLVM data layout string to an MLIR data layout specification.
DataLayoutSpecInterface getDataLayoutSpec() const
Returns the MLIR data layout specification translated from the LLVM data layout.
MLIRContext is the top-level object for a collection of MLIR operations.
FloatType getFloatType(MLIRContext *context, unsigned width)
Returns a supported MLIR floating point type of the given bit width or null if the bit width is not s...
Include the generated interface declarations.
DataLayoutSpecInterface translateDataLayout(const llvm::DataLayout &dataLayout, MLIRContext *context)
Translate the given LLVM data layout into an MLIR equivalent using the DLTI dialect.