Skip to content

Commit 6f3b18a

Browse files
clementvalvdonaldson
authored andcommitted
[flang][runtime] Add ragged array runtime functions
This patch adds the runtime function to allocate and deallocate ragged arrays. This patch is part of the upstreaming effort from fir-dev branch. Reviewed By: klausler Differential Revision: https://reviews.llvm.org/D114534 Co-authored-by: Eric Schweitz <[email protected]> Conflicts resolved in favor of recent commit: flang/include/flang/Runtime/ragged.h flang/runtime/ragged.cpp
1 parent 5192bf7 commit 6f3b18a

File tree

4 files changed

+47
-15
lines changed

4 files changed

+47
-15
lines changed

flang/include/flang/Runtime/ragged.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,13 @@ namespace Fortran::runtime {
2424
// By default, a header is set to zero, which is its unused state.
2525
// The layout of a ragged buffer header is mirrored in the compiler.
2626
struct RaggedArrayHeader {
27-
std::uint64_t flags{0u};
27+
bool indirection{false};
28+
std::uint8_t rank;
2829
void *bufferPointer{nullptr};
2930
std::int64_t *extentPointer{nullptr};
31+
32+
bool isIndirection() { return indirection; }
33+
std::uint8_t getRank() { return rank; }
3034
};
3135

3236
RaggedArrayHeader *RaggedArrayAllocate(

flang/runtime/ragged.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,21 @@
1111

1212
namespace Fortran::runtime {
1313

14-
inline bool isIndirection(const RaggedArrayHeader *const header) {
15-
return header->flags & 1;
16-
}
17-
18-
inline std::size_t rank(const RaggedArrayHeader *const header) {
19-
return header->flags >> 1;
20-
}
21-
2214
RaggedArrayHeader *RaggedArrayAllocate(RaggedArrayHeader *header, bool isHeader,
2315
std::int64_t rank, std::int64_t elementSize, std::int64_t *extentVector) {
2416
if (header && rank) {
25-
std::int64_t size = 1;
17+
std::int64_t size{1};
2618
for (std::int64_t counter{0}; counter < rank; ++counter) {
2719
size *= extentVector[counter];
2820
if (size <= 0) {
2921
return nullptr;
3022
}
3123
}
32-
header->flags = (rank << 1) | isHeader;
24+
header->indirection = isHeader;
25+
header->rank = rank;
3326
header->extentPointer = extentVector;
3427
if (isHeader) {
35-
header->bufferPointer = new RaggedArrayHeader[size];
28+
header->bufferPointer = std::malloc(sizeof(RaggedArrayHeader) * size);
3629
} else {
3730
header->bufferPointer =
3831
static_cast<void *>(std::calloc(elementSize, size));
@@ -46,8 +39,8 @@ RaggedArrayHeader *RaggedArrayAllocate(RaggedArrayHeader *header, bool isHeader,
4639
// Deallocate a ragged array from the heap.
4740
void RaggedArrayDeallocate(RaggedArrayHeader *raggedArrayHeader) {
4841
if (raggedArrayHeader) {
49-
if (std::size_t end{rank(raggedArrayHeader)}) {
50-
if (isIndirection(raggedArrayHeader)) {
42+
if (std::size_t end{raggedArrayHeader->getRank()}) {
43+
if (raggedArrayHeader->isIndirection()) {
5144
std::size_t linearExtent{1u};
5245
for (std::size_t counter{0u}; counter < end && linearExtent > 0;
5346
++counter) {
@@ -60,7 +53,8 @@ void RaggedArrayDeallocate(RaggedArrayHeader *raggedArrayHeader) {
6053
}
6154
std::free(raggedArrayHeader->bufferPointer);
6255
std::free(raggedArrayHeader->extentPointer);
63-
raggedArrayHeader->flags = 0u;
56+
raggedArrayHeader->indirection = false;
57+
raggedArrayHeader->rank = 0u;
6458
}
6559
}
6660
}

flang/unittests/Runtime/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ add_flang_unittest(FlangRuntimeTests
1111
Namelist.cpp
1212
Numeric.cpp
1313
NumericalFormatTest.cpp
14+
Ragged.cpp
1415
Random.cpp
1516
Reduction.cpp
1617
RuntimeCrashTest.cpp

flang/unittests/Runtime/Ragged.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===-- flang/unittests/Runtime/Ragged.cpp ----------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "flang/Runtime/ragged.h"
10+
#include "gtest/gtest.h"
11+
12+
using namespace Fortran::runtime;
13+
14+
TEST(Ragged, RaggedArrayAllocateDeallocateTest) {
15+
struct RaggedArrayHeader header;
16+
unsigned rank = 2;
17+
int64_t *extents = new int64_t[2];
18+
extents[0] = 10;
19+
extents[1] = 100;
20+
RaggedArrayHeader *ret = (RaggedArrayHeader *)_FortranARaggedArrayAllocate(
21+
&header, false, rank, 32, extents);
22+
EXPECT_TRUE(ret != nullptr);
23+
EXPECT_TRUE(ret->bufferPointer != nullptr);
24+
EXPECT_EQ(extents, ret->extentPointer);
25+
EXPECT_EQ(10, ret->extentPointer[0]);
26+
EXPECT_EQ(100, ret->extentPointer[1]);
27+
EXPECT_EQ(rank, ret->getRank());
28+
EXPECT_FALSE(ret->isIndirection());
29+
30+
_FortranARaggedArrayDeallocate(ret);
31+
EXPECT_EQ(0u, ret->getRank());
32+
EXPECT_FALSE(ret->isIndirection());
33+
}

0 commit comments

Comments
 (0)