Skip to content

Commit

Permalink
[flang][runtime] Enable more APIs in the offload build. (#76486)
Browse files Browse the repository at this point in the history
  • Loading branch information
vzakhari committed Dec 28, 2023
1 parent 9c39d9b commit 76facde
Show file tree
Hide file tree
Showing 31 changed files with 580 additions and 409 deletions.
20 changes: 11 additions & 9 deletions flang/include/flang/Runtime/array-constructor.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,17 @@ namespace Fortran::runtime {
// Runtime data structure to hold information about the storage of
// an array constructor being constructed.
struct ArrayConstructorVector {
ArrayConstructorVector(class Descriptor &to, SubscriptValue nextValuePosition,
SubscriptValue actualAllocationSize, const char *sourceFile,
int sourceLine, bool useValueLengthParameters)
RT_API_ATTRS ArrayConstructorVector(class Descriptor &to,
SubscriptValue nextValuePosition, SubscriptValue actualAllocationSize,
const char *sourceFile, int sourceLine, bool useValueLengthParameters)
: to{to}, nextValuePosition{nextValuePosition},
actualAllocationSize{actualAllocationSize}, sourceFile{sourceFile},
sourceLine{sourceLine}, useValueLengthParameters_{
useValueLengthParameters} {}
sourceLine{sourceLine},
useValueLengthParameters_{useValueLengthParameters} {}

bool useValueLengthParameters() const { return useValueLengthParameters_; }
RT_API_ATTRS bool useValueLengthParameters() const {
return useValueLengthParameters_;
}

class Descriptor &to;
SubscriptValue nextValuePosition;
Expand Down Expand Up @@ -95,21 +97,21 @@ extern "C" {
// the target the runtime is compiled for). This avoids the need for the runtime
// to maintain a state, or to use dynamic allocation for it. "vectorClassSize"
// is used to validate that lowering allocated enough space for it.
void RTNAME(InitArrayConstructorVector)(ArrayConstructorVector &vector,
void RTDECL(InitArrayConstructorVector)(ArrayConstructorVector &vector,
Descriptor &to, bool useValueLengthParameters, int vectorClassSize,
const char *sourceFile = nullptr, int sourceLine = 0);

// Generic API to push any kind of entity into the array constructor (any
// Fortran type and any rank).
void RTNAME(PushArrayConstructorValue)(
void RTDECL(PushArrayConstructorValue)(
ArrayConstructorVector &vector, const Descriptor &from);

// API to push scalar array constructor value of:
// - a numerical or logical type,
// - or a derived type that has no length parameters, and no allocatable
// component (that would require deep copies).
// It requires no descriptor for the value that is passed via its base address.
void RTNAME(PushArrayConstructorSimpleScalar)(
void RTDECL(PushArrayConstructorSimpleScalar)(
ArrayConstructorVector &vector, void *from);
} // extern "C"
} // namespace Fortran::runtime
Expand Down
76 changes: 39 additions & 37 deletions flang/include/flang/Runtime/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ namespace Fortran::runtime {
class Descriptor;

template <typename CHAR>
int CharacterScalarCompare(
RT_API_ATTRS int CharacterScalarCompare(
const CHAR *x, const CHAR *y, std::size_t xChars, std::size_t yChars);
extern template int CharacterScalarCompare<char>(
extern template RT_API_ATTRS int CharacterScalarCompare<char>(
const char *x, const char *y, std::size_t xChars, std::size_t yChars);
extern template int CharacterScalarCompare<char16_t>(const char16_t *x,
const char16_t *y, std::size_t xChars, std::size_t yChars);
extern template int CharacterScalarCompare<char32_t>(const char32_t *x,
const char32_t *y, std::size_t xChars, std::size_t yChars);
extern template RT_API_ATTRS int CharacterScalarCompare<char16_t>(
const char16_t *x, const char16_t *y, std::size_t xChars,
std::size_t yChars);
extern template RT_API_ATTRS int CharacterScalarCompare<char32_t>(
const char32_t *x, const char32_t *y, std::size_t xChars,
std::size_t yChars);

extern "C" {

Expand All @@ -36,12 +38,12 @@ extern "C" {
// initialized CHARACTER allocatable scalar or array descriptor -- use
// AllocatableInitCharacter() to set one up. Crashes when not
// conforming. Assumes independence of data.
void RTNAME(CharacterConcatenate)(Descriptor &accumulator,
void RTDECL(CharacterConcatenate)(Descriptor &accumulator,
const Descriptor &from, const char *sourceFile = nullptr,
int sourceLine = 0);

// Convenience specialization for ASCII scalars concatenation.
void RTNAME(CharacterConcatenateScalar1)(
void RTDECL(CharacterConcatenateScalar1)(
Descriptor &accumulator, const char *from, std::size_t chars);

// CHARACTER comparisons. The kinds must match. Like std::memcmp(),
Expand All @@ -52,77 +54,77 @@ void RTNAME(CharacterConcatenateScalar1)(
// N.B.: Calls to the restricted specific intrinsic functions LGE, LGT, LLE,
// & LLT are converted into calls to these during lowering; they don't have
// to be able to be passed as actual procedure arguments.
int RTNAME(CharacterCompareScalar)(const Descriptor &, const Descriptor &);
int RTNAME(CharacterCompareScalar1)(
int RTDECL(CharacterCompareScalar)(const Descriptor &, const Descriptor &);
int RTDECL(CharacterCompareScalar1)(
const char *x, const char *y, std::size_t xChars, std::size_t yChars);
int RTNAME(CharacterCompareScalar2)(const char16_t *x, const char16_t *y,
int RTDECL(CharacterCompareScalar2)(const char16_t *x, const char16_t *y,
std::size_t xChars, std::size_t yChars);
int RTNAME(CharacterCompareScalar4)(const char32_t *x, const char32_t *y,
int RTDECL(CharacterCompareScalar4)(const char32_t *x, const char32_t *y,
std::size_t xChars, std::size_t yChars);

// General CHARACTER comparison; the result is a LOGICAL(KIND=1) array that
// is established and populated.
void RTNAME(CharacterCompare)(
void RTDECL(CharacterCompare)(
Descriptor &result, const Descriptor &, const Descriptor &);

// Special-case support for optimized ASCII scalar expressions.

// Copies data from 'rhs' to the remaining space (lhsLength - offset)
// in 'lhs', if any. Returns the new offset. Assumes independence.
std::size_t RTNAME(CharacterAppend1)(char *lhs, std::size_t lhsBytes,
std::size_t RTDECL(CharacterAppend1)(char *lhs, std::size_t lhsBytes,
std::size_t offset, const char *rhs, std::size_t rhsBytes);

// Appends any necessary spaces to a CHARACTER(KIND=1) scalar.
void RTNAME(CharacterPad1)(char *lhs, std::size_t bytes, std::size_t offset);
void RTDECL(CharacterPad1)(char *lhs, std::size_t bytes, std::size_t offset);

// Intrinsic functions
// The result descriptors below are all established by the runtime.
void RTNAME(Adjustl)(Descriptor &result, const Descriptor &,
void RTDECL(Adjustl)(Descriptor &result, const Descriptor &,
const char *sourceFile = nullptr, int sourceLine = 0);
void RTNAME(Adjustr)(Descriptor &result, const Descriptor &,
void RTDECL(Adjustr)(Descriptor &result, const Descriptor &,
const char *sourceFile = nullptr, int sourceLine = 0);
std::size_t RTNAME(LenTrim1)(const char *, std::size_t);
std::size_t RTNAME(LenTrim2)(const char16_t *, std::size_t);
std::size_t RTNAME(LenTrim4)(const char32_t *, std::size_t);
void RTNAME(LenTrim)(Descriptor &result, const Descriptor &, int kind,
std::size_t RTDECL(LenTrim1)(const char *, std::size_t);
std::size_t RTDECL(LenTrim2)(const char16_t *, std::size_t);
std::size_t RTDECL(LenTrim4)(const char32_t *, std::size_t);
void RTDECL(LenTrim)(Descriptor &result, const Descriptor &, int kind,
const char *sourceFile = nullptr, int sourceLine = 0);
void RTNAME(Repeat)(Descriptor &result, const Descriptor &string,
void RTDECL(Repeat)(Descriptor &result, const Descriptor &string,
std::int64_t ncopies, const char *sourceFile = nullptr, int sourceLine = 0);
void RTNAME(Trim)(Descriptor &result, const Descriptor &string,
void RTDECL(Trim)(Descriptor &result, const Descriptor &string,
const char *sourceFile = nullptr, int sourceLine = 0);

void RTNAME(CharacterMax)(Descriptor &accumulator, const Descriptor &x,
void RTDECL(CharacterMax)(Descriptor &accumulator, const Descriptor &x,
const char *sourceFile = nullptr, int sourceLine = 0);
void RTNAME(CharacterMin)(Descriptor &accumulator, const Descriptor &x,
void RTDECL(CharacterMin)(Descriptor &accumulator, const Descriptor &x,
const char *sourceFile = nullptr, int sourceLine = 0);

std::size_t RTNAME(Index1)(const char *, std::size_t, const char *substring,
std::size_t RTDECL(Index1)(const char *, std::size_t, const char *substring,
std::size_t, bool back = false);
std::size_t RTNAME(Index2)(const char16_t *, std::size_t,
std::size_t RTDECL(Index2)(const char16_t *, std::size_t,
const char16_t *substring, std::size_t, bool back = false);
std::size_t RTNAME(Index4)(const char32_t *, std::size_t,
std::size_t RTDECL(Index4)(const char32_t *, std::size_t,
const char32_t *substring, std::size_t, bool back = false);
void RTNAME(Index)(Descriptor &result, const Descriptor &string,
void RTDECL(Index)(Descriptor &result, const Descriptor &string,
const Descriptor &substring, const Descriptor *back /*can be null*/,
int kind, const char *sourceFile = nullptr, int sourceLine = 0);

std::size_t RTNAME(Scan1)(
std::size_t RTDECL(Scan1)(
const char *, std::size_t, const char *set, std::size_t, bool back = false);
std::size_t RTNAME(Scan2)(const char16_t *, std::size_t, const char16_t *set,
std::size_t RTDECL(Scan2)(const char16_t *, std::size_t, const char16_t *set,
std::size_t, bool back = false);
std::size_t RTNAME(Scan4)(const char32_t *, std::size_t, const char32_t *set,
std::size_t RTDECL(Scan4)(const char32_t *, std::size_t, const char32_t *set,
std::size_t, bool back = false);
void RTNAME(Scan)(Descriptor &result, const Descriptor &string,
void RTDECL(Scan)(Descriptor &result, const Descriptor &string,
const Descriptor &set, const Descriptor *back /*can be null*/, int kind,
const char *sourceFile = nullptr, int sourceLine = 0);

std::size_t RTNAME(Verify1)(
std::size_t RTDECL(Verify1)(
const char *, std::size_t, const char *set, std::size_t, bool back = false);
std::size_t RTNAME(Verify2)(const char16_t *, std::size_t, const char16_t *set,
std::size_t RTDECL(Verify2)(const char16_t *, std::size_t, const char16_t *set,
std::size_t, bool back = false);
std::size_t RTNAME(Verify4)(const char32_t *, std::size_t, const char32_t *set,
std::size_t RTDECL(Verify4)(const char32_t *, std::size_t, const char32_t *set,
std::size_t, bool back = false);
void RTNAME(Verify)(Descriptor &result, const Descriptor &string,
void RTDECL(Verify)(Descriptor &result, const Descriptor &string,
const Descriptor &set, const Descriptor *back /*can be null*/, int kind,
const char *sourceFile = nullptr, int sourceLine = 0);
}
Expand Down
7 changes: 4 additions & 3 deletions flang/include/flang/Runtime/descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,16 @@ class Dimension {
}
// Do not use this API to cause the LB of an empty dimension
// to be anything other than 1. Use SetBounds() instead if you can.
Dimension &SetLowerBound(SubscriptValue lower) {
RT_API_ATTRS Dimension &SetLowerBound(SubscriptValue lower) {
raw_.lower_bound = lower;
return *this;
}
Dimension &SetUpperBound(SubscriptValue upper) {
RT_API_ATTRS Dimension &SetUpperBound(SubscriptValue upper) {
auto lower{raw_.lower_bound};
raw_.extent = upper >= lower ? upper - lower + 1 : 0;
return *this;
}
Dimension &SetExtent(SubscriptValue extent) {
RT_API_ATTRS Dimension &SetExtent(SubscriptValue extent) {
raw_.extent = extent;
return *this;
}
Expand Down Expand Up @@ -467,5 +467,6 @@ class alignas(Descriptor) StaticDescriptor {
private:
char storage_[byteSize]{};
};

} // namespace Fortran::runtime
#endif // FORTRAN_RUNTIME_DESCRIPTOR_H_
8 changes: 4 additions & 4 deletions flang/include/flang/Runtime/inquiry.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ class Descriptor;

extern "C" {

std::int64_t RTNAME(LboundDim)(const Descriptor &array, int dim,
std::int64_t RTDECL(LboundDim)(const Descriptor &array, int dim,
const char *sourceFile = nullptr, int line = 0);
void RTNAME(Ubound)(Descriptor &result, const Descriptor &array, int kind,
void RTDECL(Ubound)(Descriptor &result, const Descriptor &array, int kind,
const char *sourceFile = nullptr, int line = 0);
std::int64_t RTNAME(Size)(
std::int64_t RTDECL(Size)(
const Descriptor &array, const char *sourceFile = nullptr, int line = 0);
std::int64_t RTNAME(SizeDim)(const Descriptor &array, int dim,
std::int64_t RTDECL(SizeDim)(const Descriptor &array, int dim,
const char *sourceFile = nullptr, int line = 0);

} // extern "C"
Expand Down
7 changes: 5 additions & 2 deletions flang/include/flang/Runtime/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ class Terminator;

[[nodiscard]] RT_API_ATTRS void *AllocateMemoryOrCrash(
const Terminator &, std::size_t bytes);
template <typename A> [[nodiscard]] A &AllocateOrCrash(const Terminator &t) {
template <typename A>
[[nodiscard]] RT_API_ATTRS A &AllocateOrCrash(const Terminator &t) {
return *reinterpret_cast<A *>(AllocateMemoryOrCrash(t, sizeof(A)));
}
RT_API_ATTRS void *ReallocateMemoryOrCrash(
const Terminator &, void *ptr, std::size_t newByteSize);
RT_API_ATTRS void FreeMemory(void *);
template <typename A> RT_API_ATTRS void FreeMemory(A *p) {
FreeMemory(reinterpret_cast<void *>(p));
}
template <typename A> void FreeMemoryAndNullify(A *&p) {
template <typename A> RT_API_ATTRS void FreeMemoryAndNullify(A *&p) {
FreeMemory(p);
p = nullptr;
}
Expand Down
4 changes: 2 additions & 2 deletions flang/include/flang/Runtime/misc-intrinsic.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ namespace Fortran::runtime {
class Descriptor;

extern "C" {
void RTNAME(Transfer)(Descriptor &result, const Descriptor &source,
void RTDECL(Transfer)(Descriptor &result, const Descriptor &source,
const Descriptor &mold, const char *sourceFile, int line);
void RTNAME(TransferSize)(Descriptor &result, const Descriptor &source,
void RTDECL(TransferSize)(Descriptor &result, const Descriptor &source,
const Descriptor &mold, const char *sourceFile, int line,
std::int64_t size);
} // extern "C"
Expand Down
36 changes: 18 additions & 18 deletions flang/include/flang/Runtime/pointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,45 +21,45 @@ extern "C" {
// Data pointer initialization for NULLIFY(), "p=>NULL()`, & for ALLOCATE().

// Initializes a pointer to a disassociated state for NULLIFY() or "p=>NULL()".
void RTNAME(PointerNullifyIntrinsic)(
void RTDECL(PointerNullifyIntrinsic)(
Descriptor &, TypeCategory, int kind, int rank = 0, int corank = 0);
void RTNAME(PointerNullifyCharacter)(Descriptor &, SubscriptValue length = 0,
void RTDECL(PointerNullifyCharacter)(Descriptor &, SubscriptValue length = 0,
int kind = 1, int rank = 0, int corank = 0);
void RTNAME(PointerNullifyDerived)(
void RTDECL(PointerNullifyDerived)(
Descriptor &, const typeInfo::DerivedType &, int rank = 0, int corank = 0);

// Explicitly sets the bounds of an initialized disassociated pointer.
// The upper cobound is ignored for the last codimension.
void RTNAME(PointerSetBounds)(
void RTDECL(PointerSetBounds)(
Descriptor &, int zeroBasedDim, SubscriptValue lower, SubscriptValue upper);
void RTNAME(PointerSetCoBounds)(Descriptor &, int zeroBasedCoDim,
void RTDECL(PointerSetCoBounds)(Descriptor &, int zeroBasedCoDim,
SubscriptValue lower, SubscriptValue upper = 0);

// Length type parameters are indexed in declaration order; i.e., 0 is the
// first length type parameter in the deepest base type. (Not for use
// with CHARACTER; see above.)
void RTNAME(PointerSetDerivedLength)(Descriptor &, int which, SubscriptValue);
void RTDECL(PointerSetDerivedLength)(Descriptor &, int which, SubscriptValue);

// For MOLD= allocation: acquires information from another descriptor
// to initialize a null data pointer.
void RTNAME(PointerApplyMold)(
void RTDECL(PointerApplyMold)(
Descriptor &, const Descriptor &mold, int rank = 0);

// Data pointer association for "p=>TARGET"

// Associates a scalar pointer with a simple scalar target.
void RTNAME(PointerAssociateScalar)(Descriptor &, void *);
void RTDECL(PointerAssociateScalar)(Descriptor &, void *);

// Associates a pointer with a target of the same rank, possibly with new lower
// bounds, which are passed in a vector whose length must equal the rank.
void RTNAME(PointerAssociate)(Descriptor &, const Descriptor &target);
void RTNAME(PointerAssociateLowerBounds)(
void RTDECL(PointerAssociate)(Descriptor &, const Descriptor &target);
void RTDECL(PointerAssociateLowerBounds)(
Descriptor &, const Descriptor &target, const Descriptor &lowerBounds);

// Associates a pointer with a target with bounds remapping. The target must be
// simply contiguous &/or of rank 1. The bounds constitute a [2,newRank]
// integer array whose columns are [lower bound, upper bound] on each dimension.
void RTNAME(PointerAssociateRemapping)(Descriptor &, const Descriptor &target,
void RTDECL(PointerAssociateRemapping)(Descriptor &, const Descriptor &target,
const Descriptor &bounds, const char *sourceFile = nullptr,
int sourceLine = 0);

Expand All @@ -70,7 +70,7 @@ void RTNAME(PointerAssociateRemapping)(Descriptor &, const Descriptor &target,
// a derived type or CHARACTER value, the explicit value has to match
// the length type parameter's value. This API checks that requirement.
// Returns 0 for success, or the STAT= value on failure with hasStat==true.
int RTNAME(PointerCheckLengthParameter)(Descriptor &,
int RTDECL(PointerCheckLengthParameter)(Descriptor &,
int which /* 0 for CHARACTER length */, SubscriptValue other,
bool hasStat = false, const Descriptor *errMsg = nullptr,
const char *sourceFile = nullptr, int sourceLine = 0);
Expand All @@ -83,10 +83,10 @@ int RTNAME(PointerCheckLengthParameter)(Descriptor &,
// Successfully allocated memory is initialized if the pointer has a
// derived type, and is always initialized by PointerAllocateSource().
// Performs all necessary coarray synchronization and validation actions.
int RTNAME(PointerAllocate)(Descriptor &, bool hasStat = false,
int RTDECL(PointerAllocate)(Descriptor &, bool hasStat = false,
const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr,
int sourceLine = 0);
int RTNAME(PointerAllocateSource)(Descriptor &, const Descriptor &source,
int RTDECL(PointerAllocateSource)(Descriptor &, const Descriptor &source,
bool hasStat = false, const Descriptor *errMsg = nullptr,
const char *sourceFile = nullptr, int sourceLine = 0);

Expand All @@ -95,24 +95,24 @@ int RTNAME(PointerAllocateSource)(Descriptor &, const Descriptor &source,
// Finalizes elements &/or components as needed. The pointer is left
// in an initialized disassociated state suitable for reallocation
// with the same bounds, cobounds, and length type parameters.
int RTNAME(PointerDeallocate)(Descriptor &, bool hasStat = false,
int RTDECL(PointerDeallocate)(Descriptor &, bool hasStat = false,
const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr,
int sourceLine = 0);

// Same as PointerDeallocate but also set the dynamic type as the declared type
// as mentioned in 7.3.2.3 note 7.
int RTNAME(PointerDeallocatePolymorphic)(Descriptor &,
int RTDECL(PointerDeallocatePolymorphic)(Descriptor &,
const typeInfo::DerivedType *, bool hasStat = false,
const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr,
int sourceLine = 0);

// Association inquiries for ASSOCIATED()

// True when the pointer is not disassociated.
bool RTNAME(PointerIsAssociated)(const Descriptor &);
bool RTDECL(PointerIsAssociated)(const Descriptor &);

// True when the pointer is associated with a specific target.
bool RTNAME(PointerIsAssociatedWith)(
bool RTDECL(PointerIsAssociatedWith)(
const Descriptor &, const Descriptor *target);

} // extern "C"
Expand Down

0 comments on commit 76facde

Please sign in to comment.