[mlir] [llvm] [mlir] use TypeSize and uint64_t in DataLayout (PR #72874)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 20 06:13:52 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-linalg
@llvm/pr-subscribers-mlir
Author: Oleksandr "Alex" Zinenko (ftynse)
<details>
<summary>Changes</summary>
Data layout queries may be issued for types whose size exceeds the range of 32-bit integer as well as for types that don't have a size known at compile time, such as scalable vectors. Use best practices from LLVM IR and adopt `llvm::TypeSize` for size-related queries and `uint64_t` for alignment-related queries.
See #<!-- -->72678.
---
Patch is 70.48 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/72874.diff
21 Files Affected:
- (modified) llvm/include/llvm/Support/TypeSize.h (+8)
- (modified) mlir/docs/DataLayout.md (+4-4)
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h (+5-5)
- (modified) mlir/include/mlir/Interfaces/DataLayoutInterfaces.h (+24-19)
- (modified) mlir/include/mlir/Interfaces/DataLayoutInterfaces.td (+13-13)
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp (+53-46)
- (modified) mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp (+4-3)
- (modified) mlir/lib/Interfaces/DataLayoutInterfaces.cpp (+58-45)
- (modified) mlir/lib/Target/LLVMIR/DataLayoutImporter.cpp (+25-22)
- (modified) mlir/lib/Target/LLVMIR/DataLayoutImporter.h (+2-2)
- (modified) mlir/lib/Target/LLVMIR/ModuleTranslation.cpp (+12-12)
- (modified) mlir/test/Conversion/MemRefToLLVM/convert-dynamic-memref-ops.mlir (+2-2)
- (modified) mlir/test/Dialect/LLVMIR/dynamic-gep-index.mlir (+10-1)
- (modified) mlir/test/Dialect/LLVMIR/layout.mlir (+31-13)
- (modified) mlir/test/Interfaces/DataLayoutInterfaces/query.mlir (+8-8)
- (modified) mlir/test/Interfaces/DataLayoutInterfaces/types.mlir (+4-4)
- (modified) mlir/test/Target/LLVMIR/Import/data-layout.ll (+20-20)
- (modified) mlir/test/Target/LLVMIR/data-layout.mlir (+7-7)
- (modified) mlir/test/lib/Dialect/Test/TestTypeDefs.td (+1-1)
- (modified) mlir/test/lib/Dialect/Test/TestTypes.cpp (+6-5)
- (modified) mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp (+17-15)
``````````diff
diff --git a/llvm/include/llvm/Support/TypeSize.h b/llvm/include/llvm/Support/TypeSize.h
index 8e638f8278e828b..6afda46dd9eb69a 100644
--- a/llvm/include/llvm/Support/TypeSize.h
+++ b/llvm/include/llvm/Support/TypeSize.h
@@ -244,6 +244,14 @@ template <typename LeafTy, typename ValueTy> class FixedOrScalableQuantity {
isScalable());
}
+ /// Returns a value X where the known coefficient will be rounded up to the
+ /// closest power-of-two, except for the zero coefficient that remains zero.
+ constexpr LeafTy coefficientPowerOf2Ceil() const {
+ return LeafTy::get(
+ static_cast<ScalarTy>(llvm::PowerOf2Ceil(getKnownMinValue())),
+ isScalable());
+ }
+
/// Returns true if there exists a value X where RHS.multiplyCoefficientBy(X)
/// will result in a value whose quantity matches our own.
constexpr bool
diff --git a/mlir/docs/DataLayout.md b/mlir/docs/DataLayout.md
index e246e66c7fe227b..b9dde30519d6eda 100644
--- a/mlir/docs/DataLayout.md
+++ b/mlir/docs/DataLayout.md
@@ -73,10 +73,10 @@ class DataLayout {
public:
explicit DataLayout(DataLayoutOpInterface scope);
- unsigned getTypeSize(Type type) const;
- unsigned getTypeSizeInBits(Type type) const;
- unsigned getTypeABIAlignment(Type type) const;
- unsigned getTypePreferredAlignment(Type type) const;
+ llvm::TypeSize getTypeSize(Type type) const;
+ llvm::TypeSize getTypeSizeInBits(Type type) const;
+ uint64_t getTypeABIAlignment(Type type) const;
+ uint64_t getTypePreferredAlignment(Type type) const;
};
```
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
index ba2f14f173aa0c3..06a41c7c1a72459 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
@@ -186,13 +186,13 @@ class LLVMStructType
/// Hooks for DataLayoutTypeInterface. Should not be called directly. Obtain a
/// DataLayout instance and query it instead.
- unsigned getTypeSizeInBits(const DataLayout &dataLayout,
- DataLayoutEntryListRef params) const;
+ llvm::TypeSize getTypeSizeInBits(const DataLayout &dataLayout,
+ DataLayoutEntryListRef params) const;
- unsigned getABIAlignment(const DataLayout &dataLayout,
+ uint64_t getABIAlignment(const DataLayout &dataLayout,
DataLayoutEntryListRef params) const;
- unsigned getPreferredAlignment(const DataLayout &dataLayout,
+ uint64_t getPreferredAlignment(const DataLayout &dataLayout,
DataLayoutEntryListRef params) const;
bool areCompatible(DataLayoutEntryListRef oldLayout,
@@ -288,7 +288,7 @@ enum class PtrDLEntryPos { Size = 0, Abi = 1, Preferred = 2, Index = 3 };
/// Returns `std::nullopt` if `pos` is not present in the entry.
/// Currently only `PtrDLEntryPos::Index` is optional, and all other positions
/// may be assumed to be present.
-std::optional<unsigned> extractPointerSpecValue(Attribute attr,
+std::optional<uint64_t> extractPointerSpecValue(Attribute attr,
PtrDLEntryPos pos);
} // namespace LLVM
diff --git a/mlir/include/mlir/Interfaces/DataLayoutInterfaces.h b/mlir/include/mlir/Interfaces/DataLayoutInterfaces.h
index e6e31d171c6a9fd..f4b9b95fb89f89f 100644
--- a/mlir/include/mlir/Interfaces/DataLayoutInterfaces.h
+++ b/mlir/include/mlir/Interfaces/DataLayoutInterfaces.h
@@ -18,6 +18,7 @@
#include "mlir/IR/DialectInterface.h"
#include "mlir/IR/OpDefinition.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/TypeSize.h"
namespace mlir {
class DataLayout;
@@ -34,25 +35,25 @@ class ModuleOp;
namespace detail {
/// Default handler for the type size request. Computes results for built-in
/// types and dispatches to the DataLayoutTypeInterface for other types.
-unsigned getDefaultTypeSize(Type type, const DataLayout &dataLayout,
- DataLayoutEntryListRef params);
+llvm::TypeSize getDefaultTypeSize(Type type, const DataLayout &dataLayout,
+ DataLayoutEntryListRef params);
/// Default handler for the type size in bits request. Computes results for
/// built-in types and dispatches to the DataLayoutTypeInterface for other
/// types.
-unsigned getDefaultTypeSizeInBits(Type type, const DataLayout &dataLayout,
- DataLayoutEntryListRef params);
+llvm::TypeSize getDefaultTypeSizeInBits(Type type, const DataLayout &dataLayout,
+ DataLayoutEntryListRef params);
-/// Default handler for the required alignemnt request. Computes results for
+/// Default handler for the required alignment request. Computes results for
/// built-in types and dispatches to the DataLayoutTypeInterface for other
/// types.
-unsigned getDefaultABIAlignment(Type type, const DataLayout &dataLayout,
+uint64_t getDefaultABIAlignment(Type type, const DataLayout &dataLayout,
ArrayRef<DataLayoutEntryInterface> params);
-/// Default handler for the preferred alignemnt request. Computes results for
+/// Default handler for the preferred alignment request. Computes results for
/// built-in types and dispatches to the DataLayoutTypeInterface for other
/// types.
-unsigned
+uint64_t
getDefaultPreferredAlignment(Type type, const DataLayout &dataLayout,
ArrayRef<DataLayoutEntryInterface> params);
@@ -62,7 +63,7 @@ Attribute getDefaultAllocaMemorySpace(DataLayoutEntryInterface entry);
/// Default handler for the stack alignment request. Dispatches to the
/// DataLayoutInterface if specified, otherwise returns the default.
-unsigned getDefaultStackAlignment(DataLayoutEntryInterface entry);
+uint64_t getDefaultStackAlignment(DataLayoutEntryInterface entry);
/// Given a list of data layout entries, returns a new list containing the
/// entries with keys having the given type ID, i.e. belonging to the same type
@@ -85,6 +86,10 @@ LogicalResult verifyDataLayoutOp(Operation *op);
/// entry verifiers, and then to the verifiers implemented by the relevant type
/// and dialect interfaces for type and identifier keys respectively.
LogicalResult verifyDataLayoutSpec(DataLayoutSpecInterface spec, Location loc);
+
+/// Divides the known min value of the numerator by the denominator and rounds
+/// the result up to the next integer. Preserves the scalable flag.
+llvm::TypeSize divideCeil(llvm::TypeSize numerator, uint64_t denominator);
} // namespace detail
} // namespace mlir
@@ -156,16 +161,16 @@ class DataLayout {
static DataLayout closest(Operation *op);
/// Returns the size of the given type in the current scope.
- unsigned getTypeSize(Type t) const;
+ llvm::TypeSize getTypeSize(Type t) const;
/// Returns the size in bits of the given type in the current scope.
- unsigned getTypeSizeInBits(Type t) const;
+ llvm::TypeSize getTypeSizeInBits(Type t) const;
/// Returns the required alignment of the given type in the current scope.
- unsigned getTypeABIAlignment(Type t) const;
+ uint64_t getTypeABIAlignment(Type t) const;
/// Returns the preferred of the given type in the current scope.
- unsigned getTypePreferredAlignment(Type t) const;
+ uint64_t getTypePreferredAlignment(Type t) const;
/// Returns the memory space used for AllocaOps.
Attribute getAllocaMemorySpace() const;
@@ -174,7 +179,7 @@ class DataLayout {
/// stack variables should be limited to the natural stack alignment to
/// prevent dynamic stack alignment. Returns zero if the stack alignment is
/// unspecified.
- unsigned getStackAlignment() const;
+ uint64_t getStackAlignment() const;
private:
/// Combined layout spec at the given scope.
@@ -193,16 +198,16 @@ class DataLayout {
Operation *scope;
/// Caches for individual requests.
- mutable DenseMap<Type, unsigned> sizes;
- mutable DenseMap<Type, unsigned> bitsizes;
- mutable DenseMap<Type, unsigned> abiAlignments;
- mutable DenseMap<Type, unsigned> preferredAlignments;
+ mutable DenseMap<Type, llvm::TypeSize> sizes;
+ mutable DenseMap<Type, llvm::TypeSize> bitsizes;
+ mutable DenseMap<Type, uint64_t> abiAlignments;
+ mutable DenseMap<Type, uint64_t> preferredAlignments;
/// Cache for alloca memory space.
mutable std::optional<Attribute> allocaMemorySpace;
/// Cache for stack alignment.
- mutable std::optional<unsigned> stackAlignment;
+ mutable std::optional<uint64_t> stackAlignment;
};
} // namespace mlir
diff --git a/mlir/include/mlir/Interfaces/DataLayoutInterfaces.td b/mlir/include/mlir/Interfaces/DataLayoutInterfaces.td
index bac8c23ceec01ad..2f60a16baf50bca 100644
--- a/mlir/include/mlir/Interfaces/DataLayoutInterfaces.td
+++ b/mlir/include/mlir/Interfaces/DataLayoutInterfaces.td
@@ -213,22 +213,22 @@ def DataLayoutOpInterface : OpInterface<"DataLayoutOpInterface"> {
/*description=*/"Returns the size of the given type computed using the "
"relevant entries. The data layout object can be used "
"for recursive queries.",
- /*retTy=*/"unsigned",
+ /*retTy=*/"::llvm::TypeSize",
/*methodName=*/"getTypeSize",
/*args=*/(ins "::mlir::Type":$type,
"const ::mlir::DataLayout &":$dataLayout,
"::mlir::DataLayoutEntryListRef":$params),
/*methodBody=*/"",
/*defaultImplementation=*/[{
- unsigned bits = ConcreteOp::getTypeSizeInBits(type, dataLayout, params);
- return ::llvm::divideCeil(bits, 8);
+ ::llvm::TypeSize bits = ConcreteOp::getTypeSizeInBits(type, dataLayout, params);
+ return ::mlir::detail::divideCeil(bits, 8u);
}]
>,
StaticInterfaceMethod<
/*description=*/"Returns the size of the given type in bits computed "
"using the relevant entries. The data layout object can "
"be used for recursive queries.",
- /*retTy=*/"unsigned",
+ /*retTy=*/"::llvm::TypeSize",
/*methodName=*/"getTypeSizeInBits",
/*args=*/(ins "::mlir::Type":$type,
"const ::mlir::DataLayout &":$dataLayout,
@@ -243,7 +243,7 @@ def DataLayoutOpInterface : OpInterface<"DataLayoutOpInterface"> {
/*description=*/"Returns the alignment required by the ABI for the given "
"type computed using the relevant entries. The data "
"layout object can be used for recursive queries.",
- /*retTy=*/"unsigned",
+ /*retTy=*/"uint64_t",
/*methodName=*/"getTypeABIAlignment",
/*args=*/(ins "::mlir::Type":$type,
"const ::mlir::DataLayout &":$dataLayout,
@@ -257,7 +257,7 @@ def DataLayoutOpInterface : OpInterface<"DataLayoutOpInterface"> {
/*description=*/"Returns the alignment preferred by the given type "
"computed using the relevant entries. The data layout"
"object can be used for recursive queries.",
- /*retTy=*/"unsigned",
+ /*retTy=*/"uint64_t",
/*methodName=*/"getTypePreferredAlignment",
/*args=*/(ins "::mlir::Type":$type,
"const ::mlir::DataLayout &":$dataLayout,
@@ -284,7 +284,7 @@ def DataLayoutOpInterface : OpInterface<"DataLayoutOpInterface"> {
/*description=*/"Returns the natural stack alignment in bits computed "
"using the relevant entries. The data layout object "
"can be used for recursive queries.",
- /*retTy=*/"unsigned",
+ /*retTy=*/"uint64_t",
/*methodName=*/"getStackAlignment",
/*args=*/(ins "::mlir::DataLayoutEntryInterface":$entry),
/*methodBody=*/"",
@@ -331,19 +331,19 @@ def DataLayoutTypeInterface : TypeInterface<"DataLayoutTypeInterface"> {
let methods = [
InterfaceMethod<
/*description=*/"Returns the size of this type in bytes.",
- /*retTy=*/"unsigned",
+ /*retTy=*/"::llvm::TypeSize",
/*methodName=*/"getTypeSize",
/*args=*/(ins "const ::mlir::DataLayout &":$dataLayout,
"::mlir::DataLayoutEntryListRef":$params),
/*methodBody=*/"",
/*defaultImplementation=*/[{
- unsigned bits = $_type.getTypeSizeInBits(dataLayout, params);
- return ::llvm::divideCeil(bits, 8);
+ ::llvm::TypeSize bits = $_type.getTypeSizeInBits(dataLayout, params);
+ return ::mlir::detail::divideCeil(bits, 8u);
}]
>,
InterfaceMethod<
/*description=*/"Returns the size of this type in bits.",
- /*retTy=*/"unsigned",
+ /*retTy=*/"::llvm::TypeSize",
/*methodName=*/"getTypeSizeInBits",
/*args=*/(ins "const ::mlir::DataLayout &":$dataLayout,
"::mlir::DataLayoutEntryListRef":$params)
@@ -351,7 +351,7 @@ def DataLayoutTypeInterface : TypeInterface<"DataLayoutTypeInterface"> {
InterfaceMethod<
/*description=*/"Returns the ABI-required alignment for this type, "
"in bytes",
- /*retTy=*/"unsigned",
+ /*retTy=*/"uint64_t",
/*methodName=*/"getABIAlignment",
/*args=*/(ins "const ::mlir::DataLayout &":$dataLayout,
"::mlir::DataLayoutEntryListRef":$params)
@@ -359,7 +359,7 @@ def DataLayoutTypeInterface : TypeInterface<"DataLayoutTypeInterface"> {
InterfaceMethod<
/*description=*/"Returns the preferred alignment for this type, "
"in bytes.",
- /*retTy=*/"unsigned",
+ /*retTy=*/"uint64_t",
/*methodName=*/"getPreferredAlignment",
/*args=*/(ins "const ::mlir::DataLayout &":$dataLayout,
"::mlir::DataLayoutEntryListRef":$params)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
index 8841aa8362569a0..f4aa939791588da 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
@@ -27,7 +27,7 @@
using namespace mlir;
using namespace mlir::LLVM;
-constexpr const static unsigned kBitsInByte = 8;
+constexpr const static uint64_t kBitsInByte = 8;
//===----------------------------------------------------------------------===//
// custom<FunctionTypes>
@@ -178,24 +178,25 @@ LLVMArrayType::verify(function_ref<InFlightDiagnostic()> emitError,
//===----------------------------------------------------------------------===//
// DataLayoutTypeInterface
-unsigned LLVMArrayType::getTypeSizeInBits(const DataLayout &dataLayout,
- DataLayoutEntryListRef params) const {
- return kBitsInByte * getTypeSize(dataLayout, params);
+llvm::TypeSize
+LLVMArrayType::getTypeSizeInBits(const DataLayout &dataLayout,
+ DataLayoutEntryListRef params) const {
+ return llvm::TypeSize::Fixed(kBitsInByte * getTypeSize(dataLayout, params));
}
-unsigned LLVMArrayType::getTypeSize(const DataLayout &dataLayout,
- DataLayoutEntryListRef params) const {
+llvm::TypeSize LLVMArrayType::getTypeSize(const DataLayout &dataLayout,
+ DataLayoutEntryListRef params) const {
return llvm::alignTo(dataLayout.getTypeSize(getElementType()),
dataLayout.getTypeABIAlignment(getElementType())) *
getNumElements();
}
-unsigned LLVMArrayType::getABIAlignment(const DataLayout &dataLayout,
+uint64_t LLVMArrayType::getABIAlignment(const DataLayout &dataLayout,
DataLayoutEntryListRef params) const {
return dataLayout.getTypeABIAlignment(getElementType());
}
-unsigned
+uint64_t
LLVMArrayType::getPreferredAlignment(const DataLayout &dataLayout,
DataLayoutEntryListRef params) const {
return dataLayout.getTypePreferredAlignment(getElementType());
@@ -254,23 +255,23 @@ LLVMFunctionType::verify(function_ref<InFlightDiagnostic()> emitError,
//===----------------------------------------------------------------------===//
// DataLayoutTypeInterface
-constexpr const static unsigned kDefaultPointerSizeBits = 64;
-constexpr const static unsigned kDefaultPointerAlignment = 8;
+constexpr const static uint64_t kDefaultPointerSizeBits = 64;
+constexpr const static uint64_t kDefaultPointerAlignment = 8;
-std::optional<unsigned> mlir::LLVM::extractPointerSpecValue(Attribute attr,
+std::optional<uint64_t> mlir::LLVM::extractPointerSpecValue(Attribute attr,
PtrDLEntryPos pos) {
- auto spec = llvm::cast<DenseIntElementsAttr>(attr);
- auto idx = static_cast<unsigned>(pos);
+ auto spec = cast<DenseIntElementsAttr>(attr);
+ auto idx = static_cast<int64_t>(pos);
if (idx >= spec.size())
return std::nullopt;
- return spec.getValues<unsigned>()[idx];
+ return spec.getValues<uint64_t>()[idx];
}
/// Returns the part of the data layout entry that corresponds to `pos` for the
/// given `type` by interpreting the list of entries `params`. For the pointer
/// type in the default address space, returns the default value if the entries
/// do not provide a custom one, for other address spaces returns std::nullopt.
-static std::optional<unsigned>
+static std::optional<uint64_t>
getPointerDataLayoutEntry(DataLayoutEntryListRef params, LLVMPointerType type,
PtrDLEntryPos pos) {
// First, look for the entry for the pointer in the current address space.
@@ -278,8 +279,8 @@ getPointerDataLayoutEntry(DataLayoutEntryListRef params, LLVMPointerType type,
for (DataLayoutEntryInterface entry : params) {
if (!entry.isTypeEntry())
continue;
- if (llvm::cast<LLVMPointerType>(entry.getKey().get<Type>())
- .getAddressSpace() == type.getAddressSpace()) {
+ if (cast<LLVMPointerType>(entry.getKey().get<Type>()).getAddressSpace() ==
+ type.getAddressSpace()) {
currentEntry = entry.getValue();
break;
}
@@ -299,31 +300,31 @@ getPointerDataLayoutEntry(DataLayoutEntryListRef params, LLVMPointerType type,
return std::nullopt;
}
-unsigned
+llvm::TypeSize
LLVMPointerType::getTypeSizeInBits(const DataLayout &dataLayout,
DataLayoutEntryListRef params) const {
- if (std::optional<unsigned> size =
+ if (std::optional<uint64_t> size =
getPointerDataLayoutEntry(params, *this, PtrDLEntryPos::Size))
- return *size;
+ return llvm::TypeSize::Fixed(*size);
// For other memory spaces, use the size of the pointer to the default memory
// space.
return dataLayout.getTypeSizeInBits(get(getContext()));
}
-unsigned LLVMPointerType::getABIAlignment(const DataLayout &dataLayout,
+uint64_t LLVMPointerType::getABIAlignment(const DataLayout &dataLayout,
DataLayoutEntryListRef params) const {
- if (std::optional<unsigned> alignment =
+ if (std::optional<uint64_t> alignment =
getPointerDataLayoutEntry(params, *this, PtrDLEntryPos::Abi))
return *alignment;
return dataLayout.getTypeABIAlignment(get(getContext()));
}
-unsigned
+uint64_t
LLVMPointerType::getPreferredAlignment(const DataLayout &dataLayout,
DataLayoutEntryListRef params) const {
- if (std::optional<unsigned> alignment =
+ if (std::optional<uint64_t> alignment =
getPointerDataLayoutEntry(params, *this, PtrDLEntryPos::Preferred))
return *alignment;
@@ -335,8 +336,8 @@ bool LLVMPointerType::areCompatible(DataLayoutEntryListRef oldLayout,
for (DataLayoutEntryInterface newEntry : newLayout) {
if (!newEntry.isTypeEntry())
continue;
- unsigned size = kDefaultPointerSizeBits;
- unsigned abi = kDefaultPointerAlignment;
+ uint64_t size = kDefaultPointerSizeBits;
+ uint64_t abi = kDefaultPointerAlignment;
auto newType = llvm::cast<LLVMPointerType>(newEntry.getKey().get<Type>());
const auto *it =
llvm::find_if(oldLayout, [&](DataLayoutEntryInterface entry) {
@@ -360,8 +361,8 @@ bool LLVMPointerType::areCompatible(DataLayoutEntryListRef oldLayout,
}
Attribute newSpec = llvm::cast<DenseIntElementsAttr>(newEntry.getValue());
- unsigned newSize = *extractPointerSpecValue(newSpec, PtrDLEntryPos::Size);
- unsigned newAbi = *extractPointerSpecValue(newSpec, PtrDLEntryPos::Abi);
+ uint64_t newSize = *extr...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/72874
More information about the llvm-commits
mailing list