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))
66 FailureOr<SmallVector<uint64_t>>
67 DataLayoutImporter::tryToParseIntList(StringRef token)
const {
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<DenseIntElementsAttr>
81 DataLayoutImporter::tryToParseAlignment(StringRef token)
const {
82 FailureOr<SmallVector<uint64_t>> alignment = tryToParseIntList(token);
83 if (failed(alignment))
85 if (alignment->empty() || alignment->size() > 2)
92 uint64_t minimal = (*alignment)[0];
93 uint64_t preferred = alignment->size() == 1 ? minimal : (*alignment)[1];
96 {minimal, preferred});
99 FailureOr<DenseIntElementsAttr>
100 DataLayoutImporter::tryToParsePointerAlignment(StringRef token)
const {
101 FailureOr<SmallVector<uint64_t>> alignment = tryToParseIntList(token);
102 if (failed(alignment))
104 if (alignment->size() < 2 || alignment->size() > 4)
113 uint64_t size = (*alignment)[0];
114 uint64_t minimal = (*alignment)[1];
115 uint64_t preferred = alignment->size() < 3 ? minimal : (*alignment)[2];
116 uint64_t idx = alignment->size() < 4 ? size : (*alignment)[3];
117 return DenseIntElementsAttr::get<uint64_t>(
119 {size, minimal, preferred, idx});
122 LogicalResult DataLayoutImporter::tryToEmplaceAlignmentEntry(
Type type,
125 if (typeEntries.count(key))
128 FailureOr<DenseIntElementsAttr> params = tryToParseAlignment(token);
137 DataLayoutImporter::tryToEmplacePointerAlignmentEntry(LLVMPointerType type,
140 if (typeEntries.count(key))
143 FailureOr<DenseIntElementsAttr> params = tryToParsePointerAlignment(token);
152 DataLayoutImporter::tryToEmplaceEndiannessEntry(StringRef endianness,
154 auto key =
StringAttr::get(context, DLTIDialect::kDataLayoutEndiannessKey);
155 if (keyEntries.count(key))
161 keyEntries.try_emplace(
166 LogicalResult DataLayoutImporter::tryToEmplaceManglingModeEntry(
167 StringRef token, llvm::StringLiteral manglingKey) {
169 if (keyEntries.count(key))
172 token.consume_front(
":");
176 keyEntries.try_emplace(
182 DataLayoutImporter::tryToEmplaceAddrSpaceEntry(StringRef token,
183 llvm::StringLiteral spaceKey) {
185 if (keyEntries.count(key))
188 FailureOr<uint64_t> space = tryToParseInt(token);
196 keyEntries.try_emplace(
199 key, builder.getIntegerAttr(
200 builder.getIntegerType(64,
false), *space)));
205 DataLayoutImporter::tryToEmplaceStackAlignmentEntry(StringRef token) {
208 if (keyEntries.count(key))
211 FailureOr<uint64_t> alignment = tryToParseInt(token);
212 if (failed(alignment))
220 key, builder.getI64IntegerAttr(*alignment)));
224 LogicalResult DataLayoutImporter::tryToEmplaceFunctionPointerAlignmentEntry(
225 StringRef fnPtrString, StringRef token) {
227 context, DLTIDialect::kDataLayoutFunctionPointerAlignmentKey);
228 if (keyEntries.count(key))
237 bool functionDependent =
false;
238 if (fnPtrString ==
"n")
239 functionDependent =
true;
240 else if (fnPtrString !=
"i")
243 FailureOr<uint64_t> alignment = tryToParseInt(token);
244 if (failed(alignment))
247 keyEntries.try_emplace(
250 key.getContext(), *alignment, functionDependent)));
254 void DataLayoutImporter::translateDataLayout(
255 const llvm::DataLayout &llvmDataLayout) {
266 layoutStr = llvmDataLayout.getStringRepresentation();
267 if (!layoutStr.empty())
270 StringRef layout(layoutStr);
274 layout.split(tokens,
'-');
276 for (StringRef token : tokens) {
278 FailureOr<StringRef> prefix = tryToParseAlphaPrefix(token);
283 if (*prefix ==
"e") {
284 if (failed(tryToEmplaceEndiannessEntry(
285 DLTIDialect::kDataLayoutEndiannessLittle, token)))
289 if (*prefix ==
"E") {
290 if (failed(tryToEmplaceEndiannessEntry(
291 DLTIDialect::kDataLayoutEndiannessBig, token)))
296 if (*prefix ==
"P") {
297 if (failed(tryToEmplaceAddrSpaceEntry(
298 token, DLTIDialect::kDataLayoutProgramMemorySpaceKey)))
303 if (*prefix ==
"m") {
304 if (failed(tryToEmplaceManglingModeEntry(
305 token, DLTIDialect::kDataLayoutManglingModeKey)))
310 if (*prefix ==
"G") {
311 if (failed(tryToEmplaceAddrSpaceEntry(
312 token, DLTIDialect::kDataLayoutGlobalMemorySpaceKey)))
317 if (*prefix ==
"A") {
318 if (failed(tryToEmplaceAddrSpaceEntry(
319 token, DLTIDialect::kDataLayoutAllocaMemorySpaceKey)))
324 if (*prefix ==
"S") {
325 if (failed(tryToEmplaceStackAlignmentEntry(token)))
330 if (*prefix ==
"i") {
331 FailureOr<uint64_t> width = tryToParseInt(token);
336 if (failed(tryToEmplaceAlignmentEntry(type, token)))
341 if (*prefix ==
"f") {
342 FailureOr<uint64_t> width = tryToParseInt(token);
347 if (failed(tryToEmplaceAlignmentEntry(type, token)))
352 if (*prefix ==
"p") {
353 FailureOr<uint64_t> space =
354 token.starts_with(
":") ? 0 : tryToParseInt(token);
359 if (failed(tryToEmplacePointerAlignmentEntry(type, token)))
365 if (prefix->starts_with(
"F")) {
366 StringRef nextPrefix = prefix->drop_front(1);
367 if (failed(tryToEmplaceFunctionPointerAlignmentEntry(nextPrefix, token)))
373 unhandledTokens.push_back(lastToken);
378 entries.reserve(typeEntries.size() + keyEntries.size());
379 for (
const auto &it : typeEntries)
380 entries.push_back(it.second);
381 for (
const auto &it : keyEntries)
382 entries.push_back(it.second);
386 DataLayoutSpecInterface
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...