From ad3bb7c7da7b9e66cb98629d0f579546c8ead48f Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Thu, 9 Dec 2021 22:27:49 +0100 Subject: [PATCH] [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 --- flang/include/flang/Runtime/ragged.h | 16 ++++++--------- flang/lib/Optimizer/Builder/FIRBuilder.cpp | 4 +--- .../lib/Optimizer/Builder/Runtime/Ragged.cpp | 4 ++-- flang/runtime/ragged.cpp | 20 ++++++++++++------- flang/unittests/Runtime/Ragged.cpp | 7 +++---- 5 files changed, 25 insertions(+), 26 deletions(-) diff --git a/flang/include/flang/Runtime/ragged.h b/flang/include/flang/Runtime/ragged.h index ddd06225821b..e4b5838212a8 100644 --- a/flang/include/flang/Runtime/ragged.h +++ b/flang/include/flang/Runtime/ragged.h @@ -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( diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp index 1a4f6c17ea89..28a3816c121b 100644 --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -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}); } diff --git a/flang/lib/Optimizer/Builder/Runtime/Ragged.cpp b/flang/lib/Optimizer/Builder/Runtime/Ragged.cpp index 5df838250bcd..bdbbb78a75cf 100644 --- a/flang/lib/Optimizer/Builder/Runtime/Ragged.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/Ragged.cpp @@ -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().getType(1)); - auto ptr = builder.create(loc, ptrTy, header, two); + auto ptr = builder.create(loc, ptrTy, header, one); auto heap = builder.create(loc, ptr); auto cmp = builder.genIsNull(loc, heap); builder.genIfThen(loc, cmp) diff --git a/flang/runtime/ragged.cpp b/flang/runtime/ragged.cpp index 79233595f8da..855aa02e7f59 100644 --- a/flang/runtime/ragged.cpp +++ b/flang/runtime/ragged.cpp @@ -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(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; } } } diff --git a/flang/unittests/Runtime/Ragged.cpp b/flang/unittests/Runtime/Ragged.cpp index 002dba1a6cf5..4b261b14789c 100644 --- a/flang/unittests/Runtime/Ragged.cpp +++ b/flang/unittests/Runtime/Ragged.cpp @@ -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); }