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(
167 DataLayoutImporter::tryToEmplaceAddrSpaceEntry(StringRef token,
168 llvm::StringLiteral spaceKey) {
170 if (keyEntries.count(key))
173 FailureOr<uint64_t> space = tryToParseInt(token);
181 keyEntries.try_emplace(
184 key, builder.getIntegerAttr(
185 builder.getIntegerType(64,
false), *space)));
190 DataLayoutImporter::tryToEmplaceStackAlignmentEntry(StringRef token) {
193 if (keyEntries.count(key))
196 FailureOr<uint64_t> alignment = tryToParseInt(token);
197 if (failed(alignment))
205 key, builder.getI64IntegerAttr(*alignment)));
209 void DataLayoutImporter::translateDataLayout(
210 const llvm::DataLayout &llvmDataLayout) {
221 layoutStr = llvmDataLayout.getStringRepresentation();
222 if (!layoutStr.empty())
225 StringRef layout(layoutStr);
229 layout.split(tokens,
'-');
231 for (StringRef token : tokens) {
233 FailureOr<StringRef> prefix = tryToParseAlphaPrefix(token);
238 if (*prefix ==
"e") {
239 if (failed(tryToEmplaceEndiannessEntry(
240 DLTIDialect::kDataLayoutEndiannessLittle, token)))
244 if (*prefix ==
"E") {
245 if (failed(tryToEmplaceEndiannessEntry(
246 DLTIDialect::kDataLayoutEndiannessBig, token)))
251 if (*prefix ==
"P") {
252 if (failed(tryToEmplaceAddrSpaceEntry(
253 token, DLTIDialect::kDataLayoutProgramMemorySpaceKey)))
258 if (*prefix ==
"G") {
259 if (failed(tryToEmplaceAddrSpaceEntry(
260 token, DLTIDialect::kDataLayoutGlobalMemorySpaceKey)))
265 if (*prefix ==
"A") {
266 if (failed(tryToEmplaceAddrSpaceEntry(
267 token, DLTIDialect::kDataLayoutAllocaMemorySpaceKey)))
272 if (*prefix ==
"S") {
273 if (failed(tryToEmplaceStackAlignmentEntry(token)))
278 if (*prefix ==
"i") {
279 FailureOr<uint64_t> width = tryToParseInt(token);
284 if (failed(tryToEmplaceAlignmentEntry(type, token)))
289 if (*prefix ==
"f") {
290 FailureOr<uint64_t> width = tryToParseInt(token);
295 if (failed(tryToEmplaceAlignmentEntry(type, token)))
300 if (*prefix ==
"p") {
301 FailureOr<uint64_t> space =
302 token.starts_with(
":") ? 0 : tryToParseInt(token);
307 if (failed(tryToEmplacePointerAlignmentEntry(type, token)))
313 unhandledTokens.push_back(lastToken);
318 entries.reserve(typeEntries.size() + keyEntries.size());
319 for (
const auto &it : typeEntries)
320 entries.push_back(it.second);
321 for (
const auto &it : keyEntries)
322 entries.push_back(it.second);
326 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.
static FloatType getF64(MLIRContext *ctx)
static FloatType getF80(MLIRContext *ctx)
static FloatType getF16(MLIRContext *ctx)
static FloatType getF128(MLIRContext *ctx)
static FloatType getF32(MLIRContext *ctx)
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...