Skip to content

[flang][runtime] Enable more APIs in the offload build. #76486

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading