Skip to content

Commit 86685b9

Browse files
[MLIR][LLVM][DLTI] Handle data layout token 'n32:64' (#141299)
1 parent 7ed185a commit 86685b9

File tree

14 files changed

+139
-5
lines changed

14 files changed

+139
-5
lines changed

mlir/include/mlir/Dialect/DLTI/DLTIAttrs.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ def DLTI_DataLayoutSpecAttr :
9595
/// Returns the function pointer alignment identifier.
9696
StringAttr getFunctionPointerAlignmentIdentifier(MLIRContext *context) const;
9797

98+
/// Returns the legal int widths identifier.
99+
StringAttr getLegalIntWidthsIdentifier(MLIRContext *context) const;
100+
98101
/// Returns the attribute associated with the key.
99102
FailureOr<Attribute> query(DataLayoutEntryKey key) {
100103
return ::llvm::cast<mlir::DataLayoutSpecInterface>(*this).queryHelper(key);

mlir/include/mlir/Dialect/DLTI/DLTIBase.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ def DLTI_Dialect : Dialect {
7070

7171
constexpr const static ::llvm::StringLiteral
7272
kDataLayoutFunctionPointerAlignmentKey = "dlti.function_pointer_alignment";
73+
74+
constexpr const static ::llvm::StringLiteral
75+
kDataLayoutLegalIntWidthsKey = "dlti.legal_int_widths";
7376
}];
7477

7578
let useDefaultAttributePrinterParser = 1;

mlir/include/mlir/Interfaces/DataLayoutInterfaces.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ uint64_t getDefaultStackAlignment(DataLayoutEntryInterface entry);
105105
/// the DataLayoutInterface if specified, otherwise returns the default.
106106
Attribute getDefaultFunctionPointerAlignment(DataLayoutEntryInterface entry);
107107

108+
/// Default handler for the legal int widths request. Dispatches to the
109+
/// DataLayoutInterface if specified, otherwise returns the default.
110+
Attribute getDefaultLegalIntWidths(DataLayoutEntryInterface entry);
111+
108112
/// Returns the value of the property from the specified DataLayoutEntry. If the
109113
/// property is missing from the entry, returns std::nullopt.
110114
std::optional<Attribute> getDevicePropertyValue(DataLayoutEntryInterface entry);
@@ -266,6 +270,9 @@ class DataLayout {
266270
/// Returns function pointer alignment.
267271
Attribute getFunctionPointerAlignment() const;
268272

273+
/// Returns the legal int widths.
274+
Attribute getLegalIntWidths() const;
275+
269276
/// Returns the value of the specified property if the property is defined for
270277
/// the given device ID, otherwise returns std::nullopt.
271278
std::optional<Attribute>
@@ -312,6 +319,8 @@ class DataLayout {
312319
mutable std::optional<uint64_t> stackAlignment;
313320
/// Cache for function pointer alignment.
314321
mutable std::optional<Attribute> functionPointerAlignment;
322+
/// Cache for legal int widths.
323+
mutable std::optional<Attribute> legalIntWidths;
315324
};
316325

317326
} // namespace mlir

mlir/include/mlir/Interfaces/DataLayoutInterfaces.td

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ def DataLayoutSpecInterface : AttrInterface<"DataLayoutSpecInterface", [DLTIQuer
177177
/*methodName=*/"getFunctionPointerAlignmentIdentifier",
178178
/*args=*/(ins "::mlir::MLIRContext *":$context)
179179
>,
180+
InterfaceMethod<
181+
/*description=*/"Returns the legal int widths identifier.",
182+
/*retTy=*/"::mlir::StringAttr",
183+
/*methodName=*/"getLegalIntWidthsIdentifier",
184+
/*args=*/(ins "::mlir::MLIRContext *":$context)
185+
>,
180186
// Implementations may override this if they have an efficient lookup
181187
// mechanism.
182188
InterfaceMethod<
@@ -571,6 +577,18 @@ def DataLayoutOpInterface : OpInterface<"DataLayoutOpInterface"> {
571577
return ::mlir::detail::getDefaultFunctionPointerAlignment(entry);
572578
}]
573579
>,
580+
StaticInterfaceMethod<
581+
/*description=*/"Returns the legal int widths, each width in bits computed "
582+
"using the relevant entries. The data layout object "
583+
"can be used for recursive queries.",
584+
/*retTy=*/"Attribute",
585+
/*methodName=*/"getLegalIntWidths",
586+
/*args=*/(ins "::mlir::DataLayoutEntryInterface":$entry),
587+
/*methodBody=*/"",
588+
/*defaultImplementation=*/[{
589+
return ::mlir::detail::getDefaultLegalIntWidths(entry);
590+
}]
591+
>,
574592
StaticInterfaceMethod<
575593
/*description=*/"Returns the value of the property, if the property is "
576594
"defined. Otherwise, it returns std::nullopt.",

mlir/lib/Dialect/DLTI/DLTI.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,12 @@ StringAttr DataLayoutSpecAttr::getFunctionPointerAlignmentIdentifier(
426426
DLTIDialect::kDataLayoutFunctionPointerAlignmentKey);
427427
}
428428

