Skip to content

Commit b278fe3

Browse files
authored
[flang][runtime][NFC] Allow different memmove function in assign (#114301)
- Add a parameter to the `Assign` function to be able to use a different `memmove` function. This is preparatory work to be able to use the `Assign` function between host and device data. - Expose the `Assign` function so it can be used from different files. - The new `memmoveFct` is not used in `BlankPadCharacterAssignment` yet since it is not clear if there is a need. It will be updated in case it is needed.
1 parent 718d50d commit b278fe3

File tree

2 files changed

+32
-19
lines changed

2 files changed

+32
-19
lines changed

flang/include/flang/Runtime/assign.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,35 @@
2424
#define FORTRAN_RUNTIME_ASSIGN_H_
2525

2626
#include "flang/Runtime/entry-names.h"
27+
#include "flang/Runtime/freestanding-tools.h"
2728

2829
namespace Fortran::runtime {
2930
class Descriptor;
31+
class Terminator;
32+
33+
enum AssignFlags {
34+
NoAssignFlags = 0,
35+
MaybeReallocate = 1 << 0,
36+
NeedFinalization = 1 << 1,
37+
CanBeDefinedAssignment = 1 << 2,
38+
ComponentCanBeDefinedAssignment = 1 << 3,
39+
ExplicitLengthCharacterLHS = 1 << 4,
40+
PolymorphicLHS = 1 << 5,
41+
DeallocateLHS = 1 << 6
42+
};
43+
44+
using MemmoveFct = void *(*)(void *, const void *, std::size_t);
45+
46+
static RT_API_ATTRS void *MemmoveWrapper(
47+
void *dest, const void *src, std::size_t count) {
48+
return Fortran::runtime::memmove(dest, src, count);
49+
}
50+
51+
RT_API_ATTRS void Assign(Descriptor &to, const Descriptor &from,
52+
Terminator &terminator, int flags, MemmoveFct memmoveFct = &MemmoveWrapper);
3053

3154
extern "C" {
55+
3256
// API for lowering assignment
3357
void RTDECL(Assign)(Descriptor &to, const Descriptor &from,
3458
const char *sourceFile = nullptr, int sourceLine = 0);

flang/runtime/assign.cpp

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,6 @@
1717

1818
namespace Fortran::runtime {
1919

20-
enum AssignFlags {
21-
NoAssignFlags = 0,
22-
MaybeReallocate = 1 << 0,
23-
NeedFinalization = 1 << 1,
24-
CanBeDefinedAssignment = 1 << 2,
25-
ComponentCanBeDefinedAssignment = 1 << 3,
26-
ExplicitLengthCharacterLHS = 1 << 4,
27-
PolymorphicLHS = 1 << 5,
28-
DeallocateLHS = 1 << 6
29-
};
30-
3120
// Predicate: is the left-hand side of an assignment an allocated allocatable
3221
// that must be deallocated?
3322
static inline RT_API_ATTRS bool MustDeallocateLHS(
@@ -250,8 +239,8 @@ static RT_API_ATTRS void BlankPadCharacterAssignment(Descriptor &to,
250239
// of elements, but their shape need not to conform (the assignment is done in
251240
// element sequence order). This facilitates some internal usages, like when
252241
// dealing with array constructors.
253-
RT_API_ATTRS static void Assign(
254-
Descriptor &to, const Descriptor &from, Terminator &terminator, int flags) {
242+
RT_API_ATTRS void Assign(Descriptor &to, const Descriptor &from,
243+
Terminator &terminator, int flags, MemmoveFct memmoveFct) {
255244
bool mustDeallocateLHS{(flags & DeallocateLHS) ||
256245
MustDeallocateLHS(to, from, terminator, flags)};
257246
DescriptorAddendum *toAddendum{to.Addendum()};
@@ -423,14 +412,14 @@ RT_API_ATTRS static void Assign(
423412
Assign(toCompDesc, fromCompDesc, terminator, nestedFlags);
424413
} else { // Component has intrinsic type; simply copy raw bytes
425414
std::size_t componentByteSize{comp.SizeInBytes(to)};
426-
Fortran::runtime::memmove(to.Element<char>(toAt) + comp.offset(),
415+
memmoveFct(to.Element<char>(toAt) + comp.offset(),
427416
from.Element<const char>(fromAt) + comp.offset(),
428417
componentByteSize);
429418
}
430419
break;
431420
case typeInfo::Component::Genre::Pointer: {
432421
std::size_t componentByteSize{comp.SizeInBytes(to)};
433-
Fortran::runtime::memmove(to.Element<char>(toAt) + comp.offset(),
422+
memmoveFct(to.Element<char>(toAt) + comp.offset(),
434423
from.Element<const char>(fromAt) + comp.offset(),
435424
componentByteSize);
436425
} break;
@@ -476,14 +465,14 @@ RT_API_ATTRS static void Assign(
476465
const auto &procPtr{
477466
*procPtrDesc.ZeroBasedIndexedElement<typeInfo::ProcPtrComponent>(
478467
k)};
479-
Fortran::runtime::memmove(to.Element<char>(toAt) + procPtr.offset,
468+
memmoveFct(to.Element<char>(toAt) + procPtr.offset,
480469
from.Element<const char>(fromAt) + procPtr.offset,
481470
sizeof(typeInfo::ProcedurePointer));
482471
}
483472
}
484473
} else { // intrinsic type, intrinsic assignment
485474
if (isSimpleMemmove()) {
486-
Fortran::runtime::memmove(to.raw().base_addr, from.raw().base_addr,
475+
memmoveFct(to.raw().base_addr, from.raw().base_addr,
487476
toElements * toElementBytes);
488477
} else if (toElementBytes > fromElementBytes) { // blank padding
489478
switch (to.type().raw()) {
@@ -507,8 +496,8 @@ RT_API_ATTRS static void Assign(
507496
} else { // elemental copies, possibly with character truncation
508497
for (std::size_t n{toElements}; n-- > 0;
509498
to.IncrementSubscripts(toAt), from.IncrementSubscripts(fromAt)) {
510-
Fortran::runtime::memmove(to.Element<char>(toAt),
511-
from.Element<const char>(fromAt), toElementBytes);
499+
memmoveFct(to.Element<char>(toAt), from.Element<const char>(fromAt),
500+
toElementBytes);
512501
}
513502
}
514503
}

0 commit comments

Comments
 (0)