Skip to content

Commit c91ba04

Browse files
authored
[Flang][NFC] Split runtime headers in preparation for cross-compilation. (#112188)
Split some headers into headers for public and private declarations in preparation for #110217. Moving the runtime-private headers in runtime-private include directory will occur in #110298. * Do not use `sizeof(Descriptor)` in the compiler. The size of the descriptor is target-dependent while `sizeof(Descriptor)` is the size of the Descriptor for the host platform which might be too small when cross-compiling to a different platform. Another problem is that the emitted assembly ((cross-)compiling to the same target) is not identical between Flang's running on different systems. Moving the declaration of `class Descriptor` out of the included header will also reduce the amount of #included sources. * Do not use `sizeof(ArrayConstructorVector)` and `alignof(ArrayConstructorVector)` in the compiler. Same reason as with `Descriptor`. * Compute the descriptor's extra flags without instantiating a Descriptor. `Fortran::runtime::Descriptor` is defined in the runtime source, but not the compiler source. * Move `InquiryKeywordHashDecode` into runtime-private header. The function is defined in the runtime sources and trying to call it in the compiler would lead to a link-error. * Move allocator-kind magic numbers into common header. They are the only declarations out of `allocator-registry.h` in the compiler as well. This does not make Flang cross-compile ready yet, the main goal is to avoid transitive header dependencies from Flang to clang-rt. There are more assumptions that host platform is the same as the target platform.
1 parent 1801fb4 commit c91ba04

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+728
-567
lines changed

Diff for: flang/include/flang/Lower/Allocatable.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
#include "flang/Lower/AbstractConverter.h"
1717
#include "flang/Optimizer/Builder/MutableBox.h"
18-
#include "flang/Runtime/allocator-registry.h"
18+
#include "flang/Runtime/allocator-registry-consts.h"
1919
#include "llvm/ADT/StringRef.h"
2020

2121
namespace mlir {

Diff for: flang/include/flang/Optimizer/Builder/IntrinsicCall.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "flang/Optimizer/Builder/Runtime/Numeric.h"
1717
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
1818
#include "flang/Runtime/entry-names.h"
19-
#include "flang/Runtime/iostat.h"
19+
#include "flang/Runtime/iostat-consts.h"
2020
#include "mlir/Dialect/Complex/IR/Complex.h"
2121
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
2222
#include "mlir/Dialect/Math/IR/Math.h"

Diff for: flang/include/flang/Optimizer/Builder/MutableBox.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#define FORTRAN_OPTIMIZER_BUILDER_MUTABLEBOX_H
1515

1616
#include "flang/Optimizer/Builder/BoxValue.h"
17-
#include "flang/Runtime/allocator-registry.h"
17+
#include "flang/Runtime/allocator-registry-consts.h"
1818
#include "llvm/ADT/StringRef.h"
1919

2020
namespace mlir {

Diff for: flang/include/flang/Optimizer/CodeGen/DescriptorModel.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#define OPTIMIZER_DESCRIPTOR_MODEL_H
2424

2525
#include "flang/ISO_Fortran_binding_wrapper.h"
26-
#include "flang/Runtime/descriptor.h"
26+
#include "flang/Runtime/descriptor-consts.h"
2727
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
2828
#include "mlir/IR/BuiltinTypes.h"
2929
#include "llvm/Support/ErrorHandling.h"

Diff for: flang/include/flang/Runtime/CUDA/allocatable.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef FORTRAN_RUNTIME_CUDA_ALLOCATABLE_H_
1010
#define FORTRAN_RUNTIME_CUDA_ALLOCATABLE_H_
1111

12-
#include "flang/Runtime/descriptor.h"
12+
#include "flang/Runtime/descriptor-consts.h"
1313
#include "flang/Runtime/entry-names.h"
1414

1515
namespace Fortran::runtime::cuda {

Diff for: flang/include/flang/Runtime/CUDA/allocator.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#define FORTRAN_RUNTIME_CUDA_ALLOCATOR_H_
1111

1212
#include "common.h"
13-
#include "flang/Runtime/descriptor.h"
13+
#include "flang/Runtime/descriptor-consts.h"
1414
#include "flang/Runtime/entry-names.h"
1515

1616
namespace Fortran::runtime::cuda {

Diff for: flang/include/flang/Runtime/CUDA/common.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef FORTRAN_RUNTIME_CUDA_COMMON_H_
1010
#define FORTRAN_RUNTIME_CUDA_COMMON_H_
1111

12-
#include "flang/Runtime/descriptor.h"
12+
#include "flang/Runtime/descriptor-consts.h"
1313
#include "flang/Runtime/entry-names.h"
1414

1515
/// Type of memory for allocation/deallocation

Diff for: flang/include/flang/Runtime/CUDA/descriptor.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef FORTRAN_RUNTIME_CUDA_DESCRIPTOR_H_
1010
#define FORTRAN_RUNTIME_CUDA_DESCRIPTOR_H_
1111

12-
#include "flang/Runtime/descriptor.h"
12+
#include "flang/Runtime/descriptor-consts.h"
1313
#include "flang/Runtime/entry-names.h"
1414
#include <cstddef>
1515

Diff for: flang/include/flang/Runtime/CUDA/memory.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef FORTRAN_RUNTIME_CUDA_MEMORY_H_
1010
#define FORTRAN_RUNTIME_CUDA_MEMORY_H_
1111

12-
#include "flang/Runtime/descriptor.h"
12+
#include "flang/Runtime/descriptor-consts.h"
1313
#include "flang/Runtime/entry-names.h"
1414
#include <cstddef>
1515

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- include/flang/Runtime/allocator-registry-consts.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_ALLOCATOR_REGISTRY_CONSTS_H_
10+
#define FORTRAN_RUNTIME_ALLOCATOR_REGISTRY_CONSTS_H_
11+
12+
static constexpr unsigned kDefaultAllocator = 0;
13+
14+
// Allocator used for CUF
15+
static constexpr unsigned kPinnedAllocatorPos = 1;
16+
static constexpr unsigned kDeviceAllocatorPos = 2;
17+
static constexpr unsigned kManagedAllocatorPos = 3;
18+
static constexpr unsigned kUnifiedAllocatorPos = 4;
19+
20+
#endif /* FORTRAN_RUNTIME_ALLOCATOR_REGISTRY_CONSTS_H_ */

Diff for: flang/include/flang/Runtime/allocator-registry.h

+1-8
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,11 @@
1010
#define FORTRAN_RUNTIME_ALLOCATOR_REGISTRY_H_
1111

1212
#include "flang/Common/api-attrs.h"
13+
#include "flang/Runtime/allocator-registry-consts.h"
1314
#include <cstdint>
1415
#include <cstdlib>
1516
#include <vector>
1617

17-
static constexpr unsigned kDefaultAllocator = 0;
18-
19-
// Allocator used for CUF
20-
static constexpr unsigned kPinnedAllocatorPos = 1;
21-
static constexpr unsigned kDeviceAllocatorPos = 2;
22-
static constexpr unsigned kManagedAllocatorPos = 3;
23-
static constexpr unsigned kUnifiedAllocatorPos = 4;
24-
2518
#define MAX_ALLOCATOR 7 // 3 bits are reserved in the descriptor.
2619

2720
namespace Fortran::runtime {
+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//===-- include/flang/Runtime/array-constructor-consts.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_ARRAY_CONSTRUCTOR_CONSTS_H_
10+
#define FORTRAN_RUNTIME_ARRAY_CONSTRUCTOR_CONSTS_H_
11+
12+
#include "flang/Runtime/descriptor-consts.h"
13+
#include "flang/Runtime/entry-names.h"
14+
#include <cstdint>
15+
16+
namespace Fortran::runtime {
17+
struct ArrayConstructorVector;
18+
19+
// Max sizeof(ArrayConstructorVector) and sizeof(ArrayConstructorVector) for any
20+
// target.
21+
// TODO: Use target-specific size/alignment instead of overapproximation.
22+
constexpr std::size_t MaxArrayConstructorVectorSizeInBytes = 2 * 40;
23+
constexpr std::size_t MaxArrayConstructorVectorAlignInBytes = 8;
24+
25+
// This file defines an API to "push" an evaluated array constructor value
26+
// "from" into some storage "to" of an array constructor. It can be seen as a
27+
// form of std::vector::push_back() implementation for Fortran array
28+
// constructors. In the APIs and ArrayConstructorVector struct above:
29+
//
30+
// - "to" is a ranked-1 descriptor whose declared type is already set to the
31+
// array constructor derived type. It may be already allocated, even before the
32+
// first call to this API, or it may be unallocated. "to" extent is increased
33+
// every time a "from" is pushed past its current extent. At this end of the
34+
// API calls, its extent is the extent of the array constructor. If "to" is
35+
// unallocated and its extent is not null, it is assumed this is the final array
36+
// constructor extent value, and the first allocation already "reserves" storage
37+
// space accordingly to avoid reallocations.
38+
// - "from" is a scalar or array descriptor for the evaluated array
39+
// constructor value that must be copied into the storage of "to" at
40+
// "nextValuePosition".
41+
// - "useValueLengthParameters" must be set to true if the array constructor
42+
// has length parameters and no type spec. If it is true and "to" is
43+
// unallocated, "to" will take the length parameters of "from". If it is true
44+
// and "to" is an allocated character array constructor, it will be checked
45+
// that "from" length matches the one from "to". When it is false, the
46+
// character length must already be set in "to" before the first call to this
47+
// API and "from" character lengths are allowed to mismatch from "to".
48+
// - "nextValuePosition" is the zero based sequence position of "from" in the
49+
// array constructor. It is updated after this call by the number of "from"
50+
// elements. It should be set to zero by the caller of this API before the first
51+
// call.
52+
// - "actualAllocationSize" is the current allocation size of "to" storage. It
53+
// may be bigger than "to" extent for reallocation optimization purposes, but
54+
// should never be smaller, unless this is the first call and "to" is
55+
// unallocated. It is updated by the runtime after each successful allocation or
56+
// reallocation. It should be set to "to" extent if "to" is allocated before the
57+
// first call of this API, and can be left undefined otherwise.
58+
//
59+
// Note that this API can be used with "to" being a variable (that can be
60+
// discontiguous). This can be done when the variable is the left hand side of
61+
// an assignment from an array constructor as long as:
62+
// - none of the ac-value overlaps with the variable,
63+
// - this is an intrinsic assignment that is not a whole allocatable
64+
// assignment, *and* for a type that has no components requiring user defined
65+
// assignments,
66+
// - the variable is properly finalized before using this API if its need to,
67+
// - "useValueLengthParameters" should be set to false in this case, even if
68+
// the array constructor has no type-spec, since the variable may have a
69+
// different character length than the array constructor values.
70+
71+
extern "C" {
72+
// API to initialize an ArrayConstructorVector before any values are pushed to
73+
// it. Inlined code is only expected to allocate the "ArrayConstructorVector"
74+
// class instance storage with sufficient size
75+
// (MaxArrayConstructorVectorSizeInBytes is expected to be large enough for all
76+
// supported targets). This avoids the need for the runtime to maintain a state,
77+
// or to use dynamic allocation for it.
78+
void RTDECL(InitArrayConstructorVector)(ArrayConstructorVector &vector,
79+
Descriptor &to, bool useValueLengthParameters,
80+
const char *sourceFile = nullptr, int sourceLine = 0);
81+
82+
// Generic API to push any kind of entity into the array constructor (any
83+
// Fortran type and any rank).
84+
void RTDECL(PushArrayConstructorValue)(
85+
ArrayConstructorVector &vector, const Descriptor &from);
86+
87+
// API to push scalar array constructor value of:
88+
// - a numerical or logical type,
89+
// - or a derived type that has no length parameters, and no allocatable
90+
// component (that would require deep copies).
91+
// It requires no descriptor for the value that is passed via its base address.
92+
void RTDECL(PushArrayConstructorSimpleScalar)(
93+
ArrayConstructorVector &vector, void *from);
94+
} // extern "C"
95+
} // namespace Fortran::runtime
96+
97+
#endif /* FORTRAN_RUNTIME_ARRAY_CONSTRUCTOR_CONSTS_H_ */

Diff for: flang/include/flang/Runtime/array-constructor.h

+9-70
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#ifndef FORTRAN_RUNTIME_ARRAYCONSTRUCTOR_H_
1313
#define FORTRAN_RUNTIME_ARRAYCONSTRUCTOR_H_
1414

15+
#include "flang/Runtime/array-constructor-consts.h"
1516
#include "flang/Runtime/descriptor.h"
1617
#include "flang/Runtime/entry-names.h"
1718
#include <cstdint>
@@ -43,76 +44,14 @@ struct ArrayConstructorVector {
4344
unsigned char useValueLengthParameters_ : 1;
4445
};
4546

46-
// This file defines an API to "push" an evaluated array constructor value
47-
// "from" into some storage "to" of an array constructor. It can be seen as a
48-
// form of std::vector::push_back() implementation for Fortran array
49-
// constructors. In the APIs and ArrayConstructorVector struct above:
50-
//
51-
// - "to" is a ranked-1 descriptor whose declared type is already set to the
52-
// array constructor derived type. It may be already allocated, even before the
53-
// first call to this API, or it may be unallocated. "to" extent is increased
54-
// every time a "from" is pushed past its current extent. At this end of the
55-
// API calls, its extent is the extent of the array constructor. If "to" is
56-
// unallocated and its extent is not null, it is assumed this is the final array
57-
// constructor extent value, and the first allocation already "reserves" storage
58-
// space accordingly to avoid reallocations.
59-
// - "from" is a scalar or array descriptor for the evaluated array
60-
// constructor value that must be copied into the storage of "to" at
61-
// "nextValuePosition".
62-
// - "useValueLengthParameters" must be set to true if the array constructor
63-
// has length parameters and no type spec. If it is true and "to" is
64-
// unallocated, "to" will take the length parameters of "from". If it is true
65-
// and "to" is an allocated character array constructor, it will be checked
66-
// that "from" length matches the one from "to". When it is false, the
67-
// character length must already be set in "to" before the first call to this
68-
// API and "from" character lengths are allowed to mismatch from "to".
69-
// - "nextValuePosition" is the zero based sequence position of "from" in the
70-
// array constructor. It is updated after this call by the number of "from"
71-
// elements. It should be set to zero by the caller of this API before the first
72-
// call.
73-
// - "actualAllocationSize" is the current allocation size of "to" storage. It
74-
// may be bigger than "to" extent for reallocation optimization purposes, but
75-
// should never be smaller, unless this is the first call and "to" is
76-
// unallocated. It is updated by the runtime after each successful allocation or
77-
// reallocation. It should be set to "to" extent if "to" is allocated before the
78-
// first call of this API, and can be left undefined otherwise.
79-
//
80-
// Note that this API can be used with "to" being a variable (that can be
81-
// discontiguous). This can be done when the variable is the left hand side of
82-
// an assignment from an array constructor as long as:
83-
// - none of the ac-value overlaps with the variable,
84-
// - this is an intrinsic assignment that is not a whole allocatable
85-
// assignment, *and* for a type that has no components requiring user defined
86-
// assignments,
87-
// - the variable is properly finalized before using this API if its need to,
88-
// - "useValueLengthParameters" should be set to false in this case, even if
89-
// the array constructor has no type-spec, since the variable may have a
90-
// different character length than the array constructor values.
91-
92-
extern "C" {
93-
// API to initialize an ArrayConstructorVector before any values are pushed to
94-
// it. Inlined code is only expected to allocate the "ArrayConstructorVector"
95-
// class instance storage with sufficient size (using
96-
// "2*sizeof(ArrayConstructorVector)" on the host should be safe regardless of
97-
// the target the runtime is compiled for). This avoids the need for the runtime
98-
// to maintain a state, or to use dynamic allocation for it. "vectorClassSize"
99-
// is used to validate that lowering allocated enough space for it.
100-
void RTDECL(InitArrayConstructorVector)(ArrayConstructorVector &vector,
101-
Descriptor &to, bool useValueLengthParameters, int vectorClassSize,
102-
const char *sourceFile = nullptr, int sourceLine = 0);
103-
104-
// Generic API to push any kind of entity into the array constructor (any
105-
// Fortran type and any rank).
106-
void RTDECL(PushArrayConstructorValue)(
107-
ArrayConstructorVector &vector, const Descriptor &from);
47+
static_assert(sizeof(Fortran::runtime::ArrayConstructorVector) <=
48+
MaxArrayConstructorVectorSizeInBytes,
49+
"ABI requires sizeof(ArrayConstructorVector) to be smaller than "
50+
"MaxArrayConstructorVectorSizeInBytes");
51+
static_assert(alignof(Fortran::runtime::ArrayConstructorVector) <=
52+
MaxArrayConstructorVectorAlignInBytes,
53+
"ABI requires alignof(ArrayConstructorVector) to be smaller than "
54+
"MaxArrayConstructorVectorAlignInBytes");
10855

109-
// API to push scalar array constructor value of:
110-
// - a numerical or logical type,
111-
// - or a derived type that has no length parameters, and no allocatable
112-
// component (that would require deep copies).
113-
// It requires no descriptor for the value that is passed via its base address.
114-
void RTDECL(PushArrayConstructorSimpleScalar)(
115-
ArrayConstructorVector &vector, void *from);
116-
} // extern "C"
11756
} // namespace Fortran::runtime
11857
#endif // FORTRAN_RUNTIME_ARRAYCONSTRUCTOR_H_

Diff for: flang/include/flang/Runtime/descriptor-consts.h

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===-- include/flang/Runtime/descriptor-consts.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_DESCRIPTOR_CONSTS_H_
10+
#define FORTRAN_RUNTIME_DESCRIPTOR_CONSTS_H_
11+
12+
#include "flang/Common/api-attrs.h"
13+
#include "flang/ISO_Fortran_binding_wrapper.h"
14+
#include <cstddef>
15+
#include <cstdint>
16+
17+
// Value of the addendum presence flag.
18+
#define _CFI_ADDENDUM_FLAG 1
19+
// Number of bits needed to be shifted when manipulating the allocator index.
20+
#define _CFI_ALLOCATOR_IDX_SHIFT 1
21+
// Allocator index mask.
22+
#define _CFI_ALLOCATOR_IDX_MASK 0b00001110
23+
24+
namespace Fortran::runtime::typeInfo {
25+
using TypeParameterValue = std::int64_t;
26+
class DerivedType;
27+
} // namespace Fortran::runtime::typeInfo
28+
29+
namespace Fortran::runtime {
30+
class Descriptor;
31+
using SubscriptValue = ISO::CFI_index_t;
32+
33+
/// Returns size in bytes of the descriptor (not the data)
34+
/// This must be at least as large as the largest descriptor of any target
35+
/// triple.
36+
static constexpr RT_API_ATTRS std::size_t MaxDescriptorSizeInBytes(
37+
int rank, bool addendum = false, int lengthTypeParameters = 0) {
38+
// Layout:
39+
//
40+
// fortran::runtime::Descriptor {
41+
// ISO::CFI_cdesc_t {
42+
// void *base_addr; (pointer -> up to 8 bytes)
43+
// size_t elem_len; (up to 8 bytes)
44+
// int version; (up to 4 bytes)
45+
// CFI_rank_t rank; (unsigned char -> 1 byte)
46+
// CFI_type_t type; (signed char -> 1 byte)
47+
// CFI_attribute_t attribute; (unsigned char -> 1 byte)
48+
// unsigned char extra; (1 byte)
49+
// }
50+
// }
51+
// fortran::runtime::Dimension[rank] {
52+
// ISO::CFI_dim_t {
53+
// CFI_index_t lower_bound; (ptrdiff_t -> up to 8 bytes)
54+
// CFI_index_t extent; (ptrdiff_t -> up to 8 bytes)
55+
// CFI_index_t sm; (ptrdiff_t -> up to 8 bytes)
56+
// }
57+
// }
58+
// fortran::runtime::DescriptorAddendum {
59+
// const typeInfo::DerivedType *derivedType_; (pointer -> up to 8
60+
// bytes) typeInfo::TypeParameterValue len_[lenParameters]; (int64_t -> 8
61+
// bytes)
62+
// }
63+
std::size_t bytes{24u + rank * 24u};
64+
if (addendum || lengthTypeParameters > 0) {
65+
if (lengthTypeParameters < 1)
66+
lengthTypeParameters = 1;
67+
bytes += 8u + static_cast<std::size_t>(lengthTypeParameters) * 8u;
68+
}
69+
return bytes;
70+
}
71+
72+
} // namespace Fortran::runtime
73+
74+
#endif /* FORTRAN_RUNTIME_DESCRIPTOR_CONSTS_H_ */

0 commit comments

Comments
 (0)