[Mlir-commits] [mlir] [MLIR][LLVM][DLTI] Handle data layout token 'n32:64' (PR #141299)
Bruno Cardoso Lopes
llvmlistbot at llvm.org
Tue May 27 12:32:29 PDT 2025
https://github.com/bcardosolopes updated https://github.com/llvm/llvm-project/pull/141299
>From 27d4f096611e9f5129320f66e84430ee8cf766ab Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Fri, 23 May 2025 14:59:06 -0700
Subject: [PATCH 1/2] [MLIR][LLVM][DLTI] Handle data layout token 'n32:64'
---
mlir/include/mlir/Dialect/DLTI/DLTIAttrs.td | 3 ++
mlir/include/mlir/Dialect/DLTI/DLTIBase.td | 3 ++
.../mlir/Interfaces/DataLayoutInterfaces.h | 9 ++++++
.../mlir/Interfaces/DataLayoutInterfaces.td | 18 +++++++++++
mlir/lib/Dialect/DLTI/DLTI.cpp | 7 +++++
mlir/lib/Interfaces/DataLayoutInterfaces.cpp | 26 ++++++++++++++++
mlir/lib/Target/LLVMIR/DataLayoutImporter.cpp | 30 +++++++++++++++++++
mlir/lib/Target/LLVMIR/DataLayoutImporter.h | 3 ++
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 13 ++++++++
mlir/test/Dialect/LLVMIR/layout.mlir | 8 +++++
mlir/test/Target/LLVMIR/Import/data-layout.ll | 1 +
mlir/test/Target/LLVMIR/data-layout.mlir | 2 ++
.../lib/Dialect/DLTI/TestDataLayoutQuery.cpp | 7 ++++-
.../Interfaces/DataLayoutInterfacesTest.cpp | 12 +++++++-
14 files changed, 140 insertions(+), 2 deletions(-)
diff --git a/mlir/include/mlir/Dialect/DLTI/DLTIAttrs.td b/mlir/include/mlir/Dialect/DLTI/DLTIAttrs.td
index 2aa58ea014caa..56bd704d30656 100644
--- a/mlir/include/mlir/Dialect/DLTI/DLTIAttrs.td
+++ b/mlir/include/mlir/Dialect/DLTI/DLTIAttrs.td
@@ -95,6 +95,9 @@ def DLTI_DataLayoutSpecAttr :
/// Returns the function pointer alignment identifier.
StringAttr getFunctionPointerAlignmentIdentifier(MLIRContext *context) const;
+ /// Returns the legal int widths identifier.
+ StringAttr getLegalIntWidthsIdentifier(MLIRContext *context) const;
+
/// Returns the attribute associated with the key.
FailureOr<Attribute> query(DataLayoutEntryKey key) {
return ::llvm::cast<mlir::DataLayoutSpecInterface>(*this).queryHelper(key);
diff --git a/mlir/include/mlir/Dialect/DLTI/DLTIBase.td b/mlir/include/mlir/Dialect/DLTI/DLTIBase.td
index ad5f9dc611c79..3754f3699c7fd 100644
--- a/mlir/include/mlir/Dialect/DLTI/DLTIBase.td
+++ b/mlir/include/mlir/Dialect/DLTI/DLTIBase.td
@@ -70,6 +70,9 @@ def DLTI_Dialect : Dialect {
constexpr const static ::llvm::StringLiteral
kDataLayoutFunctionPointerAlignmentKey = "dlti.function_pointer_alignment";
+
+ constexpr const static ::llvm::StringLiteral
+ kDataLayoutLegalIntWidthsKey = "dlti.legal_int_widths";
}];
let useDefaultAttributePrinterParser = 1;
diff --git a/mlir/include/mlir/Interfaces/DataLayoutInterfaces.h b/mlir/include/mlir/Interfaces/DataLayoutInterfaces.h
index 55d169df1c009..bf509ba3e1c11 100644
--- a/mlir/include/mlir/Interfaces/DataLayoutInterfaces.h
+++ b/mlir/include/mlir/Interfaces/DataLayoutInterfaces.h
@@ -105,6 +105,10 @@ uint64_t getDefaultStackAlignment(DataLayoutEntryInterface entry);
/// the DataLayoutInterface if specified, otherwise returns the default.
Attribute getDefaultFunctionPointerAlignment(DataLayoutEntryInterface entry);
+/// Default handler for the legal int widths request. Dispatches to the
+/// DataLayoutInterface if specified, otherwise returns the default.
+Attribute getDefaultLegalIntWidths(DataLayoutEntryInterface entry);
+
/// Returns the value of the property from the specified DataLayoutEntry. If the
/// property is missing from the entry, returns std::nullopt.
std::optional<Attribute> getDevicePropertyValue(DataLayoutEntryInterface entry);
@@ -266,6 +270,9 @@ class DataLayout {
/// Returns function pointer alignment.
Attribute getFunctionPointerAlignment() const;
+ /// Returns the legal int widths.
+ Attribute getLegalIntWidths() const;
+
/// Returns the value of the specified property if the property is defined for
/// the given device ID, otherwise returns std::nullopt.
std::optional<Attribute>
@@ -312,6 +319,8 @@ class DataLayout {
mutable std::optional<uint64_t> stackAlignment;
/// Cache for function pointer alignment.
mutable std::optional<Attribute> functionPointerAlignment;
+ /// Cache for legal int widths.
+ mutable std::optional<Attribute> legalIntWidths;
};
} // namespace mlir
diff --git a/mlir/include/mlir/Interfaces/DataLayoutInterfaces.td b/mlir/include/mlir/Interfaces/DataLayoutInterfaces.td
index d10a2fd9dc8e4..a22aa0012ddd3 100644
--- a/mlir/include/mlir/Interfaces/DataLayoutInterfaces.td
+++ b/mlir/include/mlir/Interfaces/DataLayoutInterfaces.td
@@ -177,6 +177,12 @@ def DataLayoutSpecInterface : AttrInterface<"DataLayoutSpecInterface", [DLTIQuer
/*methodName=*/"getFunctionPointerAlignmentIdentifier",
/*args=*/(ins "::mlir::MLIRContext *":$context)
>,
+ InterfaceMethod<
+ /*description=*/"Returns the legal int widths identifier.",
+ /*retTy=*/"::mlir::StringAttr",
+ /*methodName=*/"getLegalIntWidthsIdentifier",
+ /*args=*/(ins "::mlir::MLIRContext *":$context)
+ >,
// Implementations may override this if they have an efficient lookup
// mechanism.
InterfaceMethod<
@@ -571,6 +577,18 @@ def DataLayoutOpInterface : OpInterface<"DataLayoutOpInterface"> {
return ::mlir::detail::getDefaultFunctionPointerAlignment(entry);
}]
>,
+ StaticInterfaceMethod<
+ /*description=*/"Returns the legal int widths, each width in bits computed "
+ "using the relevant entries. The data layout object "
+ "can be used for recursive queries.",
+ /*retTy=*/"Attribute",
+ /*methodName=*/"getLegalIntWidths",
+ /*args=*/(ins "::mlir::DataLayoutEntryInterface":$entry),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ return ::mlir::detail::getDefaultLegalIntWidths(entry);
+ }]
+ >,
StaticInterfaceMethod<
/*description=*/"Returns the value of the property, if the property is "
"defined. Otherwise, it returns std::nullopt.",
diff --git a/mlir/lib/Dialect/DLTI/DLTI.cpp b/mlir/lib/Dialect/DLTI/DLTI.cpp
index ae8f016c3d1a5..0c4fe27ffa58e 100644
--- a/mlir/lib/Dialect/DLTI/DLTI.cpp
+++ b/mlir/lib/Dialect/DLTI/DLTI.cpp
@@ -426,6 +426,12 @@ StringAttr DataLayoutSpecAttr::getFunctionPointerAlignmentIdentifier(
DLTIDialect::kDataLayoutFunctionPointerAlignmentKey);
}
+StringAttr
+DataLayoutSpecAttr::getLegalIntWidthsIdentifier(MLIRContext *context) const {
+ return Builder(context).getStringAttr(
+ DLTIDialect::kDataLayoutLegalIntWidthsKey);
+}
+
/// Parses an attribute with syntax:
/// dl-spec-attr ::= `#dlti.` `dl_spec` `<` entry-list `>`
/// entry-list ::= | entry | entry `,` entry-list
@@ -632,6 +638,7 @@ class TargetDataLayoutInterface : public DataLayoutDialectInterface {
entryName == DLTIDialect::kDataLayoutGlobalMemorySpaceKey ||
entryName == DLTIDialect::kDataLayoutStackAlignmentKey ||
entryName == DLTIDialect::kDataLayoutFunctionPointerAlignmentKey ||
+ entryName == DLTIDialect::kDataLayoutLegalIntWidthsKey ||
entryName == DLTIDialect::kDataLayoutManglingModeKey)
return success();
return emitError(loc) << "unknown data layout entry name: " << entryName;
diff --git a/mlir/lib/Interfaces/DataLayoutInterfaces.cpp b/mlir/lib/Interfaces/DataLayoutInterfaces.cpp
index fbbe28ce9b4cc..3b6330b6a6c58 100644
--- a/mlir/lib/Interfaces/DataLayoutInterfaces.cpp
+++ b/mlir/lib/Interfaces/DataLayoutInterfaces.cpp
@@ -321,6 +321,16 @@ Attribute mlir::detail::getDefaultFunctionPointerAlignment(
return entry.getValue();
}
+// Returns the legal int widths if specified in the given entry. If the entry is
+// empty the default legal int widths represented by an empty attribute is
+// returned.
+Attribute
+mlir::detail::getDefaultLegalIntWidths(DataLayoutEntryInterface entry) {
+ if (entry == DataLayoutEntryInterface())
+ return Attribute();
+ return entry.getValue();
+}
+
std::optional<Attribute>
mlir::detail::getDevicePropertyValue(DataLayoutEntryInterface entry) {
if (entry == DataLayoutEntryInterface())
@@ -736,6 +746,22 @@ Attribute mlir::DataLayout::getFunctionPointerAlignment() const {
return *functionPointerAlignment;
}
+Attribute mlir::DataLayout::getLegalIntWidths() const {
+ checkValid();
+ if (legalIntWidths)
+ return *legalIntWidths;
+ DataLayoutEntryInterface entry;
+ if (originalLayout)
+ entry = originalLayout.getSpecForIdentifier(
+ originalLayout.getLegalIntWidthsIdentifier(
+ originalLayout.getContext()));
+ if (auto iface = dyn_cast_or_null<DataLayoutOpInterface>(scope))
+ legalIntWidths = iface.getLegalIntWidths(entry);
+ else
+ legalIntWidths = detail::getDefaultLegalIntWidths(entry);
+ return *legalIntWidths;
+}
+
std::optional<Attribute> mlir::DataLayout::getDevicePropertyValue(
TargetSystemSpecInterface::DeviceID deviceID,
StringAttr propertyName) const {
diff --git a/mlir/lib/Target/LLVMIR/DataLayoutImporter.cpp b/mlir/lib/Target/LLVMIR/DataLayoutImporter.cpp
index 1fc36d24094bd..66568265dfce4 100644
--- a/mlir/lib/Target/LLVMIR/DataLayoutImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DataLayoutImporter.cpp
@@ -251,6 +251,30 @@ LogicalResult DataLayoutImporter::tryToEmplaceFunctionPointerAlignmentEntry(
return success();
}
+LogicalResult
+DataLayoutImporter::tryToEmplaceLegalIntWidthsEntry(StringRef token) {
+ auto key =
+ StringAttr::get(context, DLTIDialect::kDataLayoutLegalIntWidthsKey);
+ if (keyEntries.count(key))
+ return success();
+
+ FailureOr<SmallVector<uint64_t>> intWidths = tryToParseIntList(token);
+ if (failed(intWidths) || intWidths->empty())
+ return failure();
+
+ OpBuilder builder(context);
+ SmallVector<Attribute> intWidthAttrs;
+ intWidthAttrs.reserve(intWidths->size());
+ llvm::for_each(*intWidths, [&](uint64_t width) {
+ intWidthAttrs.push_back(builder.getI32IntegerAttr(width));
+ });
+
+ keyEntries.try_emplace(
+ key, DataLayoutEntryAttr::get(
+ key, ArrayAttr::get(key.getContext(), intWidthAttrs)));
+ return success();
+}
+
void DataLayoutImporter::translateDataLayout(
const llvm::DataLayout &llvmDataLayout) {
dataLayout = {};
@@ -360,6 +384,12 @@ void DataLayoutImporter::translateDataLayout(
return;
continue;
}
+ // Parse native integer widths specifications.
+ if (*prefix == "n") {
+ if (failed(tryToEmplaceLegalIntWidthsEntry(token)))
+ return;
+ continue;
+ }
// Parse function pointer alignment specifications.
// Note that prefix here is "Fn" or "Fi", not a single character.
if (prefix->starts_with("F")) {
diff --git a/mlir/lib/Target/LLVMIR/DataLayoutImporter.h b/mlir/lib/Target/LLVMIR/DataLayoutImporter.h
index 501cff89d4738..88ceaf1a74e62 100644
--- a/mlir/lib/Target/LLVMIR/DataLayoutImporter.h
+++ b/mlir/lib/Target/LLVMIR/DataLayoutImporter.h
@@ -113,6 +113,9 @@ class DataLayoutImporter {
tryToEmplaceFunctionPointerAlignmentEntry(StringRef fnPtrAlignEntry,
StringRef token);
+ /// Adds legal int widths entry if there is none yet.
+ LogicalResult tryToEmplaceLegalIntWidthsEntry(StringRef token);
+
std::string layoutStr = {};
StringRef lastToken = {};
SmallVector<StringRef> unhandledTokens;
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 047e870b7dcd8..4be8856872212 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -35,6 +35,7 @@
#include "mlir/Target/LLVMIR/TypeToLLVM.h"
#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/TypeSwitch.h"
@@ -52,6 +53,7 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
@@ -250,6 +252,17 @@ translateDataLayout(DataLayoutSpecInterface attribute,
<< alignment;
continue;
}
+ if (key.getValue() == DLTIDialect::kDataLayoutLegalIntWidthsKey) {
+ layoutStream << "-n";
+ llvm::interleave(
+ cast<ArrayAttr>(entry.getValue()).getAsValueRange<IntegerAttr>(),
+ layoutStream,
+ [&](const llvm::APInt &intWidth) {
+ layoutStream << intWidth.getZExtValue();
+ },
+ ":");
+ continue;
+ }
emitError(*loc) << "unsupported data layout key " << key;
return failure();
}
diff --git a/mlir/test/Dialect/LLVMIR/layout.mlir b/mlir/test/Dialect/LLVMIR/layout.mlir
index d7392deea67bc..998eebc503a72 100644
--- a/mlir/test/Dialect/LLVMIR/layout.mlir
+++ b/mlir/test/Dialect/LLVMIR/layout.mlir
@@ -12,6 +12,7 @@ module {
// CHECK-SAME: #dlti.function_pointer_alignment<0, function_dependent = false>,
// CHECK: global_memory_space = 0
// CHECK: index = 64
+ // CHECK: legal_int_widths = []
// CHECK: mangling_mode = ""
// CHECK: preferred = 8
// CHECK: program_memory_space = 0
@@ -27,6 +28,7 @@ module {
// CHECK-SAME: #dlti.function_pointer_alignment<0, function_dependent = false>,
// CHECK: global_memory_space = 0
// CHECK: index = 64
+ // CHECK: legal_int_widths = []
// CHECK: mangling_mode = ""
// CHECK: preferred = 8
// CHECK: program_memory_space = 0
@@ -42,6 +44,7 @@ module {
// CHECK-SAME: #dlti.function_pointer_alignment<0, function_dependent = false>,
// CHECK: global_memory_space = 0
// CHECK: index = 64
+ // CHECK: legal_int_widths = []
// CHECK: mangling_mode = ""
// CHECK: preferred = 8
// CHECK: program_memory_space = 0
@@ -65,6 +68,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<"dlti.program_memory_space", 3 : ui64>,
#dlti.dl_entry<"dlti.stack_alignment", 128 : i64>,
#dlti.dl_entry<"dlti.mangling_mode", "e">,
+ #dlti.dl_entry<"dlti.legal_int_widths", [32 : i32, 64 : i32]>,
#dlti.dl_entry<"dlti.function_pointer_alignment",
"#dlti.function_pointer_alignment<32, function_dependent = true>">
>} {
@@ -79,6 +83,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
// CHECK-SAME: "#dlti.function_pointer_alignment<32, function_dependent = true>",
// CHECK: global_memory_space = 2
// CHECK: index = 32
+ // CHECK: legal_int_widths = [32 : i32, 64 : i32]
// CHECK: mangling_mode = "e"
// CHECK: preferred = 8
// CHECK: program_memory_space = 3
@@ -94,6 +99,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
// CHECK-SAME: "#dlti.function_pointer_alignment<32, function_dependent = true>",
// CHECK: global_memory_space = 2
// CHECK: index = 32
+ // CHECK: legal_int_widths = [32 : i32, 64 : i32]
// CHECK: preferred = 8
// CHECK: program_memory_space = 3
// CHECK: size = 4
@@ -108,6 +114,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
// CHECK-SAME: "#dlti.function_pointer_alignment<32, function_dependent = true>",
// CHECK: global_memory_space = 2
// CHECK: index = 64
+ // CHECK: legal_int_widths = [32 : i32, 64 : i32]
// CHECK: mangling_mode = "e"
// CHECK: preferred = 8
// CHECK: program_memory_space = 3
@@ -123,6 +130,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
// CHECK-SAME: "#dlti.function_pointer_alignment<32, function_dependent = true>",
// CHECK: global_memory_space = 2
// CHECK: index = 24
+ // CHECK: legal_int_widths = [32 : i32, 64 : i32]
// CHECK: mangling_mode = "e"
// CHECK: preferred = 8
// CHECK: program_memory_space = 3
diff --git a/mlir/test/Target/LLVMIR/Import/data-layout.ll b/mlir/test/Target/LLVMIR/Import/data-layout.ll
index 55e3f4dea5ff4..9114a7b276095 100644
--- a/mlir/test/Target/LLVMIR/Import/data-layout.ll
+++ b/mlir/test/Target/LLVMIR/Import/data-layout.ll
@@ -29,6 +29,7 @@ target datalayout = ""
; CHECK-SAME: i8 = dense<8> : vector<2xi64>
; CHECK-SAME: "dlti.endianness" = "little"
; CHECK-SAME: "dlti.mangling_mode" = "e"
+; CHECK-SAME: "dlti.legal_int_widths" = [8 : i32, 16 : i32, 32 : i32, 64 : i32]
; CHECK-SAME: "dlti.stack_alignment" = 128 : i64
; CHECK-SAME: "dlti.function_pointer_alignment" = #dlti.function_pointer_alignment<32, function_dependent = true>
target datalayout = "e-m:e-p270:32:64-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-Fn32"
diff --git a/mlir/test/Target/LLVMIR/data-layout.mlir b/mlir/test/Target/LLVMIR/data-layout.mlir
index 30b9b03de3dbb..491f1b7b957f3 100644
--- a/mlir/test/Target/LLVMIR/data-layout.mlir
+++ b/mlir/test/Target/LLVMIR/data-layout.mlir
@@ -5,6 +5,7 @@
// CHECK: A4-
// CHECK: S128-
// CHECK: m:e-
+// CHECK: n8:16:32:64-
// CHECK: Fn32
// CHECK: i64:64:128
// CHECK: f80:128:256
@@ -15,6 +16,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<"dlti.alloca_memory_space", 4 : ui32>,
#dlti.dl_entry<"dlti.stack_alignment", 128 : i32>,
#dlti.dl_entry<"dlti.mangling_mode", "e">,
+#dlti.dl_entry<"dlti.legal_int_widths", [8 : i32, 16 : i32, 32 : i32, 64 : i32]>,
#dlti.dl_entry<"dlti.function_pointer_alignment",
#dlti.function_pointer_alignment<32, function_dependent = true>>,
#dlti.dl_entry<index, 64>,
diff --git a/mlir/test/lib/Dialect/DLTI/TestDataLayoutQuery.cpp b/mlir/test/lib/Dialect/DLTI/TestDataLayoutQuery.cpp
index 08c8042f71a95..9c6b5c81758ad 100644
--- a/mlir/test/lib/Dialect/DLTI/TestDataLayoutQuery.cpp
+++ b/mlir/test/lib/Dialect/DLTI/TestDataLayoutQuery.cpp
@@ -49,6 +49,7 @@ struct TestDataLayoutQuery
Attribute globalMemorySpace = layout.getGlobalMemorySpace();
uint64_t stackAlignment = layout.getStackAlignment();
Attribute functionPointerAlignment = layout.getFunctionPointerAlignment();
+ Attribute legalIntWidths = layout.getLegalIntWidths();
auto convertTypeSizeToAttr = [&](llvm::TypeSize typeSize) -> Attribute {
if (!typeSize.isScalable())
@@ -97,7 +98,11 @@ struct TestDataLayoutQuery
? FunctionPointerAlignmentAttr::get(
builder.getContext(), 0,
/*function_dependent=*/false)
- : functionPointerAlignment)
+ : functionPointerAlignment),
+ builder.getNamedAttr("legal_int_widths",
+ legalIntWidths == Attribute()
+ ? ArrayAttr::get(builder.getContext(), {})
+ : legalIntWidths)
});
diff --git a/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp b/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
index ea173cdad7cce..8483cc2b03d13 100644
--- a/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
+++ b/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
@@ -37,6 +37,8 @@ constexpr static llvm::StringLiteral kStackAlignmentKeyName =
"dltest.stack_alignment";
constexpr static llvm::StringLiteral kFunctionPointerAlignmentKeyName =
"dltest.function_pointer_alignment";
+constexpr static llvm::StringLiteral kLegalIntWidthsKeyName =
+ "dltest.legal_int_widths";
constexpr static llvm::StringLiteral kTargetSystemDescAttrName =
"dl_target_sys_desc_test.target_system_spec";
@@ -107,6 +109,9 @@ struct CustomDataLayoutSpec
StringAttr getFunctionPointerAlignmentIdentifier(MLIRContext *context) const {
return Builder(context).getStringAttr(kFunctionPointerAlignmentKeyName);
}
+ StringAttr getLegalIntWidthsIdentifier(MLIRContext *context) const {
+ return Builder(context).getStringAttr(kLegalIntWidthsKeyName);
+ }
FailureOr<Attribute> query(DataLayoutEntryKey key) const {
return llvm::cast<mlir::DataLayoutSpecInterface>(*this).queryHelper(key);
}
@@ -500,6 +505,7 @@ module {}
EXPECT_EQ(layout.getGlobalMemorySpace(), Attribute());
EXPECT_EQ(layout.getStackAlignment(), 0u);
EXPECT_EQ(layout.getFunctionPointerAlignment(), Attribute());
+ EXPECT_EQ(layout.getLegalIntWidths(), Attribute());
EXPECT_EQ(layout.getManglingMode(), Attribute());
}
@@ -578,6 +584,7 @@ TEST(DataLayout, EmptySpec) {
EXPECT_EQ(layout.getStackAlignment(), 0u);
EXPECT_EQ(layout.getManglingMode(), Attribute());
EXPECT_EQ(layout.getFunctionPointerAlignment(), Attribute());
+ EXPECT_EQ(layout.getLegalIntWidths(), Attribute());
EXPECT_EQ(layout.getDevicePropertyValue(
Builder(&ctx).getStringAttr("CPU" /* device ID*/),
@@ -603,7 +610,8 @@ TEST(DataLayout, SpecWithEntries) {
#dlti.dl_entry<"dltest.stack_alignment", 128 : i32>,
#dlti.dl_entry<"dltest.mangling_mode", "o">,
#dlti.dl_entry<"dltest.function_pointer_alignment",
- #dlti.function_pointer_alignment<64, function_dependent = true>>
+ #dlti.function_pointer_alignment<64, function_dependent = true>>,
+ #dlti.dl_entry<"dltest.legal_int_widths", [64 : i32]>
> } : () -> ()
)MLIR";
@@ -645,6 +653,8 @@ TEST(DataLayout, SpecWithEntries) {
EXPECT_EQ(
layout.getFunctionPointerAlignment(),
FunctionPointerAlignmentAttr::get(&ctx, 64, /*function_dependent=*/true));
+ EXPECT_EQ(layout.getLegalIntWidths(),
+ ArrayAttr::get(&ctx, {Builder(&ctx).getI32IntegerAttr(64)}));
}
TEST(DataLayout, SpecWithTargetSystemDescEntries) {
>From d56b80cecccd559ed6e07e21290e3cf757fe02c7 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Tue, 27 May 2025 12:32:16 -0700
Subject: [PATCH 2/2] address review: use dense array i32
---
mlir/lib/Target/LLVMIR/DataLayoutImporter.cpp | 24 +++++++++----------
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 8 ++-----
mlir/test/Dialect/LLVMIR/layout.mlir | 16 ++++++-------
mlir/test/Target/LLVMIR/Import/data-layout.ll | 2 +-
mlir/test/Target/LLVMIR/data-layout.mlir | 2 +-
.../lib/Dialect/DLTI/TestDataLayoutQuery.cpp | 2 +-
.../Interfaces/DataLayoutInterfacesTest.cpp | 4 ++--
7 files changed, 27 insertions(+), 31 deletions(-)
diff --git a/mlir/lib/Target/LLVMIR/DataLayoutImporter.cpp b/mlir/lib/Target/LLVMIR/DataLayoutImporter.cpp
index 66568265dfce4..5f5ca2af277c3 100644
--- a/mlir/lib/Target/LLVMIR/DataLayoutImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DataLayoutImporter.cpp
@@ -63,20 +63,25 @@ FailureOr<uint64_t> DataLayoutImporter::tryToParseInt(StringRef &token) const {
return parameter;
}
-FailureOr<SmallVector<uint64_t>>
-DataLayoutImporter::tryToParseIntList(StringRef token) const {
+template <class T>
+static FailureOr<SmallVector<T>> tryToParseIntListImpl(StringRef token) {
SmallVector<StringRef> tokens;
token.consume_front(":");
token.split(tokens, ':');
// Parse an integer list.
- SmallVector<uint64_t> results(tokens.size());
+ SmallVector<T> results(tokens.size());
for (auto [result, token] : llvm::zip(results, tokens))
if (token.getAsInteger(/*Radix=*/10, result))
return failure();
return results;
}
+FailureOr<SmallVector<uint64_t>>
+DataLayoutImporter::tryToParseIntList(StringRef token) const {
+ return tryToParseIntListImpl<uint64_t>(token);
+}
+
FailureOr<DenseIntElementsAttr>
DataLayoutImporter::tryToParseAlignment(StringRef token) const {
FailureOr<SmallVector<uint64_t>> alignment = tryToParseIntList(token);
@@ -258,20 +263,15 @@ DataLayoutImporter::tryToEmplaceLegalIntWidthsEntry(StringRef token) {
if (keyEntries.count(key))
return success();
- FailureOr<SmallVector<uint64_t>> intWidths = tryToParseIntList(token);
+ FailureOr<SmallVector<int32_t>> intWidths =
+ tryToParseIntListImpl<int32_t>(token);
if (failed(intWidths) || intWidths->empty())
return failure();
OpBuilder builder(context);
- SmallVector<Attribute> intWidthAttrs;
- intWidthAttrs.reserve(intWidths->size());
- llvm::for_each(*intWidths, [&](uint64_t width) {
- intWidthAttrs.push_back(builder.getI32IntegerAttr(width));
- });
-
keyEntries.try_emplace(
- key, DataLayoutEntryAttr::get(
- key, ArrayAttr::get(key.getContext(), intWidthAttrs)));
+ key,
+ DataLayoutEntryAttr::get(key, builder.getDenseI32ArrayAttr(*intWidths)));
return success();
}
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 4be8856872212..e3264985ecd6e 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -255,12 +255,8 @@ translateDataLayout(DataLayoutSpecInterface attribute,
if (key.getValue() == DLTIDialect::kDataLayoutLegalIntWidthsKey) {
layoutStream << "-n";
llvm::interleave(
- cast<ArrayAttr>(entry.getValue()).getAsValueRange<IntegerAttr>(),
- layoutStream,
- [&](const llvm::APInt &intWidth) {
- layoutStream << intWidth.getZExtValue();
- },
- ":");
+ cast<DenseI32ArrayAttr>(entry.getValue()).asArrayRef(), layoutStream,
+ [&](int32_t val) { layoutStream << val; }, ":");
continue;
}
emitError(*loc) << "unsupported data layout key " << key;
diff --git a/mlir/test/Dialect/LLVMIR/layout.mlir b/mlir/test/Dialect/LLVMIR/layout.mlir
index 998eebc503a72..aa1744b6d7720 100644
--- a/mlir/test/Dialect/LLVMIR/layout.mlir
+++ b/mlir/test/Dialect/LLVMIR/layout.mlir
@@ -12,7 +12,7 @@ module {
// CHECK-SAME: #dlti.function_pointer_alignment<0, function_dependent = false>,
// CHECK: global_memory_space = 0
// CHECK: index = 64
- // CHECK: legal_int_widths = []
+ // CHECK: legal_int_widths = array<i32>
// CHECK: mangling_mode = ""
// CHECK: preferred = 8
// CHECK: program_memory_space = 0
@@ -28,7 +28,7 @@ module {
// CHECK-SAME: #dlti.function_pointer_alignment<0, function_dependent = false>,
// CHECK: global_memory_space = 0
// CHECK: index = 64
- // CHECK: legal_int_widths = []
+ // CHECK: legal_int_widths = array<i32>
// CHECK: mangling_mode = ""
// CHECK: preferred = 8
// CHECK: program_memory_space = 0
@@ -44,7 +44,7 @@ module {
// CHECK-SAME: #dlti.function_pointer_alignment<0, function_dependent = false>,
// CHECK: global_memory_space = 0
// CHECK: index = 64
- // CHECK: legal_int_widths = []
+ // CHECK: legal_int_widths = array<i32>
// CHECK: mangling_mode = ""
// CHECK: preferred = 8
// CHECK: program_memory_space = 0
@@ -68,7 +68,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<"dlti.program_memory_space", 3 : ui64>,
#dlti.dl_entry<"dlti.stack_alignment", 128 : i64>,
#dlti.dl_entry<"dlti.mangling_mode", "e">,
- #dlti.dl_entry<"dlti.legal_int_widths", [32 : i32, 64 : i32]>,
+ #dlti.dl_entry<"dlti.legal_int_widths", array<i32: 32, 64>>,
#dlti.dl_entry<"dlti.function_pointer_alignment",
"#dlti.function_pointer_alignment<32, function_dependent = true>">
>} {
@@ -83,7 +83,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
// CHECK-SAME: "#dlti.function_pointer_alignment<32, function_dependent = true>",
// CHECK: global_memory_space = 2
// CHECK: index = 32
- // CHECK: legal_int_widths = [32 : i32, 64 : i32]
+ // CHECK: legal_int_widths = array<i32: 32, 64>
// CHECK: mangling_mode = "e"
// CHECK: preferred = 8
// CHECK: program_memory_space = 3
@@ -99,7 +99,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
// CHECK-SAME: "#dlti.function_pointer_alignment<32, function_dependent = true>",
// CHECK: global_memory_space = 2
// CHECK: index = 32
- // CHECK: legal_int_widths = [32 : i32, 64 : i32]
+ // CHECK: legal_int_widths = array<i32: 32, 64>
// CHECK: preferred = 8
// CHECK: program_memory_space = 3
// CHECK: size = 4
@@ -114,7 +114,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
// CHECK-SAME: "#dlti.function_pointer_alignment<32, function_dependent = true>",
// CHECK: global_memory_space = 2
// CHECK: index = 64
- // CHECK: legal_int_widths = [32 : i32, 64 : i32]
+ // CHECK: legal_int_widths = array<i32: 32, 64>
// CHECK: mangling_mode = "e"
// CHECK: preferred = 8
// CHECK: program_memory_space = 3
@@ -130,7 +130,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
// CHECK-SAME: "#dlti.function_pointer_alignment<32, function_dependent = true>",
// CHECK: global_memory_space = 2
// CHECK: index = 24
- // CHECK: legal_int_widths = [32 : i32, 64 : i32]
+ // CHECK: legal_int_widths = array<i32: 32, 64>
// CHECK: mangling_mode = "e"
// CHECK: preferred = 8
// CHECK: program_memory_space = 3
diff --git a/mlir/test/Target/LLVMIR/Import/data-layout.ll b/mlir/test/Target/LLVMIR/Import/data-layout.ll
index 9114a7b276095..a8ad4bdf2ff84 100644
--- a/mlir/test/Target/LLVMIR/Import/data-layout.ll
+++ b/mlir/test/Target/LLVMIR/Import/data-layout.ll
@@ -29,7 +29,7 @@ target datalayout = ""
; CHECK-SAME: i8 = dense<8> : vector<2xi64>
; CHECK-SAME: "dlti.endianness" = "little"
; CHECK-SAME: "dlti.mangling_mode" = "e"
-; CHECK-SAME: "dlti.legal_int_widths" = [8 : i32, 16 : i32, 32 : i32, 64 : i32]
+; CHECK-SAME: "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>
; CHECK-SAME: "dlti.stack_alignment" = 128 : i64
; CHECK-SAME: "dlti.function_pointer_alignment" = #dlti.function_pointer_alignment<32, function_dependent = true>
target datalayout = "e-m:e-p270:32:64-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-Fn32"
diff --git a/mlir/test/Target/LLVMIR/data-layout.mlir b/mlir/test/Target/LLVMIR/data-layout.mlir
index 491f1b7b957f3..deaed332a969b 100644
--- a/mlir/test/Target/LLVMIR/data-layout.mlir
+++ b/mlir/test/Target/LLVMIR/data-layout.mlir
@@ -16,7 +16,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<"dlti.alloca_memory_space", 4 : ui32>,
#dlti.dl_entry<"dlti.stack_alignment", 128 : i32>,
#dlti.dl_entry<"dlti.mangling_mode", "e">,
-#dlti.dl_entry<"dlti.legal_int_widths", [8 : i32, 16 : i32, 32 : i32, 64 : i32]>,
+#dlti.dl_entry<"dlti.legal_int_widths", array<i32: 8, 16, 32, 64>>,
#dlti.dl_entry<"dlti.function_pointer_alignment",
#dlti.function_pointer_alignment<32, function_dependent = true>>,
#dlti.dl_entry<index, 64>,
diff --git a/mlir/test/lib/Dialect/DLTI/TestDataLayoutQuery.cpp b/mlir/test/lib/Dialect/DLTI/TestDataLayoutQuery.cpp
index 9c6b5c81758ad..58c77cb94b47f 100644
--- a/mlir/test/lib/Dialect/DLTI/TestDataLayoutQuery.cpp
+++ b/mlir/test/lib/Dialect/DLTI/TestDataLayoutQuery.cpp
@@ -101,7 +101,7 @@ struct TestDataLayoutQuery
: functionPointerAlignment),
builder.getNamedAttr("legal_int_widths",
legalIntWidths == Attribute()
- ? ArrayAttr::get(builder.getContext(), {})
+ ? builder.getDenseI32ArrayAttr({})
: legalIntWidths)
});
diff --git a/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp b/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
index 8483cc2b03d13..3067cf103590c 100644
--- a/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
+++ b/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
@@ -611,7 +611,7 @@ TEST(DataLayout, SpecWithEntries) {
#dlti.dl_entry<"dltest.mangling_mode", "o">,
#dlti.dl_entry<"dltest.function_pointer_alignment",
#dlti.function_pointer_alignment<64, function_dependent = true>>,
- #dlti.dl_entry<"dltest.legal_int_widths", [64 : i32]>
+ #dlti.dl_entry<"dltest.legal_int_widths", array<i32: 64>>
> } : () -> ()
)MLIR";
@@ -654,7 +654,7 @@ TEST(DataLayout, SpecWithEntries) {
layout.getFunctionPointerAlignment(),
FunctionPointerAlignmentAttr::get(&ctx, 64, /*function_dependent=*/true));
EXPECT_EQ(layout.getLegalIntWidths(),
- ArrayAttr::get(&ctx, {Builder(&ctx).getI32IntegerAttr(64)}));
+ Builder(&ctx).getDenseI32ArrayAttr({64}));
}
TEST(DataLayout, SpecWithTargetSystemDescEntries) {
More information about the Mlir-commits
mailing list