429+
StringAttr
430+
DataLayoutSpecAttr::getLegalIntWidthsIdentifier(MLIRContext *context) const {
431+
return Builder(context).getStringAttr(
432+
DLTIDialect::kDataLayoutLegalIntWidthsKey);
433+
}
434+
429435
/// Parses an attribute with syntax:
430436
/// dl-spec-attr ::= `#dlti.` `dl_spec` `<` entry-list `>`
431437
/// entry-list ::= | entry | entry `,` entry-list
@@ -632,6 +638,7 @@ class TargetDataLayoutInterface : public DataLayoutDialectInterface {
632638
entryName == DLTIDialect::kDataLayoutGlobalMemorySpaceKey ||
633639
entryName == DLTIDialect::kDataLayoutStackAlignmentKey ||
634640
entryName == DLTIDialect::kDataLayoutFunctionPointerAlignmentKey ||
641+
entryName == DLTIDialect::kDataLayoutLegalIntWidthsKey ||
635642
entryName == DLTIDialect::kDataLayoutManglingModeKey)
636643
return success();
637644
return emitError(loc) << "unknown data layout entry name: " << entryName;

mlir/lib/Interfaces/DataLayoutInterfaces.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,16 @@ Attribute mlir::detail::getDefaultFunctionPointerAlignment(
321321
return entry.getValue();
322322
}
323323

