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);
88 if (failed(alignment))
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);
107 if (failed(alignment))
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);
217 if (failed(alignment))
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);
249 if (failed(alignment))
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 void DataLayoutImporter::translateDataLayout(
279 const llvm::DataLayout &llvmDataLayout) {
290 layoutStr = llvmDataLayout.getStringRepresentation();
291 if (!layoutStr.empty())
294 StringRef layout(layoutStr);
298 layout.split(tokens,
'-');
300 for (StringRef token : tokens) {
302 FailureOr<StringRef> prefix = tryToParseAlphaPrefix(token);
307 if (*prefix ==
"e") {
308 if (failed(tryToEmplaceEndiannessEntry(
309 DLTIDialect::kDataLayoutEndiannessLittle, token)))
313 if (*prefix ==
"E") {
314 if (failed(tryToEmplaceEndiannessEntry(
315 DLTIDialect::kDataLayoutEndiannessBig, token)))
320 if (*prefix ==
"P") {
321 if (failed(tryToEmplaceAddrSpaceEntry(
322 token, DLTIDialect::kDataLayoutProgramMemorySpaceKey)))
327 if (*prefix ==
"m") {
328 if (failed(tryToEmplaceManglingModeEntry(
329 token, DLTIDialect::kDataLayoutManglingModeKey)))
334 if (*prefix ==
"G") {
335 if (failed(tryToEmplaceAddrSpaceEntry(
336 token, DLTIDialect::kDataLayoutGlobalMemorySpaceKey)))
341 if (*prefix ==
"A") {
342 if (failed(tryToEmplaceAddrSpaceEntry(
343 token, DLTIDialect::kDataLayoutAllocaMemorySpaceKey)))
348 if (*prefix ==
"S") {
349 if (failed(tryToEmplaceStackAlignmentEntry(token)))
354 if (*prefix ==
"i") {
355 FailureOr<uint64_t> width = tryToParseInt(token);
360 if (failed(tryToEmplaceAlignmentEntry(type, token)))
365 if (*prefix ==
"f") {
366 FailureOr<uint64_t> width = tryToParseInt(token);
371 if (failed(tryToEmplaceAlignmentEntry(type, token)))
376 if (*prefix ==
"p") {
377 FailureOr<uint64_t> space =
378 token.starts_with(
":") ? 0 : tryToParseInt(token);
383 if (failed(tryToEmplacePointerAlignmentEntry(type, token)))
388 if (*prefix ==
"n") {
389 if (failed(tryToEmplaceLegalIntWidthsEntry(token)))
395 if (prefix->starts_with(
"F")) {
396 StringRef nextPrefix = prefix->drop_front(1);
397 if (failed(tryToEmplaceFunctionPointerAlignmentEntry(nextPrefix, token)))
403 unhandledTokens.push_back(lastToken);
408 entries.reserve(typeEntries.size() + keyEntries.size());
409 for (
const auto &it : typeEntries)
410 entries.push_back(it.second);
411 for (
const auto &it : keyEntries)
412 entries.push_back(it.second);
416 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 to an MLIR data layout specification.
DataLayoutSpecInterface getDataLayout() 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...