Skip to content

Commit ef5be2b

Browse files
committed
[mlir] Implement DataLayoutTypeInterface for LLVMArrayType
Implementation of the interface allows querying the size and alignments of an LLVMArrayType as well as query the size and alignment of a struct containing an LLVMArrayType. The implementation should yield the same results as llvm::DataLayout, including support for over aligned element types. There is no customization point for adjusting an arrays alignment; it is simply taken from the element type. Differential Revision: https://reviews.llvm.org/D115704
1 parent 9769340 commit ef5be2b

File tree

3 files changed

+92
-7
lines changed

3 files changed

+92
-7
lines changed

mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,9 @@ DEFINE_TRIVIAL_LLVM_TYPE(LLVMMetadataType);
7171
/// LLVM dialect array type. It is an aggregate type representing consecutive
7272
/// elements in memory, parameterized by the number of elements and the element
7373
/// type.
74-
class LLVMArrayType : public Type::TypeBase<LLVMArrayType, Type,
75-
detail::LLVMTypeAndSizeStorage> {
74+
class LLVMArrayType
75+
: public Type::TypeBase<LLVMArrayType, Type, detail::LLVMTypeAndSizeStorage,
76+
DataLayoutTypeInterface::Trait> {
7677
public:
7778
/// Inherit base constructors.
7879
using Base::Base;
@@ -88,14 +89,28 @@ class LLVMArrayType : public Type::TypeBase<LLVMArrayType, Type,
8889
Type elementType, unsigned numElements);
8990

9091
/// Returns the element type of the array.
91-
Type getElementType();
92+
Type getElementType() const;
9293

9394
/// Returns the number of elements in the array type.
94-
unsigned getNumElements();
95+
unsigned getNumElements() const;
9596

9697
/// Verifies that the type about to be constructed is well-formed.
9798
static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError,
9899
Type elementType, unsigned numElements);
100+
101+
/// Hooks for DataLayoutTypeInterface. Should not be called directly. Obtain a
102+
/// DataLayout instance and query it instead.
103+
unsigned getTypeSizeInBits(const DataLayout &dataLayout,
104+
DataLayoutEntryListRef params) const;
105+
106+
unsigned getTypeSize(const DataLayout &dataLayout,
107+
DataLayoutEntryListRef params) const;
108+
109+
unsigned getABIAlignment(const DataLayout &dataLayout,
110+
DataLayoutEntryListRef params) const;
111+
112+
unsigned getPreferredAlignment(const DataLayout &dataLayout,
113+
DataLayoutEntryListRef params) const;
99114
};
100115

101116
//===----------------------------------------------------------------------===//

mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
using namespace mlir;
2626
using namespace mlir::LLVM;
2727

28+
constexpr const static unsigned kBitsInByte = 8;
29+
2830
//===----------------------------------------------------------------------===//
2931
// Array type.
3032
//===----------------------------------------------------------------------===//
@@ -47,9 +49,11 @@ LLVMArrayType::getChecked(function_ref<InFlightDiagnostic()> emitError,
4749
numElements);
4850
}
4951

50-
Type LLVMArrayType::getElementType() { return getImpl()->elementType; }
52+
Type LLVMArrayType::getElementType() const { return getImpl()->elementType; }
5153

52-
unsigned LLVMArrayType::getNumElements() { return getImpl()->numElements; }
54+
unsigned LLVMArrayType::getNumElements() const {
55+
return getImpl()->numElements;
56+
}
5357

5458
LogicalResult
5559
LLVMArrayType::verify(function_ref<InFlightDiagnostic()> emitError,
@@ -59,6 +63,29 @@ LLVMArrayType::verify(function_ref<InFlightDiagnostic()> emitError,
5963
return success();
6064
}
6165

66+
unsigned LLVMArrayType::getTypeSizeInBits(const DataLayout &dataLayout,
67+
DataLayoutEntryListRef params) const {
68+
return kBitsInByte * getTypeSize(dataLayout, params);
69+
}
70+
71+
unsigned LLVMArrayType::getTypeSize(const DataLayout &dataLayout,
72+
DataLayoutEntryListRef params) const {
73+
return llvm::alignTo(dataLayout.getTypeSize(getElementType()),
74+
dataLayout.getTypeABIAlignment(getElementType())) *
75+
getNumElements();
76+
}
77+
78+
unsigned LLVMArrayType::getABIAlignment(const DataLayout &dataLayout,
79+
DataLayoutEntryListRef params) const {
80+
return dataLayout.getTypeABIAlignment(getElementType());
81+
}
82+
83+
unsigned
84+
LLVMArrayType::getPreferredAlignment(const DataLayout &dataLayout,
85+
DataLayoutEntryListRef params) const {
86+
return dataLayout.getTypePreferredAlignment(getElementType());
87+
}
88+
6289
//===----------------------------------------------------------------------===//
6390
// Function type.
6491
//===----------------------------------------------------------------------===//
@@ -159,7 +186,6 @@ enum class DLEntryPos { Size = 0, Abi = 1, Preferred = 2, Address = 3 };
159186

160187
constexpr const static unsigned kDefaultPointerSizeBits = 64;
161188
constexpr const static unsigned kDefaultPointerAlignment = 8;
162-
constexpr const static unsigned kBitsInByte = 8;
163189

164190
/// Returns the value that corresponds to named position `pos` from the
165191
/// attribute `attr` assuming it's a dense integer elements attribute.

mlir/test/Dialect/LLVMIR/layout.mlir

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,47 @@ module attributes { dlti.dl_spec = #dlti.dl_spec<
244244
}
245245

246246
// -----
247+
248+
module {
249+
// CHECK: @arrays
250+
func @arrays() {
251+
// simple case
252+
// CHECK: alignment = 4
253+
// CHECK: bitsize = 64
254+
// CHECK: preferred = 4
255+
// CHECK: size = 8
256+
"test.data_layout_query"() : () -> !llvm.array<2 x i32>
257+
258+
// size 0
259+
// CHECK: alignment = 8
260+
// CHECK: bitsize = 0
261+
// CHECK: preferred = 8
262+
// CHECK: size = 0
263+
"test.data_layout_query"() : () -> !llvm.array<0 x f64>
264+
265+
// alignment info matches element type
266+
// CHECK: alignment = 4
267+
// CHECK: bitsize = 64
268+
// CHECK: preferred = 8
269+
// CHECK: size = 8
270+
"test.data_layout_query"() : () -> !llvm.array<1 x i64>
271+
return
272+
}
273+
}
274+
275+
// -----
276+
277+
module attributes { dlti.dl_spec = #dlti.dl_spec<
278+
#dlti.dl_entry<!llvm.struct<()>, dense<[64]> : vector<1xi32>>
279+
>} {
280+
// CHECK: @overaligned
281+
func @overaligned() {
282+
// Over aligned element types are respected
283+
// CHECK: alignment = 8
284+
// CHECK: bitsize = 128
285+
// CHECK: preferred = 8
286+
// CHECK: size = 16
287+
"test.data_layout_query"() : () -> !llvm.array<2 x struct<(i8)>>
288+
return
289+
}
290+
}

0 commit comments

Comments
 (0)