mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 13:50:11 +00:00
[mlir] use TypeSize and uint64_t in DataLayout (#72874)
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.
This commit is contained in:
parent
49f0070237
commit
8134a8fc3f
@ -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;
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -186,13 +186,13 @@ public:
|
||||
|
||||
/// 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
|
||||
|
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
/// 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 @@ private:
|
||||
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
|
||||
|
@ -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)
|
||||
|
@ -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 = *extractPointerSpecValue(newSpec, PtrDLEntryPos::Size);
|
||||
uint64_t newAbi = *extractPointerSpecValue(newSpec, PtrDLEntryPos::Abi);
|
||||
if (size != newSize || abi < newAbi || abi % newAbi != 0)
|
||||
return false;
|
||||
}
|
||||
@ -373,13 +374,17 @@ LogicalResult LLVMPointerType::verifyEntries(DataLayoutEntryListRef entries,
|
||||
for (DataLayoutEntryInterface entry : entries) {
|
||||
if (!entry.isTypeEntry())
|
||||
continue;
|
||||
auto key = entry.getKey().get<Type>();
|
||||
auto values = llvm::dyn_cast<DenseIntElementsAttr>(entry.getValue());
|
||||
if (!values || (values.size() != 3 && values.size() != 4)) {
|
||||
return emitError(loc)
|
||||
<< "expected layout attribute for " << entry.getKey().get<Type>()
|
||||
<< "expected layout attribute for " << key
|
||||
<< " to be a dense integer elements attribute with 3 or 4 "
|
||||
"elements";
|
||||
}
|
||||
if (!values.getElementType().isInteger(64))
|
||||
return emitError(loc) << "expected i64 parameters for " << key;
|
||||
|
||||
if (extractPointerSpecValue(values, PtrDLEntryPos::Abi) >
|
||||
extractPointerSpecValue(values, PtrDLEntryPos::Preferred)) {
|
||||
return emitError(loc) << "preferred alignment is expected to be at least "
|
||||
@ -484,16 +489,16 @@ LLVMStructType::verify(function_ref<InFlightDiagnostic()> emitError,
|
||||
return success();
|
||||
}
|
||||
|
||||
unsigned
|
||||
llvm::TypeSize
|
||||
LLVMStructType::getTypeSizeInBits(const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params) const {
|
||||
unsigned structSize = 0;
|
||||
unsigned structAlignment = 1;
|
||||
auto structSize = llvm::TypeSize::Fixed(0);
|
||||
uint64_t structAlignment = 1;
|
||||
for (Type element : getBody()) {
|
||||
unsigned elementAlignment =
|
||||
uint64_t elementAlignment =
|
||||
isPacked() ? 1 : dataLayout.getTypeABIAlignment(element);
|
||||
// Add padding to the struct size to align it to the abi alignment of the
|
||||
// element type before than adding the size of the element
|
||||
// element type before than adding the size of the element.
|
||||
structSize = llvm::alignTo(structSize, elementAlignment);
|
||||
structSize += dataLayout.getTypeSize(element);
|
||||
|
||||
@ -511,7 +516,7 @@ namespace {
|
||||
enum class StructDLEntryPos { Abi = 0, Preferred = 1 };
|
||||
} // namespace
|
||||
|
||||
static std::optional<unsigned>
|
||||
static std::optional<uint64_t>
|
||||
getStructDataLayoutEntry(DataLayoutEntryListRef params, LLVMStructType type,
|
||||
StructDLEntryPos pos) {
|
||||
const auto *currentEntry =
|
||||
@ -523,14 +528,14 @@ getStructDataLayoutEntry(DataLayoutEntryListRef params, LLVMStructType type,
|
||||
|
||||
auto attr = llvm::cast<DenseIntElementsAttr>(currentEntry->getValue());
|
||||
if (pos == StructDLEntryPos::Preferred &&
|
||||
attr.size() <= static_cast<unsigned>(StructDLEntryPos::Preferred))
|
||||
attr.size() <= static_cast<int64_t>(StructDLEntryPos::Preferred))
|
||||
// If no preferred was specified, fall back to abi alignment
|
||||
pos = StructDLEntryPos::Abi;
|
||||
|
||||
return attr.getValues<unsigned>()[static_cast<unsigned>(pos)];
|
||||
return attr.getValues<uint64_t>()[static_cast<size_t>(pos)];
|
||||
}
|
||||
|
||||
static unsigned calculateStructAlignment(const DataLayout &dataLayout,
|
||||
static uint64_t calculateStructAlignment(const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params,
|
||||
LLVMStructType type,
|
||||
StructDLEntryPos pos) {
|
||||
@ -541,36 +546,36 @@ static unsigned calculateStructAlignment(const DataLayout &dataLayout,
|
||||
|
||||
// The alignment requirement of a struct is equal to the strictest alignment
|
||||
// requirement of its elements.
|
||||
unsigned structAlignment = 1;
|
||||
uint64_t structAlignment = 1;
|
||||
for (Type iter : type.getBody()) {
|
||||
structAlignment =
|
||||
std::max(dataLayout.getTypeABIAlignment(iter), structAlignment);
|
||||
}
|
||||
|
||||
// Entries are only allowed to be stricter than the required alignment
|
||||
if (std::optional<unsigned> entryResult =
|
||||
if (std::optional<uint64_t> entryResult =
|
||||
getStructDataLayoutEntry(params, type, pos))
|
||||
return std::max(*entryResult / kBitsInByte, structAlignment);
|
||||
|
||||
return structAlignment;
|
||||
}
|
||||
|
||||
unsigned LLVMStructType::getABIAlignment(const DataLayout &dataLayout,
|
||||
uint64_t LLVMStructType::getABIAlignment(const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params) const {
|
||||
return calculateStructAlignment(dataLayout, params, *this,
|
||||
StructDLEntryPos::Abi);
|
||||
}
|
||||
|
||||
unsigned
|
||||
uint64_t
|
||||
LLVMStructType::getPreferredAlignment(const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params) const {
|
||||
return calculateStructAlignment(dataLayout, params, *this,
|
||||
StructDLEntryPos::Preferred);
|
||||
}
|
||||
|
||||
static unsigned extractStructSpecValue(Attribute attr, StructDLEntryPos pos) {
|
||||
static uint64_t extractStructSpecValue(Attribute attr, StructDLEntryPos pos) {
|
||||
return llvm::cast<DenseIntElementsAttr>(attr)
|
||||
.getValues<unsigned>()[static_cast<unsigned>(pos)];
|
||||
.getValues<uint64_t>()[static_cast<size_t>(pos)];
|
||||
}
|
||||
|
||||
bool LLVMStructType::areCompatible(DataLayoutEntryListRef oldLayout,
|
||||
@ -586,9 +591,9 @@ bool LLVMStructType::areCompatible(DataLayoutEntryListRef oldLayout,
|
||||
if (previousEntry == oldLayout.end())
|
||||
continue;
|
||||
|
||||
unsigned abi = extractStructSpecValue(previousEntry->getValue(),
|
||||
uint64_t abi = extractStructSpecValue(previousEntry->getValue(),
|
||||
StructDLEntryPos::Abi);
|
||||
unsigned newAbi =
|
||||
uint64_t newAbi =
|
||||
extractStructSpecValue(newEntry.getValue(), StructDLEntryPos::Abi);
|
||||
if (abi < newAbi || abi % newAbi != 0)
|
||||
return false;
|
||||
@ -609,6 +614,8 @@ LogicalResult LLVMStructType::verifyEntries(DataLayoutEntryListRef entries,
|
||||
<< "expected layout attribute for " << entry.getKey().get<Type>()
|
||||
<< " to be a dense integer elements attribute of 1 or 2 elements";
|
||||
}
|
||||
if (!values.getElementType().isInteger(64))
|
||||
return emitError(loc) << "expected i64 entries for " << key;
|
||||
|
||||
if (key.isIdentified() || !key.getBody().empty()) {
|
||||
return emitError(loc) << "unexpected layout attribute for struct " << key;
|
||||
|
@ -49,7 +49,8 @@ static Value allocBuffer(ImplicitLocOpBuilder &b,
|
||||
const LinalgPromotionOptions &options,
|
||||
Type elementType, Value allocSize, DataLayout &layout,
|
||||
std::optional<unsigned> alignment = std::nullopt) {
|
||||
auto width = layout.getTypeSize(elementType);
|
||||
llvm::TypeSize width = layout.getTypeSize(elementType);
|
||||
assert(!width.isScalable() && "cannot allocate buffer for a scalable vector");
|
||||
|
||||
IntegerAttr alignmentAttr;
|
||||
if (alignment.has_value())
|
||||
@ -61,8 +62,8 @@ static Value allocBuffer(ImplicitLocOpBuilder &b,
|
||||
|
||||
// Static buffer.
|
||||
if (std::optional<int64_t> cst = getConstantIntValue(allocSize)) {
|
||||
auto staticBufferType =
|
||||
MemRefType::get(width * cst.value(), b.getIntegerType(8));
|
||||
auto staticBufferType = MemRefType::get(width.getFixedValue() * cst.value(),
|
||||
b.getIntegerType(8));
|
||||
staticBufferType =
|
||||
MemRefType::Builder(staticBufferType).setMemorySpace(memorySpaceAttr);
|
||||
if (options.useAlloca) {
|
||||
|
@ -34,31 +34,31 @@ using namespace mlir;
|
||||
|
||||
/// Returns the bitwidth of the index type if specified in the param list.
|
||||
/// Assumes 64-bit index otherwise.
|
||||
static unsigned getIndexBitwidth(DataLayoutEntryListRef params) {
|
||||
static uint64_t getIndexBitwidth(DataLayoutEntryListRef params) {
|
||||
if (params.empty())
|
||||
return 64;
|
||||
auto attr = cast<IntegerAttr>(params.front().getValue());
|
||||
return attr.getValue().getZExtValue();
|
||||
}
|
||||
|
||||
unsigned
|
||||
llvm::TypeSize
|
||||
mlir::detail::getDefaultTypeSize(Type type, const DataLayout &dataLayout,
|
||||
ArrayRef<DataLayoutEntryInterface> params) {
|
||||
unsigned bits = getDefaultTypeSizeInBits(type, dataLayout, params);
|
||||
return llvm::divideCeil(bits, 8);
|
||||
llvm::TypeSize bits = getDefaultTypeSizeInBits(type, dataLayout, params);
|
||||
return divideCeil(bits, 8);
|
||||
}
|
||||
|
||||
unsigned mlir::detail::getDefaultTypeSizeInBits(Type type,
|
||||
const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params) {
|
||||
llvm::TypeSize
|
||||
mlir::detail::getDefaultTypeSizeInBits(Type type, const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params) {
|
||||
if (isa<IntegerType, FloatType>(type))
|
||||
return type.getIntOrFloatBitWidth();
|
||||
return llvm::TypeSize::Fixed(type.getIntOrFloatBitWidth());
|
||||
|
||||
if (auto ctype = dyn_cast<ComplexType>(type)) {
|
||||
auto et = ctype.getElementType();
|
||||
auto innerAlignment =
|
||||
Type et = ctype.getElementType();
|
||||
uint64_t innerAlignment =
|
||||
getDefaultPreferredAlignment(et, dataLayout, params) * 8;
|
||||
auto innerSize = getDefaultTypeSizeInBits(et, dataLayout, params);
|
||||
llvm::TypeSize innerSize = getDefaultTypeSizeInBits(et, dataLayout, params);
|
||||
|
||||
// Include padding required to align the imaginary value in the complex
|
||||
// type.
|
||||
@ -102,35 +102,40 @@ findEntryForIntegerType(IntegerType intType,
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
static unsigned extractABIAlignment(DataLayoutEntryInterface entry) {
|
||||
constexpr const static uint64_t kDefaultBitsInByte = 8u;
|
||||
|
||||
static uint64_t extractABIAlignment(DataLayoutEntryInterface entry) {
|
||||
auto values =
|
||||
cast<DenseIntElementsAttr>(entry.getValue()).getValues<int32_t>();
|
||||
return *values.begin() / 8u;
|
||||
cast<DenseIntElementsAttr>(entry.getValue()).getValues<uint64_t>();
|
||||
return static_cast<uint64_t>(*values.begin()) / kDefaultBitsInByte;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
static uint64_t
|
||||
getIntegerTypeABIAlignment(IntegerType intType,
|
||||
ArrayRef<DataLayoutEntryInterface> params) {
|
||||
constexpr uint64_t kDefaultSmallIntAlignment = 4u;
|
||||
constexpr unsigned kSmallIntSize = 64;
|
||||
if (params.empty()) {
|
||||
return intType.getWidth() < 64
|
||||
? llvm::PowerOf2Ceil(llvm::divideCeil(intType.getWidth(), 8))
|
||||
: 4;
|
||||
return intType.getWidth() < kSmallIntSize
|
||||
? llvm::PowerOf2Ceil(
|
||||
llvm::divideCeil(intType.getWidth(), kDefaultBitsInByte))
|
||||
: kDefaultSmallIntAlignment;
|
||||
}
|
||||
|
||||
return extractABIAlignment(findEntryForIntegerType(intType, params));
|
||||
}
|
||||
|
||||
static unsigned
|
||||
static uint64_t
|
||||
getFloatTypeABIAlignment(FloatType fltType, const DataLayout &dataLayout,
|
||||
ArrayRef<DataLayoutEntryInterface> params) {
|
||||
assert(params.size() <= 1 && "at most one data layout entry is expected for "
|
||||
"the singleton floating-point type");
|
||||
if (params.empty())
|
||||
return llvm::PowerOf2Ceil(dataLayout.getTypeSize(fltType));
|
||||
return llvm::PowerOf2Ceil(dataLayout.getTypeSize(fltType).getFixedValue());
|
||||
return extractABIAlignment(params[0]);
|
||||
}
|
||||
|
||||
unsigned mlir::detail::getDefaultABIAlignment(
|
||||
uint64_t mlir::detail::getDefaultABIAlignment(
|
||||
Type type, const DataLayout &dataLayout,
|
||||
ArrayRef<DataLayoutEntryInterface> params) {
|
||||
// Natural alignment is the closest power-of-two number above.
|
||||
@ -157,23 +162,23 @@ unsigned mlir::detail::getDefaultABIAlignment(
|
||||
reportMissingDataLayout(type);
|
||||
}
|
||||
|
||||
static unsigned extractPreferredAlignment(DataLayoutEntryInterface entry) {
|
||||
static uint64_t extractPreferredAlignment(DataLayoutEntryInterface entry) {
|
||||
auto values =
|
||||
cast<DenseIntElementsAttr>(entry.getValue()).getValues<int32_t>();
|
||||
return *std::next(values.begin(), values.size() - 1) / 8u;
|
||||
cast<DenseIntElementsAttr>(entry.getValue()).getValues<uint64_t>();
|
||||
return *std::next(values.begin(), values.size() - 1) / kDefaultBitsInByte;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
static uint64_t
|
||||
getIntegerTypePreferredAlignment(IntegerType intType,
|
||||
const DataLayout &dataLayout,
|
||||
ArrayRef<DataLayoutEntryInterface> params) {
|
||||
if (params.empty())
|
||||
return llvm::PowerOf2Ceil(dataLayout.getTypeSize(intType));
|
||||
return llvm::PowerOf2Ceil(dataLayout.getTypeSize(intType).getFixedValue());
|
||||
|
||||
return extractPreferredAlignment(findEntryForIntegerType(intType, params));
|
||||
}
|
||||
|
||||
static unsigned
|
||||
static uint64_t
|
||||
getFloatTypePreferredAlignment(FloatType fltType, const DataLayout &dataLayout,
|
||||
ArrayRef<DataLayoutEntryInterface> params) {
|
||||
assert(params.size() <= 1 && "at most one data layout entry is expected for "
|
||||
@ -183,7 +188,7 @@ getFloatTypePreferredAlignment(FloatType fltType, const DataLayout &dataLayout,
|
||||
return extractPreferredAlignment(params[0]);
|
||||
}
|
||||
|
||||
unsigned mlir::detail::getDefaultPreferredAlignment(
|
||||
uint64_t mlir::detail::getDefaultPreferredAlignment(
|
||||
Type type, const DataLayout &dataLayout,
|
||||
ArrayRef<DataLayoutEntryInterface> params) {
|
||||
// Preferred alignment is same as natural for floats and vectors.
|
||||
@ -227,7 +232,7 @@ mlir::detail::getDefaultAllocaMemorySpace(DataLayoutEntryInterface entry) {
|
||||
|
||||
// Returns the stack alignment if specified in the given entry. If the entry is
|
||||
// empty the default alignment zero is returned.
|
||||
unsigned
|
||||
uint64_t
|
||||
mlir::detail::getDefaultStackAlignment(DataLayoutEntryInterface entry) {
|
||||
if (entry == DataLayoutEntryInterface())
|
||||
return 0;
|
||||
@ -353,6 +358,13 @@ LogicalResult mlir::detail::verifyDataLayoutOp(Operation *op) {
|
||||
return success();
|
||||
}
|
||||
|
||||
llvm::TypeSize mlir::detail::divideCeil(llvm::TypeSize numerator,
|
||||
uint64_t denominator) {
|
||||
uint64_t divided =
|
||||
llvm::divideCeil(numerator.getKnownMinValue(), denominator);
|
||||
return llvm::TypeSize::get(divided, numerator.isScalable());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DataLayout
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -423,8 +435,9 @@ void mlir::DataLayout::checkValid() const {
|
||||
/// Looks up the value for the given type key in the given cache. If there is no
|
||||
/// such value in the cache, compute it using the given callback and put it in
|
||||
/// the cache before returning.
|
||||
static unsigned cachedLookup(Type t, DenseMap<Type, unsigned> &cache,
|
||||
function_ref<unsigned(Type)> compute) {
|
||||
template <typename T>
|
||||
static T cachedLookup(Type t, DenseMap<Type, T> &cache,
|
||||
function_ref<T(Type)> compute) {
|
||||
auto it = cache.find(t);
|
||||
if (it != cache.end())
|
||||
return it->second;
|
||||
@ -433,9 +446,9 @@ static unsigned cachedLookup(Type t, DenseMap<Type, unsigned> &cache,
|
||||
return result.first->second;
|
||||
}
|
||||
|
||||
unsigned mlir::DataLayout::getTypeSize(Type t) const {
|
||||
llvm::TypeSize mlir::DataLayout::getTypeSize(Type t) const {
|
||||
checkValid();
|
||||
return cachedLookup(t, sizes, [&](Type ty) {
|
||||
return cachedLookup<llvm::TypeSize>(t, sizes, [&](Type ty) {
|
||||
DataLayoutEntryList list;
|
||||
if (originalLayout)
|
||||
list = originalLayout.getSpecForType(ty.getTypeID());
|
||||
@ -445,9 +458,9 @@ unsigned mlir::DataLayout::getTypeSize(Type t) const {
|
||||
});
|
||||
}
|
||||
|
||||
unsigned mlir::DataLayout::getTypeSizeInBits(Type t) const {
|
||||
llvm::TypeSize mlir::DataLayout::getTypeSizeInBits(Type t) const {
|
||||
checkValid();
|
||||
return cachedLookup(t, bitsizes, [&](Type ty) {
|
||||
return cachedLookup<llvm::TypeSize>(t, bitsizes, [&](Type ty) {
|
||||
DataLayoutEntryList list;
|
||||
if (originalLayout)
|
||||
list = originalLayout.getSpecForType(ty.getTypeID());
|
||||
@ -457,9 +470,9 @@ unsigned mlir::DataLayout::getTypeSizeInBits(Type t) const {
|
||||
});
|
||||
}
|
||||
|
||||
unsigned mlir::DataLayout::getTypeABIAlignment(Type t) const {
|
||||
uint64_t mlir::DataLayout::getTypeABIAlignment(Type t) const {
|
||||
checkValid();
|
||||
return cachedLookup(t, abiAlignments, [&](Type ty) {
|
||||
return cachedLookup<uint64_t>(t, abiAlignments, [&](Type ty) {
|
||||
DataLayoutEntryList list;
|
||||
if (originalLayout)
|
||||
list = originalLayout.getSpecForType(ty.getTypeID());
|
||||
@ -469,9 +482,9 @@ unsigned mlir::DataLayout::getTypeABIAlignment(Type t) const {
|
||||
});
|
||||
}
|
||||
|
||||
unsigned mlir::DataLayout::getTypePreferredAlignment(Type t) const {
|
||||
uint64_t mlir::DataLayout::getTypePreferredAlignment(Type t) const {
|
||||
checkValid();
|
||||
return cachedLookup(t, preferredAlignments, [&](Type ty) {
|
||||
return cachedLookup<uint64_t>(t, preferredAlignments, [&](Type ty) {
|
||||
DataLayoutEntryList list;
|
||||
if (originalLayout)
|
||||
list = originalLayout.getSpecForType(ty.getTypeID());
|
||||
@ -497,7 +510,7 @@ mlir::Attribute mlir::DataLayout::getAllocaMemorySpace() const {
|
||||
return *allocaMemorySpace;
|
||||
}
|
||||
|
||||
unsigned mlir::DataLayout::getStackAlignment() const {
|
||||
uint64_t mlir::DataLayout::getStackAlignment() const {
|
||||
checkValid();
|
||||
if (stackAlignment)
|
||||
return *stackAlignment;
|
||||
@ -556,14 +569,14 @@ LogicalResult mlir::detail::verifyDataLayoutSpec(DataLayoutSpecInterface spec,
|
||||
if (isa<IntegerType, FloatType>(sampleType)) {
|
||||
for (DataLayoutEntryInterface entry : kvp.second) {
|
||||
auto value = dyn_cast<DenseIntElementsAttr>(entry.getValue());
|
||||
if (!value || !value.getElementType().isSignlessInteger(32)) {
|
||||
emitError(loc) << "expected a dense i32 elements attribute in the "
|
||||
if (!value || !value.getElementType().isSignlessInteger(64)) {
|
||||
emitError(loc) << "expected a dense i64 elements attribute in the "
|
||||
"data layout entry "
|
||||
<< entry;
|
||||
return failure();
|
||||
}
|
||||
|
||||
auto elements = llvm::to_vector<2>(value.getValues<int32_t>());
|
||||
auto elements = llvm::to_vector<2>(value.getValues<uint64_t>());
|
||||
unsigned numElements = elements.size();
|
||||
if (numElements < 1 || numElements > 2) {
|
||||
emitError(loc) << "expected 1 or 2 elements in the data layout entry "
|
||||
@ -571,8 +584,8 @@ LogicalResult mlir::detail::verifyDataLayoutSpec(DataLayoutSpecInterface spec,
|
||||
return failure();
|
||||
}
|
||||
|
||||
int32_t abi = elements[0];
|
||||
int32_t preferred = numElements == 2 ? elements[1] : abi;
|
||||
uint64_t abi = elements[0];
|
||||
uint64_t preferred = numElements == 2 ? elements[1] : abi;
|
||||
if (preferred < abi) {
|
||||
emitError(loc)
|
||||
<< "preferred alignment is expected to be greater than or equal "
|
||||
|
@ -56,21 +56,21 @@ DataLayoutImporter::tryToParseAlphaPrefix(StringRef &token) const {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
FailureOr<unsigned> DataLayoutImporter::tryToParseInt(StringRef &token) const {
|
||||
unsigned parameter;
|
||||
FailureOr<uint64_t> DataLayoutImporter::tryToParseInt(StringRef &token) const {
|
||||
uint64_t parameter;
|
||||
if (token.consumeInteger(/*Radix=*/10, parameter))
|
||||
return failure();
|
||||
return parameter;
|
||||
}
|
||||
|
||||
FailureOr<SmallVector<unsigned>>
|
||||
FailureOr<SmallVector<uint64_t>>
|
||||
DataLayoutImporter::tryToParseIntList(StringRef token) const {
|
||||
SmallVector<StringRef> tokens;
|
||||
token.consume_front(":");
|
||||
token.split(tokens, ':');
|
||||
|
||||
// Parse an integer list.
|
||||
SmallVector<unsigned> results(tokens.size());
|
||||
SmallVector<uint64_t> results(tokens.size());
|
||||
for (auto [result, token] : llvm::zip(results, tokens))
|
||||
if (token.getAsInteger(/*Radix=*/10, result))
|
||||
return failure();
|
||||
@ -79,7 +79,7 @@ DataLayoutImporter::tryToParseIntList(StringRef token) const {
|
||||
|
||||
FailureOr<DenseIntElementsAttr>
|
||||
DataLayoutImporter::tryToParseAlignment(StringRef token) const {
|
||||
FailureOr<SmallVector<unsigned>> alignment = tryToParseIntList(token);
|
||||
FailureOr<SmallVector<uint64_t>> alignment = tryToParseIntList(token);
|
||||
if (failed(alignment))
|
||||
return failure();
|
||||
if (alignment->empty() || alignment->size() > 2)
|
||||
@ -89,16 +89,16 @@ DataLayoutImporter::tryToParseAlignment(StringRef token) const {
|
||||
// form <abi>[:<pref>], where abi specifies the minimal alignment and pref the
|
||||
// optional preferred alignment. The preferred alignment is set to the minimal
|
||||
// alignment if not available.
|
||||
unsigned minimal = (*alignment)[0];
|
||||
unsigned preferred = alignment->size() == 1 ? minimal : (*alignment)[1];
|
||||
uint64_t minimal = (*alignment)[0];
|
||||
uint64_t preferred = alignment->size() == 1 ? minimal : (*alignment)[1];
|
||||
return DenseIntElementsAttr::get(
|
||||
VectorType::get({2}, IntegerType::get(context, 32)),
|
||||
VectorType::get({2}, IntegerType::get(context, 64)),
|
||||
{minimal, preferred});
|
||||
}
|
||||
|
||||
FailureOr<DenseIntElementsAttr>
|
||||
DataLayoutImporter::tryToParsePointerAlignment(StringRef token) const {
|
||||
FailureOr<SmallVector<unsigned>> alignment = tryToParseIntList(token);
|
||||
FailureOr<SmallVector<uint64_t>> alignment = tryToParseIntList(token);
|
||||
if (failed(alignment))
|
||||
return failure();
|
||||
if (alignment->size() < 2 || alignment->size() > 4)
|
||||
@ -110,12 +110,12 @@ DataLayoutImporter::tryToParsePointerAlignment(StringRef token) const {
|
||||
// idx the optional index computation bit width. The preferred alignment is
|
||||
// set to the minimal alignment if not available and the index computation
|
||||
// width is set to the pointer size if not available.
|
||||
unsigned size = (*alignment)[0];
|
||||
unsigned minimal = (*alignment)[1];
|
||||
unsigned preferred = alignment->size() < 3 ? minimal : (*alignment)[2];
|
||||
unsigned idx = alignment->size() < 4 ? size : (*alignment)[3];
|
||||
return DenseIntElementsAttr::get(
|
||||
VectorType::get({4}, IntegerType::get(context, 32)),
|
||||
uint64_t size = (*alignment)[0];
|
||||
uint64_t minimal = (*alignment)[1];
|
||||
uint64_t preferred = alignment->size() < 3 ? minimal : (*alignment)[2];
|
||||
uint64_t idx = alignment->size() < 4 ? size : (*alignment)[3];
|
||||
return DenseIntElementsAttr::get<uint64_t>(
|
||||
VectorType::get({4}, IntegerType::get(context, 64)),
|
||||
{size, minimal, preferred, idx});
|
||||
}
|
||||
|
||||
@ -170,7 +170,7 @@ DataLayoutImporter::tryToEmplaceAllocaAddrSpaceEntry(StringRef token) {
|
||||
if (keyEntries.count(key))
|
||||
return success();
|
||||
|
||||
FailureOr<unsigned> space = tryToParseInt(token);
|
||||
FailureOr<uint64_t> space = tryToParseInt(token);
|
||||
if (failed(space))
|
||||
return failure();
|
||||
|
||||
@ -179,7 +179,10 @@ DataLayoutImporter::tryToEmplaceAllocaAddrSpaceEntry(StringRef token) {
|
||||
return success();
|
||||
OpBuilder builder(context);
|
||||
keyEntries.try_emplace(
|
||||
key, DataLayoutEntryAttr::get(key, builder.getUI32IntegerAttr(*space)));
|
||||
key,
|
||||
DataLayoutEntryAttr::get(
|
||||
key, builder.getIntegerAttr(
|
||||
builder.getIntegerType(64, /*isSigned=*/false), *space)));
|
||||
return success();
|
||||
}
|
||||
|
||||
@ -190,7 +193,7 @@ DataLayoutImporter::tryToEmplaceStackAlignmentEntry(StringRef token) {
|
||||
if (keyEntries.count(key))
|
||||
return success();
|
||||
|
||||
FailureOr<unsigned> alignment = tryToParseInt(token);
|
||||
FailureOr<uint64_t> alignment = tryToParseInt(token);
|
||||
if (failed(alignment))
|
||||
return failure();
|
||||
|
||||
@ -199,7 +202,7 @@ DataLayoutImporter::tryToEmplaceStackAlignmentEntry(StringRef token) {
|
||||
return success();
|
||||
OpBuilder builder(context);
|
||||
keyEntries.try_emplace(key, DataLayoutEntryAttr::get(
|
||||
key, builder.getI32IntegerAttr(*alignment)));
|
||||
key, builder.getI64IntegerAttr(*alignment)));
|
||||
return success();
|
||||
}
|
||||
|
||||
@ -258,7 +261,7 @@ void DataLayoutImporter::translateDataLayout(
|
||||
}
|
||||
// Parse integer alignment specifications.
|
||||
if (*prefix == "i") {
|
||||
FailureOr<unsigned> width = tryToParseInt(token);
|
||||
FailureOr<uint64_t> width = tryToParseInt(token);
|
||||
if (failed(width))
|
||||
return;
|
||||
|
||||
@ -269,7 +272,7 @@ void DataLayoutImporter::translateDataLayout(
|
||||
}
|
||||
// Parse float alignment specifications.
|
||||
if (*prefix == "f") {
|
||||
FailureOr<unsigned> width = tryToParseInt(token);
|
||||
FailureOr<uint64_t> width = tryToParseInt(token);
|
||||
if (failed(width))
|
||||
return;
|
||||
|
||||
@ -280,7 +283,7 @@ void DataLayoutImporter::translateDataLayout(
|
||||
}
|
||||
// Parse pointer alignment specifications.
|
||||
if (*prefix == "p") {
|
||||
FailureOr<unsigned> space =
|
||||
FailureOr<uint64_t> space =
|
||||
token.starts_with(":") ? 0 : tryToParseInt(token);
|
||||
if (failed(space))
|
||||
return;
|
||||
|
@ -73,10 +73,10 @@ private:
|
||||
|
||||
/// Tries to parse an integer parameter and removes the integer from the
|
||||
/// beginning of the string.
|
||||
FailureOr<unsigned> tryToParseInt(StringRef &token) const;
|
||||
FailureOr<uint64_t> tryToParseInt(StringRef &token) const;
|
||||
|
||||
/// Tries to parse an integer parameter array.
|
||||
FailureOr<SmallVector<unsigned>> tryToParseIntList(StringRef token) const;
|
||||
FailureOr<SmallVector<uint64_t>> tryToParseIntList(StringRef token) const;
|
||||
|
||||
/// Tries to parse the parameters of a type alignment entry.
|
||||
FailureOr<DenseIntElementsAttr> tryToParseAlignment(StringRef token) const;
|
||||
|
@ -131,9 +131,9 @@ translateDataLayout(DataLayoutSpecInterface attribute,
|
||||
} else {
|
||||
layoutStream << "f";
|
||||
}
|
||||
unsigned size = dataLayout.getTypeSizeInBits(type);
|
||||
unsigned abi = dataLayout.getTypeABIAlignment(type) * 8u;
|
||||
unsigned preferred =
|
||||
uint64_t size = dataLayout.getTypeSizeInBits(type);
|
||||
uint64_t abi = dataLayout.getTypeABIAlignment(type) * 8u;
|
||||
uint64_t preferred =
|
||||
dataLayout.getTypePreferredAlignment(type) * 8u;
|
||||
layoutStream << size << ":" << abi;
|
||||
if (abi != preferred)
|
||||
@ -142,12 +142,12 @@ translateDataLayout(DataLayoutSpecInterface attribute,
|
||||
})
|
||||
.Case([&](LLVMPointerType ptrType) {
|
||||
layoutStream << "p" << ptrType.getAddressSpace() << ":";
|
||||
unsigned size = dataLayout.getTypeSizeInBits(type);
|
||||
unsigned abi = dataLayout.getTypeABIAlignment(type) * 8u;
|
||||
unsigned preferred =
|
||||
uint64_t size = dataLayout.getTypeSizeInBits(type);
|
||||
uint64_t abi = dataLayout.getTypeABIAlignment(type) * 8u;
|
||||
uint64_t preferred =
|
||||
dataLayout.getTypePreferredAlignment(type) * 8u;
|
||||
layoutStream << size << ":" << abi << ":" << preferred;
|
||||
if (std::optional<unsigned> index = extractPointerSpecValue(
|
||||
if (std::optional<uint64_t> index = extractPointerSpecValue(
|
||||
entry.getValue(), PtrDLEntryPos::Index))
|
||||
layoutStream << ":" << *index;
|
||||
return success();
|
||||
@ -246,15 +246,15 @@ convertDenseElementsAttr(Location loc, DenseElementsAttr denseElementsAttr,
|
||||
// raw data.
|
||||
// TODO: we may also need to consider endianness when cross-compiling to an
|
||||
// architecture where it is different.
|
||||
unsigned elementByteSize = denseElementsAttr.getRawData().size() /
|
||||
denseElementsAttr.getNumElements();
|
||||
int64_t elementByteSize = denseElementsAttr.getRawData().size() /
|
||||
denseElementsAttr.getNumElements();
|
||||
if (8 * elementByteSize != innermostLLVMType->getScalarSizeInBits())
|
||||
return nullptr;
|
||||
|
||||
// Compute the shape of all dimensions but the innermost. Note that the
|
||||
// innermost dimension may be that of the vector element type.
|
||||
bool hasVectorElementType = isa<VectorType>(type.getElementType());
|
||||
unsigned numAggregates =
|
||||
int64_t numAggregates =
|
||||
denseElementsAttr.getNumElements() /
|
||||
(hasVectorElementType ? 1
|
||||
: denseElementsAttr.getType().getShape().back());
|
||||
@ -305,8 +305,8 @@ convertDenseElementsAttr(Location loc, DenseElementsAttr denseElementsAttr,
|
||||
// Create innermost constants and defer to the default constant creation
|
||||
// mechanism for other dimensions.
|
||||
SmallVector<llvm::Constant *> constants;
|
||||
unsigned aggregateSize = denseElementsAttr.getType().getShape().back() *
|
||||
(innermostLLVMType->getScalarSizeInBits() / 8);
|
||||
int64_t aggregateSize = denseElementsAttr.getType().getShape().back() *
|
||||
(innermostLLVMType->getScalarSizeInBits() / 8);
|
||||
constants.reserve(numAggregates);
|
||||
for (unsigned i = 0; i < numAggregates; ++i) {
|
||||
StringRef data(denseElementsAttr.getRawData().data() + i * aggregateSize,
|
||||
|
@ -261,8 +261,8 @@ func.func @mixed_store(%mixed : memref<42x?xf32>, %i : index, %j : index, %val :
|
||||
// to set address spaces, so the constants below don't reflect the layout
|
||||
// Update this test once that data layout attribute works how we'd expect it to.
|
||||
module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<!llvm.ptr, dense<[64, 64, 64]> : vector<3xi32>>,
|
||||
#dlti.dl_entry<!llvm.ptr<1>, dense<[32, 32, 32]> : vector<3xi32>>> } {
|
||||
#dlti.dl_entry<!llvm.ptr, dense<[64, 64, 64]> : vector<3xi64>>,
|
||||
#dlti.dl_entry<!llvm.ptr<1>, dense<[32, 32, 32]> : vector<3xi64>>> } {
|
||||
// CHECK-LABEL: @memref_memory_space_cast
|
||||
func.func @memref_memory_space_cast(%input : memref<*xf32>) -> memref<*xf32, 1> {
|
||||
%cast = memref.memory_space_cast %input : memref<*xf32> to memref<*xf32, 1>
|
||||
|
@ -1,6 +1,15 @@
|
||||
// RUN: mlir-opt %s | FileCheck %s
|
||||
|
||||
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<i1, dense<8> : vector<2xi32>>, #dlti.dl_entry<i8, dense<8> : vector<2xi32>>, #dlti.dl_entry<i16, dense<16> : vector<2xi32>>, #dlti.dl_entry<i32, dense<32> : vector<2xi32>>, #dlti.dl_entry<i64, dense<[32, 64]> : vector<2xi32>>, #dlti.dl_entry<f16, dense<16> : vector<2xi32>>, #dlti.dl_entry<f64, dense<64> : vector<2xi32>>, #dlti.dl_entry<f128, dense<128> : vector<2xi32>>>} {
|
||||
module attributes {
|
||||
dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<i1, dense<8> : vector<2xi64>>,
|
||||
#dlti.dl_entry<i8, dense<8> : vector<2xi64>>,
|
||||
#dlti.dl_entry<i16, dense<16> : vector<2xi64>>,
|
||||
#dlti.dl_entry<i32, dense<32> : vector<2xi64>>,
|
||||
#dlti.dl_entry<i64, dense<[32, 64]> : vector<2xi64>>,
|
||||
#dlti.dl_entry<f16, dense<16> : vector<2xi64>>,
|
||||
#dlti.dl_entry<f64, dense<64> : vector<2xi64>>,
|
||||
#dlti.dl_entry<f128, dense<128> : vector<2xi64>>>} {
|
||||
// CHECK: llvm.func @foo(%[[ARG0:.+]]: !llvm.ptr, %[[ARG1:.+]]: i32)
|
||||
llvm.func @foo(%arg0: !llvm.ptr, %arg1: i32) {
|
||||
// CHECK: %[[C0:.+]] = llvm.mlir.constant(0 : i32)
|
||||
|
14
mlir/test/Dialect/LLVMIR/inline-byval-huge.mlir
Normal file
14
mlir/test/Dialect/LLVMIR/inline-byval-huge.mlir
Normal file
@ -0,0 +1,14 @@
|
||||
// RUN: mlir-opt -inline %s | FileCheck %s
|
||||
|
||||
// CHECK-LABEL: @byval_2_000_000_000
|
||||
llvm.func @byval_2_000_000_000(%ptr : !llvm.ptr) {
|
||||
// CHECK: %[[SIZE:.+]] = llvm.mlir.constant(2000000000 : i64)
|
||||
// CHECK: "llvm.intr.memcpy"(%{{.*}}, %{{.*}}, %[[SIZE]]
|
||||
|
||||
llvm.call @with_byval_arg(%ptr) : (!llvm.ptr) -> ()
|
||||
llvm.return
|
||||
}
|
||||
|
||||
llvm.func @with_byval_arg(%ptr : !llvm.ptr { llvm.byval = !llvm.array<1000 x array<1000 x array <500 x i32>>> }) {
|
||||
llvm.return
|
||||
}
|
@ -31,11 +31,11 @@ module {
|
||||
// -----
|
||||
|
||||
module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<!llvm.ptr, dense<[32, 32, 64]> : vector<3xi32>>,
|
||||
#dlti.dl_entry<!llvm.ptr<5>, dense<[64, 64, 64]> : vector<3xi32>>,
|
||||
#dlti.dl_entry<!llvm.ptr<4>, dense<[32, 64, 64]> : vector<3xi32>>,
|
||||
#dlti.dl_entry<"dlti.alloca_memory_space", 5 : ui32>,
|
||||
#dlti.dl_entry<"dlti.stack_alignment", 128 : i32>
|
||||
#dlti.dl_entry<!llvm.ptr, dense<[32, 32, 64]> : vector<3xi64>>,
|
||||
#dlti.dl_entry<!llvm.ptr<5>, dense<[64, 64, 64]> : vector<3xi64>>,
|
||||
#dlti.dl_entry<!llvm.ptr<4>, dense<[32, 64, 64]> : vector<3xi64>>,
|
||||
#dlti.dl_entry<"dlti.alloca_memory_space", 5 : ui64>,
|
||||
#dlti.dl_entry<"dlti.stack_alignment", 128 : i64>
|
||||
>} {
|
||||
// CHECK: @spec
|
||||
func.func @spec() {
|
||||
@ -73,7 +73,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
// CHECK: preferred = 8
|
||||
// CHECK: size = 4
|
||||
// CHECK: stack_alignment = 128
|
||||
"test.data_layout_query"() : () -> !llvm.ptr<4>
|
||||
"test.data_layout_query"() : () -> !llvm.ptr<4>
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -93,7 +93,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
|
||||
// expected-error@below {{preferred alignment is expected to be at least as large as ABI alignment}}
|
||||
module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<!llvm.ptr, dense<[64, 64, 32]> : vector<3xi32>>
|
||||
#dlti.dl_entry<!llvm.ptr, dense<[64, 64, 32]> : vector<3xi64>>
|
||||
>} {
|
||||
func.func @pointer() {
|
||||
return
|
||||
@ -102,6 +102,14 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error @below {{expected i64 parameters for '!llvm.ptr'}}
|
||||
module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<!llvm.ptr, dense<[32, 32, 64]> : vector<3xi32>>
|
||||
>} {
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
module {
|
||||
// CHECK: @no_spec
|
||||
func.func @no_spec() {
|
||||
@ -146,7 +154,7 @@ module {
|
||||
// -----
|
||||
|
||||
module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<!llvm.struct<()>, dense<[32, 32]> : vector<2xi32>>
|
||||
#dlti.dl_entry<!llvm.struct<()>, dense<[32, 32]> : vector<2xi64>>
|
||||
>} {
|
||||
// CHECK: @spec
|
||||
func.func @spec() {
|
||||
@ -184,7 +192,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
// -----
|
||||
|
||||
module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<!llvm.struct<()>, dense<[32]> : vector<1xi32>>
|
||||
#dlti.dl_entry<!llvm.struct<()>, dense<[32]> : vector<1xi64>>
|
||||
>} {
|
||||
// CHECK: @spec_without_preferred
|
||||
func.func @spec_without_preferred() {
|
||||
@ -202,7 +210,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
|
||||
// expected-error@below {{unexpected layout attribute for struct '!llvm.struct<(i8)>'}}
|
||||
module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<!llvm.struct<(i8)>, dense<[64, 64]> : vector<2xi32>>
|
||||
#dlti.dl_entry<!llvm.struct<(i8)>, dense<[64, 64]> : vector<2xi64>>
|
||||
>} {
|
||||
func.func @struct() {
|
||||
return
|
||||
@ -213,7 +221,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
|
||||
// expected-error@below {{expected layout attribute for '!llvm.struct<()>' to be a dense integer elements attribute of 1 or 2 elements}}
|
||||
module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<!llvm.struct<()>, dense<[64, 64, 64]> : vector<3xi32>>
|
||||
#dlti.dl_entry<!llvm.struct<()>, dense<[64, 64, 64]> : vector<3xi64>>
|
||||
>} {
|
||||
func.func @struct() {
|
||||
return
|
||||
@ -224,7 +232,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
|
||||
// expected-error@below {{preferred alignment is expected to be at least as large as ABI alignment}}
|
||||
module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<!llvm.struct<()>, dense<[64, 32]> : vector<2xi32>>
|
||||
#dlti.dl_entry<!llvm.struct<()>, dense<[64, 32]> : vector<2xi64>>
|
||||
>} {
|
||||
func.func @struct() {
|
||||
return
|
||||
@ -263,7 +271,7 @@ module {
|
||||
// -----
|
||||
|
||||
module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<!llvm.struct<()>, dense<[64]> : vector<1xi32>>
|
||||
#dlti.dl_entry<!llvm.struct<()>, dense<[64]> : vector<1xi64>>
|
||||
>} {
|
||||
// CHECK: @overaligned
|
||||
func.func @overaligned() {
|
||||
@ -276,3 +284,11 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error @below {{expected i64 entries for '!llvm.struct<()>'}}
|
||||
module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<!llvm.struct<()>, dense<[64]> : vector<1xi32>>
|
||||
>} {
|
||||
}
|
||||
|
@ -216,8 +216,8 @@ func.func @integers() {
|
||||
"test.data_layout_query"() : () -> i128
|
||||
"test.maybe_terminator"() : () -> ()
|
||||
}) { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<i32, dense<64> : vector<1xi32>>,
|
||||
#dlti.dl_entry<i64, dense<128> : vector<1xi32>>
|
||||
#dlti.dl_entry<i32, dense<64> : vector<1xi64>>,
|
||||
#dlti.dl_entry<i64, dense<128> : vector<1xi64>>
|
||||
>} : () -> ()
|
||||
"test.op_with_data_layout"() ({
|
||||
// CHECK: alignment = 8
|
||||
@ -238,8 +238,8 @@ func.func @integers() {
|
||||
"test.data_layout_query"() : () -> i128
|
||||
"test.maybe_terminator"() : () -> ()
|
||||
}) { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<i32, dense<[64, 128]> : vector<2xi32>>,
|
||||
#dlti.dl_entry<i64, dense<[128, 256]> : vector<2xi32>>
|
||||
#dlti.dl_entry<i32, dense<[64, 128]> : vector<2xi64>>,
|
||||
#dlti.dl_entry<i64, dense<[128, 256]> : vector<2xi64>>
|
||||
>} : () -> ()
|
||||
return
|
||||
}
|
||||
@ -256,8 +256,8 @@ func.func @floats() {
|
||||
"test.data_layout_query"() : () -> f80
|
||||
"test.maybe_terminator"() : () -> ()
|
||||
}) { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<f32, dense<64> : vector<1xi32>>,
|
||||
#dlti.dl_entry<f80, dense<128> : vector<1xi32>>
|
||||
#dlti.dl_entry<f32, dense<64> : vector<1xi64>>,
|
||||
#dlti.dl_entry<f80, dense<128> : vector<1xi64>>
|
||||
>} : () -> ()
|
||||
"test.op_with_data_layout"() ({
|
||||
// CHECK: alignment = 8
|
||||
@ -270,8 +270,8 @@ func.func @floats() {
|
||||
"test.data_layout_query"() : () -> f80
|
||||
"test.maybe_terminator"() : () -> ()
|
||||
}) { dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<f32, dense<[64, 128]> : vector<2xi32>>,
|
||||
#dlti.dl_entry<f80, dense<[128, 256]> : vector<2xi32>>
|
||||
#dlti.dl_entry<f32, dense<[64, 128]> : vector<2xi64>>,
|
||||
#dlti.dl_entry<f80, dense<[128, 256]> : vector<2xi64>>
|
||||
>} : () -> ()
|
||||
return
|
||||
}
|
||||
|
@ -7,23 +7,23 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@below {{expected a dense i32 elements attribute}}
|
||||
// expected-error@below {{expected a dense i64 elements attribute}}
|
||||
module attributes {dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<i32, dense<[64,128]> : vector<2xi64>>>
|
||||
#dlti.dl_entry<i32, dense<[64,128]> : vector<2xi32>>>
|
||||
} {}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@below {{expected 1 or 2 elements}}
|
||||
module attributes {dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<i32, dense<[64,64,64]> : vector<3xi32>>>
|
||||
#dlti.dl_entry<i32, dense<[64,64,64]> : vector<3xi64>>>
|
||||
} {}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@below {{preferred alignment is expected to be greater than or equal to the abi alignment}}
|
||||
module attributes {dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<i32, dense<[64,32]> : vector<2xi32>>>
|
||||
#dlti.dl_entry<i32, dense<[64,32]> : vector<2xi64>>>
|
||||
} {}
|
||||
|
||||
// -----
|
||||
|
@ -5,15 +5,15 @@
|
||||
; CHECK: dlti.dl_spec =
|
||||
; CHECK: #dlti.dl_spec<
|
||||
; CHECK-DAG: #dlti.dl_entry<"dlti.endianness", "little">
|
||||
; CHECK-DAG: #dlti.dl_entry<i1, dense<8> : vector<2xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<i8, dense<8> : vector<2xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<i16, dense<16> : vector<2xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<i32, dense<32> : vector<2xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<i64, dense<[32, 64]> : vector<2xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<f16, dense<16> : vector<2xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<f64, dense<64> : vector<2xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<f128, dense<128> : vector<2xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<i1, dense<8> : vector<2xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<i8, dense<8> : vector<2xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<i16, dense<16> : vector<2xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<i32, dense<32> : vector<2xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<i64, dense<[32, 64]> : vector<2xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<f16, dense<16> : vector<2xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<f64, dense<64> : vector<2xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<f128, dense<128> : vector<2xi64>>
|
||||
; CHECK: >
|
||||
target datalayout = ""
|
||||
|
||||
@ -22,13 +22,13 @@ target datalayout = ""
|
||||
; CHECK: dlti.dl_spec =
|
||||
; CHECK: #dlti.dl_spec<
|
||||
; CHECK-DAG: #dlti.dl_entry<"dlti.endianness", "little">
|
||||
; CHECK-DAG: #dlti.dl_entry<i64, dense<64> : vector<2xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<f80, dense<128> : vector<2xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<i8, dense<8> : vector<2xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<!llvm.ptr<270>, dense<[32, 64, 64, 32]> : vector<4xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<!llvm.ptr<272>, dense<64> : vector<4xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<"dlti.stack_alignment", 128 : i32>
|
||||
; CHECK-DAG: #dlti.dl_entry<i64, dense<64> : vector<2xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<f80, dense<128> : vector<2xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<i8, dense<8> : vector<2xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<!llvm.ptr<270>, dense<[32, 64, 64, 32]> : vector<4xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<!llvm.ptr<272>, dense<64> : vector<4xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>
|
||||
target datalayout = "e-m:e-p270:32:64-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
; // -----
|
||||
@ -36,10 +36,10 @@ target datalayout = "e-m:e-p270:32:64-p271:32:32-p272:64:64-i64:64-f80:128-n8:16
|
||||
; CHECK: dlti.dl_spec =
|
||||
; CHECK: #dlti.dl_spec<
|
||||
; CHECK-DAG: #dlti.dl_entry<"dlti.endianness", "big">
|
||||
; CHECK-DAG: #dlti.dl_entry<!llvm.ptr<270>, dense<[16, 32, 64, 8]> : vector<4xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<!llvm.ptr<271>, dense<[16, 32, 64, 16]> : vector<4xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<"dlti.alloca_memory_space", 1 : ui32>
|
||||
; CHECK-DAG: #dlti.dl_entry<i64, dense<[64, 128]> : vector<2xi32>>
|
||||
; CHECK-DAG: #dlti.dl_entry<!llvm.ptr<270>, dense<[16, 32, 64, 8]> : vector<4xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<!llvm.ptr<271>, dense<[16, 32, 64, 16]> : vector<4xi64>>
|
||||
; CHECK-DAG: #dlti.dl_entry<"dlti.alloca_memory_space", 1 : ui64>
|
||||
; CHECK-DAG: #dlti.dl_entry<i64, dense<[64, 128]> : vector<2xi64>>
|
||||
target datalayout = "A1-E-p270:16:32:64:8-p271:16:32:64-i64:64:128"
|
||||
|
||||
; // -----
|
||||
|
@ -13,10 +13,10 @@ 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<index, 64>,
|
||||
#dlti.dl_entry<i64, dense<[64,128]> : vector<2xi32>>,
|
||||
#dlti.dl_entry<f80, dense<[128,256]> : vector<2xi32>>,
|
||||
#dlti.dl_entry<!llvm.ptr, dense<[32,64,128]> : vector<3xi32>>,
|
||||
#dlti.dl_entry<!llvm.ptr<1>, dense<[32,32,32,16]> : vector<4xi32>>
|
||||
#dlti.dl_entry<i64, dense<[64,128]> : vector<2xi64>>,
|
||||
#dlti.dl_entry<f80, dense<[128,256]> : vector<2xi64>>,
|
||||
#dlti.dl_entry<!llvm.ptr, dense<[32,64,128]> : vector<3xi64>>,
|
||||
#dlti.dl_entry<!llvm.ptr<1>, dense<[32,32,32,16]> : vector<4xi64>>
|
||||
>} {
|
||||
llvm.func @foo() {
|
||||
llvm.return
|
||||
@ -43,19 +43,19 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<
|
||||
|
||||
// expected-error@below {{unsupported data layout for non-signless integer 'ui64'}}
|
||||
module attributes {dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<ui64, dense<[64,128]> : vector<2xi32>>>
|
||||
#dlti.dl_entry<ui64, dense<[64,128]> : vector<2xi64>>>
|
||||
} {}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@below {{unsupported type in data layout: 'bf16'}}
|
||||
module attributes {dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<bf16, dense<[64,128]> : vector<2xi32>>>
|
||||
#dlti.dl_entry<bf16, dense<[64,128]> : vector<2xi64>>>
|
||||
} {}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@below {{unsupported data layout key "foo"}}
|
||||
module attributes {dlti.dl_spec = #dlti.dl_spec<
|
||||
#dlti.dl_entry<"foo", dense<[64,128]> : vector<2xi32>>>
|
||||
#dlti.dl_entry<"foo", dense<[64,128]> : vector<2xi64>>>
|
||||
} {}
|
||||
|
@ -157,7 +157,7 @@ def TestTypeWithLayoutType : Test_Type<"TestTypeWithLayout", [
|
||||
::mlir::Location loc) const;
|
||||
|
||||
private:
|
||||
unsigned extractKind(::mlir::DataLayoutEntryListRef params,
|
||||
uint64_t extractKind(::mlir::DataLayoutEntryListRef params,
|
||||
::llvm::StringRef expectedKind) const;
|
||||
|
||||
public:
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "llvm/ADT/Hashing.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/TypeSwitch.h"
|
||||
#include "llvm/Support/TypeSize.h"
|
||||
#include <optional>
|
||||
|
||||
using namespace mlir;
|
||||
@ -258,19 +259,19 @@ void TestTypeWithLayoutType::print(AsmPrinter &printer) const {
|
||||
printer << "<" << getKey() << ">";
|
||||
}
|
||||
|
||||
unsigned
|
||||
llvm::TypeSize
|
||||
TestTypeWithLayoutType::getTypeSizeInBits(const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params) const {
|
||||
return extractKind(params, "size");
|
||||
return llvm::TypeSize::Fixed(extractKind(params, "size"));
|
||||
}
|
||||
|
||||
unsigned
|
||||
uint64_t
|
||||
TestTypeWithLayoutType::getABIAlignment(const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params) const {
|
||||
return extractKind(params, "alignment");
|
||||
}
|
||||
|
||||
unsigned TestTypeWithLayoutType::getPreferredAlignment(
|
||||
uint64_t TestTypeWithLayoutType::getPreferredAlignment(
|
||||
const DataLayout &dataLayout, DataLayoutEntryListRef params) const {
|
||||
return extractKind(params, "preferred");
|
||||
}
|
||||
@ -303,7 +304,7 @@ TestTypeWithLayoutType::verifyEntries(DataLayoutEntryListRef params,
|
||||
return success();
|
||||
}
|
||||
|
||||
unsigned TestTypeWithLayoutType::extractKind(DataLayoutEntryListRef params,
|
||||
uint64_t TestTypeWithLayoutType::extractKind(DataLayoutEntryListRef params,
|
||||
StringRef expectedKind) const {
|
||||
for (DataLayoutEntryInterface entry : params) {
|
||||
ArrayRef<Attribute> pair =
|
||||
|
@ -85,17 +85,17 @@ struct SingleQueryType
|
||||
|
||||
static SingleQueryType get(MLIRContext *ctx) { return Base::get(ctx); }
|
||||
|
||||
unsigned getTypeSizeInBits(const DataLayout &layout,
|
||||
DataLayoutEntryListRef params) const {
|
||||
llvm::TypeSize getTypeSizeInBits(const DataLayout &layout,
|
||||
DataLayoutEntryListRef params) const {
|
||||
static bool executed = false;
|
||||
if (executed)
|
||||
llvm::report_fatal_error("repeated call");
|
||||
|
||||
executed = true;
|
||||
return 1;
|
||||
return llvm::TypeSize::Fixed(1);
|
||||
}
|
||||
|
||||
unsigned getABIAlignment(const DataLayout &layout,
|
||||
uint64_t getABIAlignment(const DataLayout &layout,
|
||||
DataLayoutEntryListRef params) {
|
||||
static bool executed = false;
|
||||
if (executed)
|
||||
@ -105,7 +105,7 @@ struct SingleQueryType
|
||||
return 2;
|
||||
}
|
||||
|
||||
unsigned getPreferredAlignment(const DataLayout &layout,
|
||||
uint64_t getPreferredAlignment(const DataLayout &layout,
|
||||
DataLayoutEntryListRef params) {
|
||||
static bool executed = false;
|
||||
if (executed)
|
||||
@ -149,8 +149,9 @@ struct OpWithLayout : public Op<OpWithLayout, DataLayoutOpInterface::Trait> {
|
||||
return getOperation()->getAttrOfType<DataLayoutSpecInterface>(kAttrName);
|
||||
}
|
||||
|
||||
static unsigned getTypeSizeInBits(Type type, const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params) {
|
||||
static llvm::TypeSize getTypeSizeInBits(Type type,
|
||||
const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params) {
|
||||
// Make a recursive query.
|
||||
if (isa<FloatType>(type))
|
||||
return dataLayout.getTypeSizeInBits(
|
||||
@ -160,21 +161,22 @@ struct OpWithLayout : public Op<OpWithLayout, DataLayoutOpInterface::Trait> {
|
||||
if (auto iType = dyn_cast<IntegerType>(type)) {
|
||||
for (DataLayoutEntryInterface entry : params)
|
||||
if (llvm::dyn_cast_if_present<Type>(entry.getKey()) == type)
|
||||
return 8 *
|
||||
cast<IntegerAttr>(entry.getValue()).getValue().getZExtValue();
|
||||
return 8 * iType.getIntOrFloatBitWidth();
|
||||
return llvm::TypeSize::Fixed(
|
||||
8 *
|
||||
cast<IntegerAttr>(entry.getValue()).getValue().getZExtValue());
|
||||
return llvm::TypeSize::Fixed(8 * iType.getIntOrFloatBitWidth());
|
||||
}
|
||||
|
||||
// Use the default process for everything else.
|
||||
return detail::getDefaultTypeSize(type, dataLayout, params);
|
||||
}
|
||||
|
||||
static unsigned getTypeABIAlignment(Type type, const DataLayout &dataLayout,
|
||||
static uint64_t getTypeABIAlignment(Type type, const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params) {
|
||||
return llvm::PowerOf2Ceil(getTypeSize(type, dataLayout, params));
|
||||
}
|
||||
|
||||
static unsigned getTypePreferredAlignment(Type type,
|
||||
static uint64_t getTypePreferredAlignment(Type type,
|
||||
const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params) {
|
||||
return 2 * getTypeABIAlignment(type, dataLayout, params);
|
||||
@ -195,9 +197,9 @@ struct OpWith7BitByte
|
||||
}
|
||||
|
||||
// Bytes are assumed to be 7-bit here.
|
||||
static unsigned getTypeSize(Type type, const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params) {
|
||||
return llvm::divideCeil(dataLayout.getTypeSizeInBits(type), 7);
|
||||
static llvm::TypeSize getTypeSize(Type type, const DataLayout &dataLayout,
|
||||
DataLayoutEntryListRef params) {
|
||||
return mlir::detail::divideCeil(dataLayout.getTypeSizeInBits(type), 7);
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user