[flang] Simplify RaggedArrayHeader and make it plain C struct
- Join indirection and rank into a single value `flags` - Make the struct a plain C struct. Reviewed By: schweitz Differential Revision: https://reviews.llvm.org/D115464
This commit is contained in:
parent
c1cd698a52
commit
ad3bb7c7da
|
@ -16,21 +16,17 @@ namespace Fortran::runtime {
|
|||
|
||||
// A ragged array header block.
|
||||
// The header block is used to create the "array of arrays" ragged data
|
||||
// structure. It contains a boolean value to indicate if the header points to
|
||||
// structure. It contains a pair in `flags` to indicate if the header points to
|
||||
// an array of headers (isIndirection) or data elements and the rank of the
|
||||
// pointed-to array in an integer value. The rank is the length of the extents
|
||||
// vector accessed through `extentPointer`. The `bufferPointer` is overloaded
|
||||
// pointed-to array. The rank is the length of the extents vector accessed
|
||||
// through `extentPointer`. The `bufferPointer` is overloaded
|
||||
// and is null, points to an array of headers (isIndirection), or data.
|
||||
// By default, a header is set to zero, which is its unused state.
|
||||
// The layout of a ragged buffer header is mirrored in the compiler.
|
||||
struct RaggedArrayHeader {
|
||||
bool indirection{false};
|
||||
std::uint8_t rank;
|
||||
void *bufferPointer{nullptr};
|
||||
std::int64_t *extentPointer{nullptr};
|
||||
|
||||
bool isIndirection() { return indirection; }
|
||||
std::uint8_t getRank() { return rank; }
|
||||
std::uint64_t flags;
|
||||
void *bufferPointer;
|
||||
std::int64_t *extentPointer;
|
||||
};
|
||||
|
||||
RaggedArrayHeader *RaggedArrayAllocate(
|
||||
|
|
|
@ -597,12 +597,10 @@ fir::factory::createExtents(fir::FirOpBuilder &builder, mlir::Location loc,
|
|||
|
||||
mlir::TupleType
|
||||
fir::factory::getRaggedArrayHeaderType(fir::FirOpBuilder &builder) {
|
||||
mlir::IntegerType i1Ty = builder.getIntegerType(1);
|
||||
mlir::IntegerType i8Ty = builder.getIntegerType(8);
|
||||
mlir::IntegerType i64Ty = builder.getIntegerType(64);
|
||||
auto arrTy = fir::SequenceType::get(builder.getIntegerType(8), 1);
|
||||
auto buffTy = fir::HeapType::get(arrTy);
|
||||
auto extTy = fir::SequenceType::get(i64Ty, 1);
|
||||
auto shTy = fir::HeapType::get(extTy);
|
||||
return mlir::TupleType::get(builder.getContext(), {i1Ty, i8Ty, buffTy, shTy});
|
||||
return mlir::TupleType::get(builder.getContext(), {i64Ty, buffTy, shTy});
|
||||
}
|
||||
|
|
|
@ -30,10 +30,10 @@ void fir::runtime::genRaggedArrayAllocate(mlir::Location loc,
|
|||
auto extentTy = fir::SequenceType::get(shape, i64Ty);
|
||||
auto refTy = fir::ReferenceType::get(i64Ty);
|
||||
// Position of the bufferPointer in the header struct.
|
||||
auto two = builder.createIntegerConstant(loc, i32Ty, 2);
|
||||
auto one = builder.createIntegerConstant(loc, i32Ty, 1);
|
||||
auto eleTy = fir::unwrapSequenceType(fir::unwrapRefType(header.getType()));
|
||||
auto ptrTy = builder.getRefType(eleTy.cast<mlir::TupleType>().getType(1));
|
||||
auto ptr = builder.create<fir::CoordinateOp>(loc, ptrTy, header, two);
|
||||
auto ptr = builder.create<fir::CoordinateOp>(loc, ptrTy, header, one);
|
||||
auto heap = builder.create<fir::LoadOp>(loc, ptr);
|
||||
auto cmp = builder.genIsNull(loc, heap);
|
||||
builder.genIfThen(loc, cmp)
|
||||
|
|
|
@ -11,6 +11,14 @@
|
|||
|
||||
namespace Fortran::runtime {
|
||||
|
||||
inline bool isIndirection(const RaggedArrayHeader *const header) {
|
||||
return header->flags & 1;
|
||||
}
|
||||
|
||||
inline std::size_t rank(const RaggedArrayHeader *const header) {
|
||||
return header->flags >> 1;
|
||||
}
|
||||
|
||||
RaggedArrayHeader *RaggedArrayAllocate(RaggedArrayHeader *header, bool isHeader,
|
||||
std::int64_t rank, std::int64_t elementSize, std::int64_t *extentVector) {
|
||||
if (header && rank) {
|
||||
|
@ -21,11 +29,10 @@ RaggedArrayHeader *RaggedArrayAllocate(RaggedArrayHeader *header, bool isHeader,
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
header->indirection = isHeader;
|
||||
header->rank = rank;
|
||||
header->flags = (rank << 1) | isHeader;
|
||||
header->extentPointer = extentVector;
|
||||
if (isHeader) {
|
||||
header->bufferPointer = std::malloc(sizeof(RaggedArrayHeader) * size);
|
||||
header->bufferPointer = std::calloc(sizeof(RaggedArrayHeader), size);
|
||||
} else {
|
||||
header->bufferPointer =
|
||||
static_cast<void *>(std::calloc(elementSize, size));
|
||||
|
@ -39,8 +46,8 @@ RaggedArrayHeader *RaggedArrayAllocate(RaggedArrayHeader *header, bool isHeader,
|
|||
// Deallocate a ragged array from the heap.
|
||||
void RaggedArrayDeallocate(RaggedArrayHeader *raggedArrayHeader) {
|
||||
if (raggedArrayHeader) {
|
||||
if (std::size_t end{raggedArrayHeader->getRank()}) {
|
||||
if (raggedArrayHeader->isIndirection()) {
|
||||
if (std::size_t end{rank(raggedArrayHeader)}) {
|
||||
if (isIndirection(raggedArrayHeader)) {
|
||||
std::size_t linearExtent{1u};
|
||||
for (std::size_t counter{0u}; counter < end && linearExtent > 0;
|
||||
++counter) {
|
||||
|
@ -53,8 +60,7 @@ void RaggedArrayDeallocate(RaggedArrayHeader *raggedArrayHeader) {
|
|||
}
|
||||
std::free(raggedArrayHeader->bufferPointer);
|
||||
std::free(raggedArrayHeader->extentPointer);
|
||||
raggedArrayHeader->indirection = false;
|
||||
raggedArrayHeader->rank = 0u;
|
||||
raggedArrayHeader->flags = 0u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,10 +24,9 @@ TEST(Ragged, RaggedArrayAllocateDeallocateTest) {
|
|||
EXPECT_EQ(extents, ret->extentPointer);
|
||||
EXPECT_EQ(10, ret->extentPointer[0]);
|
||||
EXPECT_EQ(100, ret->extentPointer[1]);
|
||||
EXPECT_EQ(rank, ret->getRank());
|
||||
EXPECT_FALSE(ret->isIndirection());
|
||||
EXPECT_EQ(rank, ret->flags >> 1);
|
||||
EXPECT_FALSE(ret->flags & 1);
|
||||
|
||||
_FortranARaggedArrayDeallocate(ret);
|
||||
EXPECT_EQ(0u, ret->getRank());
|
||||
EXPECT_FALSE(ret->isIndirection());
|
||||
EXPECT_EQ(0u, ret->flags);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue