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";
47 DataLayoutImporter::tryToParseAlphaPrefix(StringRef &token)
const {
51 StringRef prefix = token.take_while(isalpha);
55 token.consume_front(prefix);
59 FailureOr<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))
80 FailureOr<SmallVector<uint64_t>>
81 DataLayoutImporter::tryToParseIntList(StringRef token)
const {
82 return tryToParseIntListImpl<uint64_t>(token);
85 FailureOr<DenseIntElementsAttr>
86 DataLayoutImporter::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];
101 {minimal, preferred});
104 FailureOr<DenseIntElementsAttr>
105 DataLayoutImporter::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];
122 return DenseIntElementsAttr::get<uint64_t>(
124 {size, minimal, preferred, idx});
127 LogicalResult DataLayoutImporter::tryToEmplaceAlignmentEntry(
Type type,
130 if (typeEntries.count(key))
133 FailureOr<DenseIntElementsAttr> params = tryToParseAlignment(token);
142 DataLayoutImporter::tryToEmplacePointerAlignmentEntry(LLVMPointerType type,
145 if (typeEntries.count(key))
148 FailureOr<DenseIntElementsAttr> params = tryToParsePointerAlignment(token);
157 DataLayoutImporter::tryToEmplaceEndiannessEntry(StringRef endianness,
159 auto key =
StringAttr::get(context, DLTIDialect::kDataLayoutEndiannessKey);
160 if (keyEntries.count(key))
166 keyEntries.try_emplace(
171 LogicalResult DataLayoutImporter::tryToEmplaceManglingModeEntry(
172 StringRef token, llvm::StringLiteral manglingKey) {
174 if (keyEntries.count(key))
177 token.consume_front(
":");
181 keyEntries.try_emplace(
187 DataLayoutImporter::tryToEmplaceAddrSpaceEntry(StringRef token,
188 llvm::StringLiteral spaceKey) {
190 if (keyEntries.count(key))
193 FailureOr<uint64_t> space = tryToParseInt(token);
201 keyEntries.try_emplace(
204 key, builder.getIntegerAttr(
205 builder.getIntegerType(64,
false), *space)));
210 DataLayoutImporter::tryToEmplaceStackAlignmentEntry(StringRef token) {
213 if (keyEntries.count(key))
216 FailureOr<uint64_t> alignment = tryToParseInt(token);
225 key, builder.getI64IntegerAttr(*alignment)));
229 LogicalResult DataLayoutImporter::tryToEmplaceFunctionPointerAlignmentEntry(
230 StringRef fnPtrString, StringRef token) {
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(
255 key.getContext(), *alignment, functionDependent)));
260 DataLayoutImporter::tryToEmplaceLegalIntWidthsEntry(StringRef token) {
263 if (keyEntries.count(key))
266 FailureOr<SmallVector<int32_t>> intWidths =
267 tryToParseIntListImpl<int32_t>(token);
268 if (
failed(intWidths) || intWidths->empty())
272 keyEntries.try_emplace(
278 DataLayoutSpecInterface DataLayoutImporter::dataLayoutSpecFromDataLayoutStr() {
279 if (!dataLayoutStr.empty())
280 dataLayoutStr +=
"-";
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);
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);
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);
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);
403 DataLayoutSpecInterface
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.
This class helps build Operations.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
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.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...