Skip to content

Commit 7792dbe

Browse files
authored
Reland '[flang][runtime] Allow different memmov function in assign' (#114587)
Reland #114301
1 parent 0cfcd38 commit 7792dbe

File tree

3 files changed

+39
-20
lines changed

3 files changed

+39
-20
lines changed

flang/include/flang/Runtime/assign.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,40 @@
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+
#ifdef RT_DEVICE_COMPILATION
47+
static RT_API_ATTRS void *MemmoveWrapper(
48+
void *dest, const void *src, std::size_t count) {
49+
return Fortran::runtime::memmove(dest, src, count);
50+
}
51+
RT_API_ATTRS void Assign(Descriptor &to, const Descriptor &from,
52+
Terminator &terminator, int flags, MemmoveFct memmoveFct = &MemmoveWrapper);
53+
#else
54+
RT_API_ATTRS void Assign(Descriptor &to, const Descriptor &from,
55+
Terminator &terminator, int flags,
56+
MemmoveFct memmoveFct = &Fortran::runtime::memmove);
57+
#endif
3058

3159
extern "C" {
60+
3261
// API for lowering assignment
3362
void RTDECL(Assign)(Descriptor &to, const Descriptor &from,
3463
const char *sourceFile = nullptr, int sourceLine = 0);

flang/include/flang/Runtime/freestanding-tools.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ using std::fill_n;
8282
#if STD_MEMMOVE_UNSUPPORTED
8383
// Provides alternative implementation for std::memmove(), if
8484
// it is not supported.
85-
static inline RT_API_ATTRS void memmove(
85+
static inline RT_API_ATTRS void *memmove(
8686
void *dest, const void *src, std::size_t count) {
8787
char *to{reinterpret_cast<char *>(dest)};
8888
const char *from{reinterpret_cast<const char *>(src)};
@@ -103,6 +103,7 @@ static inline RT_API_ATTRS void memmove(
103103
*--to = *--from;
104104
}
105105
}
106+
return dest;
106107
}
107108
#else // !STD_MEMMOVE_UNSUPPORTED
108109
using std::memmove;

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)