[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:
Valentin Clement 2021-12-09 22:27:49 +01:00
parent c1cd698a52
commit ad3bb7c7da
No known key found for this signature in database
GPG key ID: 086D54783C928776
5 changed files with 25 additions and 26 deletions

View file

@ -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(

View file

@ -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});
}

View file

@ -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)

View file

@ -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;
}
}
}

View file

@ -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);
}