1 //===-- Runtime/ragged.h ----------------------------------------*- 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 #ifndef FORTRAN_RUNTIME_RAGGED_H_
10 #define FORTRAN_RUNTIME_RAGGED_H_
11 
12 #include "flang/Runtime/entry-names.h"
13 #include <cstdint>
14 
15 namespace Fortran::runtime {
16 
17 // A ragged array header block.
18 // The header block is used to create the "array of arrays" ragged data
19 // structure. It contains a pair in `flags` to indicate if the header points to
20 // an array of headers (isIndirection) or data elements and the rank of the
21 // pointed-to array. The rank is the length of the extents vector accessed
22 // through `extentPointer`. The `bufferPointer` is overloaded
23 // and is null, points to an array of headers (isIndirection), or data.
24 // By default, a header is set to zero, which is its unused state.
25 // The layout of a ragged buffer header is mirrored in the compiler.
26 struct RaggedArrayHeader {
27   std::uint64_t flags;
28   void *bufferPointer;
29   std::int64_t *extentPointer;
30 };
31 
32 RaggedArrayHeader *RaggedArrayAllocate(
33     RaggedArrayHeader *, bool, std::int64_t, std::int64_t, std::int64_t *);
34 
35 void RaggedArrayDeallocate(RaggedArrayHeader *);
36 
37 extern "C" {
38 
39 // For more on ragged arrays see https://en.wikipedia.org/wiki/Jagged_array. The
40 // Flang compiler allocates ragged arrays as a generalization for
41 // non-rectangular array temporaries. Ragged arrays can be allocated recursively
42 // and on demand. Structurally, each leaf is an optional rectangular array of
43 // elements. The shape of each leaf is independent and may be computed on
44 // demand. Each branch node is an optional, possibly sparse rectangular array of
45 // headers. The shape of each branch is independent and may be computed on
46 // demand. Ragged arrays preserve a correspondence between a multidimensional
47 // iteration space and array access vectors, which is helpful for dependence
48 // analysis.
49 
50 // Runtime helper for allocation of ragged array buffers.
51 // A pointer to the header block to be allocated is given as header. The flag
52 // isHeader indicates if a block of headers or data is to be allocated. A
53 // non-negative rank indicates the length of the extentVector, which is a list
54 // of non-negative extents. elementSize is the size of a data element in the
55 // rectangular space defined by the extentVector.
56 void *RTNAME(RaggedArrayAllocate)(void *header, bool isHeader,
57     std::int64_t rank, std::int64_t elementSize, std::int64_t *extentVector);
58 
59 // Runtime helper for deallocation of ragged array buffers. The root header of
60 // the ragged array structure is passed to deallocate the entire ragged array.
61 void RTNAME(RaggedArrayDeallocate)(void *raggedArrayHeader);
62 
63 } // extern "C"
64 } // namespace Fortran::runtime
65 #endif // FORTRAN_RUNTIME_RAGGED_H_
66