324+
// Returns the legal int widths if specified in the given entry. If the entry is
325+
// empty the default legal int widths represented by an empty attribute is
326+
// returned.
327+
Attribute
328+
mlir::detail::getDefaultLegalIntWidths(DataLayoutEntryInterface entry) {
329+
if (entry == DataLayoutEntryInterface())
330+
return Attribute();
331+
return entry.getValue();
332+
}
333+
324334
std::optional<Attribute>
325335
mlir::detail::getDevicePropertyValue(DataLayoutEntryInterface entry) {
326336
if (entry == DataLayoutEntryInterface())
@@ -736,6 +746,22 @@ Attribute mlir::DataLayout::getFunctionPointerAlignment() const {
736746
return *functionPointerAlignment;
737747
}
738748

749+
Attribute mlir::DataLayout::getLegalIntWidths() const {
750+
checkValid();
751+
if (legalIntWidths)
752+
return *legalIntWidths;
753+
DataLayoutEntryInterface entry;
754+
if (originalLayout)
755+
entry = originalLayout.getSpecForIdentifier(
756+
originalLayout.getLegalIntWidthsIdentifier(
757+
originalLayout.getContext()));
758+
if (auto iface = dyn_cast_or_null<DataLayoutOpInterface>(scope))
759+
legalIntWidths = iface.getLegalIntWidths(entry);
760+
else
761+
legalIntWidths = detail::getDefaultLegalIntWidths(entry);
762+
return *legalIntWidths;
763+
}
764+
739765
std::optional<Attribute> mlir::DataLayout::getDevicePropertyValue(
740766
TargetSystemSpecInterface::DeviceID deviceID,
741767
StringAttr propertyName) const {

mlir/lib/Target/LLVMIR/DataLayoutImporter.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,25 @@ FailureOr<uint64_t> DataLayoutImporter::tryToParseInt(StringRef &token) const {
6363
return parameter;
6464
}
6565

66-
FailureOr<SmallVector<uint64_t>>
67-
DataLayoutImporter::tryToParseIntList(StringRef token) const {
66+
template <class T>
67+
static FailureOr<SmallVector<T>> tryToParseIntListImpl(StringRef token) {
6868
SmallVector<StringRef> tokens;
6969
token.consume_front(":");
7070
token.split(tokens, ':');
7171

7272
// Parse an integer list.
73-
SmallVector<uint64_t> results(tokens.size());
73+
SmallVector<T> results(tokens.size());
7474
for (auto [result, token] : llvm::zip(results, tokens))
7575
if (token.getAsInteger(/*Radix=*/10, result))
7676
return failure();
7777
return results;
7878
}
7979

80+
FailureOr<SmallVector<uint64_t>>
81+
DataLayoutImporter::tryToParseIntList(StringRef token) const {
82+
return tryToParseIntListImpl<uint64_t>(token);
83+
}
84+
8085
FailureOr<DenseIntElementsAttr>
8186
DataLayoutImporter::tryToParseAlignment(StringRef token) const {
8287
FailureOr<SmallVector<uint64_t>> alignment = tryToParseIntList(token);
@@ -251,6 +256,25 @@ LogicalResult DataLayoutImporter::tryToEmplaceFunctionPointerAlignmentEntry(
251256
return success();
252257
}
253258

259+
LogicalResult
260+
DataLayoutImporter::tryToEmplaceLegalIntWidthsEntry(StringRef token) {
261+
auto key =
262+
StringAttr::get(context, DLTIDialect::kDataLayoutLegalIntWidthsKey);
263+
if (keyEntries.count(key))
264+
return success();
265+
266+
FailureOr<SmallVector<int32_t>> intWidths =
267+
tryToParseIntListImpl<int32_t>(token);
268+
if (failed(intWidths) || intWidths->empty())
269+
return failure();
270+
271+
OpBuilder builder(context);
272+
keyEntries.try_emplace(
273+
key,
274+
DataLayoutEntryAttr::get(key, builder.getDenseI32ArrayAttr(*intWidths)));
275+
return success();
276+
}
277+
254278
void DataLayoutImporter::translateDataLayout(
255279
const llvm::DataLayout &llvmDataLayout) {
256280
dataLayout = {};
@@ -360,6 +384,12 @@ void DataLayoutImporter::translateDataLayout(
360384
return;
361385
continue;
362386
}
387+
// Parse native integer widths specifications.
388+
if (*prefix == "n") {
389+
if (failed(tryToEmplaceLegalIntWidthsEntry(token)))
390+
return;
391+
continue;
392+
}
363393
// Parse function pointer alignment specifications.
364394
// Note that prefix here is "Fn" or "Fi", not a single character.
365395
if (prefix->starts_with("F")) {

mlir/lib/Target/LLVMIR/DataLayoutImporter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ class DataLayoutImporter {
113113
tryToEmplaceFunctionPointerAlignmentEntry(StringRef fnPtrAlignEntry,
114114
StringRef token);
115115

116+
/// Adds legal int widths entry if there is none yet.
117+
LogicalResult tryToEmplaceLegalIntWidthsEntry(StringRef token);
118+
116119
std::string layoutStr = {};
117120
StringRef lastToken = {};
118121
SmallVector<StringRef> unhandledTokens;

mlir/lib/Target/LLVMIR/ModuleTranslation.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "mlir/Target/LLVMIR/TypeToLLVM.h"
3636

3737
#include "llvm/ADT/PostOrderIterator.h"
38+
#include "llvm/ADT/STLExtras.h"
3839
#include "llvm/ADT/SetVector.h"
3940
#include "llvm/ADT/StringExtras.h"
4041
#include "llvm/ADT/TypeSwitch.h"
@@ -52,6 +53,7 @@
5253
#include "llvm/IR/Module.h"
5354
#include "llvm/IR/Verifier.h"
5455
#include "llvm/Support/Debug.h"
56+
#include "llvm/Support/ErrorHandling.h"
5557
#include "llvm/Support/raw_ostream.h"
5658
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
5759
#include "llvm/Transforms/Utils/Cloning.h"
@@ -250,6 +252,13 @@ translateDataLayout(DataLayoutSpecInterface attribute,
250252
<< alignment;
251253
continue;
252254
}
255+
if (key.getValue() == DLTIDialect::kDataLayoutLegalIntWidthsKey) {
256+
layoutStream << "-n";
257+
llvm::interleave(
258+
cast<DenseI32ArrayAttr>(entry.getValue()).asArrayRef(), layoutStream,
259+
[&](int32_t val) { layoutStream << val; }, ":");
260+
continue;
261+
}
253262
emitError(*loc) << "unsupported data layout key " << key;
254263
return failure();
255264
}

mlir/test/Dialect/LLVMIR/layout.mlir

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module {
1212
// CHECK-SAME: #dlti.function_pointer_alignment<0, function_dependent = false>,
1313
// CHECK: global_memory_space = 0
1414
// CHECK: index = 64
15+
// CHECK: legal_int_widths = array<i32>
1516
// CHECK: mangling_mode = ""
1617
// CHECK: preferred = 8
1718
// CHECK: program_memory_space = 0
@@ -27,6 +28,7 @@ module {
2728
// CHECK-SAME: #dlti.function_pointer_alignment<0, function_dependent = false>,
2829
// CHECK: global_memory_space = 0
2930
// CHECK: index = 64
31+
// CHECK: legal_int_widths = array<i32>
3032
// CHECK: mangling_mode = ""
3133
// CHECK: preferred = 8
3234
// CHECK: program_memory_space = 0
@@ -42,6 +44,7 @@ module {
4244
// CHECK-SAME: #dlti.function_pointer_alignment<0, function_dependent = false>,
4345
// CHECK: global_memory_space = 0
4446
// CHECK: index = 64
47+
// CHECK: legal_int_widths = array<i32>
4548
// CHECK: mangling_mode = ""
4649
// CHECK: preferred = 8
4750
// CHECK: program_memory_space = 0
@@ -65,6 +68,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
6568
#dlti.dl_entry<"dlti.program_memory_space", 3 : ui64>,
6669
#dlti.dl_entry<"dlti.stack_alignment", 128 : i64>,
6770
#dlti.dl_entry<"dlti.mangling_mode", "e">,
71+
#dlti.dl_entry<"dlti.legal_int_widths", array<i32: 32, 64>>,
6872
#dlti.dl_entry<"dlti.function_pointer_alignment",
6973
"#dlti.function_pointer_alignment<32, function_dependent = true>">
7074
>} {
@@ -79,6 +83,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
7983
// CHECK-SAME: "#dlti.function_pointer_alignment<32, function_dependent = true>",
8084
// CHECK: global_memory_space = 2
8185
// CHECK: index = 32
86+
// CHECK: legal_int_widths = array<i32: 32, 64>
8287
// CHECK: mangling_mode = "e"
8388
// CHECK: preferred = 8
8489
// CHECK: program_memory_space = 3
@@ -94,6 +99,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
9499
// CHECK-SAME: "#dlti.function_pointer_alignment<32, function_dependent = true>",
95100
// CHECK: global_memory_space = 2
96101
// CHECK: index = 32
102+
// CHECK: legal_int_widths = array<i32: 32, 64>
97103
// CHECK: preferred = 8
98104
// CHECK: program_memory_space = 3
99105
// CHECK: size = 4
@@ -108,6 +114,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
108114
// CHECK-SAME: "#dlti.function_pointer_alignment<32, function_dependent = true>",
109115
// CHECK: global_memory_space = 2
110116
// CHECK: index = 64
117+
// CHECK: legal_int_widths = array<i32: 32, 64>
111118
// CHECK: mangling_mode = "e"
112119
// CHECK: preferred = 8
113120
// CHECK: program_memory_space = 3
@@ -123,6 +130,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
123130
// CHECK-SAME: "#dlti.function_pointer_alignment<32, function_dependent = true>",
124131
// CHECK: global_memory_space = 2
125132
// CHECK: index = 24
133+
// CHECK: legal_int_widths = array<i32: 32, 64>
126134
// CHECK: mangling_mode = "e"
127135
// CHECK: preferred = 8
128136
// CHECK: program_memory_space = 3

mlir/test/Target/LLVMIR/Import/data-layout.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ target datalayout = ""
2929
; CHECK-SAME: i8 = dense<8> : vector<2xi64>
3030
; CHECK-SAME: "dlti.endianness" = "little"
3131
; CHECK-SAME: "dlti.mangling_mode" = "e"
32+
; CHECK-SAME: "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>
3233
; CHECK-SAME: "dlti.stack_alignment" = 128 : i64
3334
; CHECK-SAME: "dlti.function_pointer_alignment" = #dlti.function_pointer_alignment<32, function_dependent = true>
3435
target datalayout = "e-m:e-p270:32:64-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-Fn32"

mlir/test/Target/LLVMIR/data-layout.mlir

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// CHECK: A4-
66
// CHECK: S128-
77
// CHECK: m:e-
8+
// CHECK: n8:16:32:64-
89
// CHECK: Fn32
910
// CHECK: i64:64:128
1011
// CHECK: f80:128:256
@@ -15,6 +16,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<
1516
#dlti.dl_entry<"dlti.alloca_memory_space", 4 : ui32>,
1617
#dlti.dl_entry<"dlti.stack_alignment", 128 : i32>,
1718
#dlti.dl_entry<"dlti.mangling_mode", "e">,
19+
#dlti.dl_entry<"dlti.legal_int_widths", array<i32: 8, 16, 32, 64>>,
1820
#dlti.dl_entry<"dlti.function_pointer_alignment",
1921
#dlti.function_pointer_alignment<32, function_dependent = true>>,
2022
#dlti.dl_entry<index, 64>,

mlir/test/lib/Dialect/DLTI/TestDataLayoutQuery.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ struct TestDataLayoutQuery
4949
Attribute globalMemorySpace = layout.getGlobalMemorySpace();
5050
uint64_t stackAlignment = layout.getStackAlignment();
5151
Attribute functionPointerAlignment = layout.getFunctionPointerAlignment();
52+
Attribute legalIntWidths = layout.getLegalIntWidths();
5253

5354
auto convertTypeSizeToAttr = [&](llvm::TypeSize typeSize) -> Attribute {
5455
if (!typeSize.isScalable())
@@ -97,7 +98,11 @@ struct TestDataLayoutQuery
9798
? FunctionPointerAlignmentAttr::get(
9899
builder.getContext(), 0,
99100
/*function_dependent=*/false)
100-
: functionPointerAlignment)
101+
: functionPointerAlignment),
102+
builder.getNamedAttr("legal_int_widths",
103+
legalIntWidths == Attribute()
104+
? builder.getDenseI32ArrayAttr({})
105+
: legalIntWidths)
101106

102107
});
103108

0 commit comments

Comments
 (0)