Skip to content

Commit 15949dd

Browse files
authored
Merge pull request #176 from ROCm/dp_flangrt_hostdev_builtins
[flang][OpenMP] Make FlangRuntime offload use builtins vs. libc
2 parents 31ffc5f + c216291 commit 15949dd

File tree

8 files changed

+95
-21
lines changed

8 files changed

+95
-21
lines changed

flang/include/flang/Decimal/binary-floating-point.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ enum FortranRounding {
3232

3333
template <int BINARY_PRECISION> class BinaryFloatingPointNumber {
3434
public:
35+
RT_OFFLOAD_VAR_GROUP_BEGIN
3536
static constexpr common::RealCharacteristics realChars{BINARY_PRECISION};
3637
static constexpr int binaryPrecision{BINARY_PRECISION};
3738
static constexpr int bits{realChars.bits};
@@ -47,7 +48,6 @@ template <int BINARY_PRECISION> class BinaryFloatingPointNumber {
4748

4849
using RawType = common::HostUnsignedIntType<bits>;
4950
static_assert(CHAR_BIT * sizeof(RawType) >= bits);
50-
RT_OFFLOAD_VAR_GROUP_BEGIN
5151
static constexpr RawType significandMask{(RawType{1} << significandBits) - 1};
5252

5353
constexpr RT_API_ATTRS BinaryFloatingPointNumber() {} // zero

flang/include/flang/Runtime/allocator-registry.h

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <cstdlib>
1414
#include <vector>
1515

16+
RT_OFFLOAD_VAR_GROUP_BEGIN
17+
1618
static constexpr unsigned kDefaultAllocator = 0;
1719

1820
// Allocator used for CUF
@@ -21,6 +23,8 @@ static constexpr unsigned kDeviceAllocatorPos = 2;
2123
static constexpr unsigned kManagedAllocatorPos = 3;
2224
static constexpr unsigned kUnifiedAllocatorPos = 4;
2325

26+
RT_OFFLOAD_VAR_GROUP_END
27+
2428
#define MAX_ALLOCATOR 7 // 3 bits are reserved in the descriptor.
2529

2630
namespace Fortran::runtime {

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

+72-3
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,26 @@
6363
#define STD_TOUPPER_UNSUPPORTED 1
6464
#endif
6565

66+
#if defined(OMP_OFFLOAD_BUILD) || defined(OMP_NOHOST_BUILD)
67+
// #pragma message "OMP_OFFLOAD_BUILD or OMP_NOHOST_BUILD is defined"
68+
#define STD_LIBC_UNSUPPORTED 1
69+
#define STD_FILL_N_UNSUPPORTED 1
70+
#define STD_MEMSET_BUILTIN 1
71+
#define STD_MEMSET_UNSUPPORTED 1
72+
#define STD_MEMCPY_BUILTIN 1
73+
#define STD_MEMCPY_UNSUPPORTED 1
74+
#define STD_MEMMOVE_BUILTIN 1
75+
#define STD_MEMMOVE_UNSUPPORTED 1
76+
// #define STD_STRLEN_BUILTIN 1 // still resolves to strlen
77+
#define STD_STRLEN_UNSUPPORTED 1
78+
#define STD_MEMCMP_UNSUPPORTED 1
79+
#define STD_REALLOC_UNSUPPORTED 1
80+
#define STD_MEMCHR_UNSUPPORTED 1
81+
#define STD_STRCPY_UNSUPPORTED 1
82+
#define STD_STRCMP_UNSUPPORTED 1
83+
#define STD_TOUPPER_UNSUPPORTED 1
84+
#endif
85+
6686
namespace Fortran::runtime {
6787

6888
#if STD_FILL_N_UNSUPPORTED
@@ -79,7 +99,52 @@ fill_n(A *start, std::size_t count, const B &value) {
7999
using std::fill_n;
80100
#endif // !STD_FILL_N_UNSUPPORTED
81101

82-
#if STD_MEMMOVE_UNSUPPORTED
102+
#if STD_MEMSET_BUILTIN
103+
static inline RT_API_ATTRS void memset(
104+
void *dest, uint8_t value, std::size_t count) {
105+
__builtin_memset(dest, value, count);
106+
}
107+
#elif STD_MEMSET_UNSUPPORTED
108+
static inline RT_API_ATTRS void memset(
109+
void *dest, uint8_t value, std::size_t count) {
110+
char *to{reinterpret_cast<char *>(dest)};
111+
while (count--) {
112+
*to++ = value;
113+
}
114+
return;
115+
}
116+
#else
117+
using std::memset;
118+
#endif
119+
120+
#if STD_MEMCPY_BUILTIN
121+
static inline RT_API_ATTRS void memcpy(
122+
void *dest, const void *src, std::size_t count) {
123+
__builtin_memcpy(dest, src, count);
124+
}
125+
#elif STD_MEMCPY_UNSUPPORTED
126+
static inline RT_API_ATTRS void memcpy(
127+
void *dest, const void *src, std::size_t count) {
128+
char *to{reinterpret_cast<char *>(dest)};
129+
const char *from{reinterpret_cast<const char *>(src)};
130+
if (to == from) {
131+
return;
132+
}
133+
while (count--) {
134+
*to++ = *from++;
135+
}
136+
return;
137+
}
138+
#else
139+
using std::memcpy;
140+
#endif
141+
142+
#if STD_MEMMOVE_BUILTIN
143+
static inline RT_API_ATTRS void memmove(
144+
void *dest, const void *src, std::size_t count) {
145+
__builtin_memmove(dest, src, count);
146+
}
147+
#elif STD_MEMMOVE_UNSUPPORTED
83148
// Provides alternative implementation for std::memmove(), if
84149
// it is not supported.
85150
static inline RT_API_ATTRS void memmove(
@@ -91,7 +156,7 @@ static inline RT_API_ATTRS void memmove(
91156
return;
92157
}
93158
if (to + count <= from || from + count <= to) {
94-
std::memcpy(dest, src, count);
159+
memcpy(dest, src, count);
95160
} else if (to < from) {
96161
while (count--) {
97162
*to++ = *from++;
@@ -108,7 +173,11 @@ static inline RT_API_ATTRS void memmove(
108173
using std::memmove;
109174
#endif // !STD_MEMMOVE_UNSUPPORTED
110175

111-
#if STD_STRLEN_UNSUPPORTED
176+
#if STD_STRLEN_BUILTIN
177+
static inline RT_API_ATTRS std::size_t strlen(const char *str) {
178+
return __builtin_strlen(str);
179+
}
180+
#elif STD_STRLEN_UNSUPPORTED
112181
// Provides alternative implementation for std::strlen(), if
113182
// it is not supported.
114183
static inline RT_API_ATTRS std::size_t strlen(const char *str) {

flang/runtime/assign.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -274,15 +274,15 @@ RT_API_ATTRS static void Assign(
274274
if (MayAlias(to, from)) {
275275
if (mustDeallocateLHS) {
276276
deferDeallocation = &deferredDeallocStatDesc.descriptor();
277-
std::memcpy(deferDeallocation, &to, to.SizeInBytes());
277+
Fortran::runtime::memcpy(deferDeallocation, &to, to.SizeInBytes());
278278
to.set_base_addr(nullptr);
279279
} else if (!isSimpleMemmove()) {
280280
// Handle LHS/RHS aliasing by copying RHS into a temp, then
281281
// recursively assigning from that temp.
282282
auto descBytes{from.SizeInBytes()};
283283
StaticDescriptor<maxRank, true, 16> staticDesc;
284284
Descriptor &newFrom{staticDesc.descriptor()};
285-
std::memcpy(&newFrom, &from, descBytes);
285+
Fortran::runtime::memcpy(&newFrom, &from, descBytes);
286286
// Pretend the temporary descriptor is for an ALLOCATABLE
287287
// entity, otherwise, the Deallocate() below will not
288288
// free the descriptor memory.

flang/runtime/derived.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ RT_API_ATTRS int Initialize(const Descriptor &instance,
7373
std::size_t bytes{comp.SizeInBytes(instance)};
7474
for (std::size_t j{0}; j++ < elements; instance.IncrementSubscripts(at)) {
7575
char *ptr{instance.ElementComponent<char>(at, comp.offset())};
76-
std::memcpy(ptr, init, bytes);
76+
// std::memcpy(ptr, init, bytes);
77+
Fortran::runtime::memcpy(ptr, init, bytes);
7778
}
7879
} else if (comp.genre() == typeInfo::Component::Genre::Pointer) {
7980
// Data pointers without explicit initialization are established

flang/runtime/descriptor.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ RT_OFFLOAD_API_GROUP_BEGIN
2626
RT_API_ATTRS Descriptor::Descriptor(const Descriptor &that) { *this = that; }
2727

2828
RT_API_ATTRS Descriptor &Descriptor::operator=(const Descriptor &that) {
29-
std::memcpy(this, &that, that.SizeInBytes());
29+
Fortran::runtime::memcpy(this, &that, that.SizeInBytes());
3030
return *this;
3131
}
3232

flang/runtime/stat.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ RT_API_ATTRS int ToErrmsg(const Descriptor *errmsg, int stat) {
8484
std::size_t bufferLength{errmsg->ElementBytes()};
8585
std::size_t msgLength{Fortran::runtime::strlen(msg)};
8686
if (msgLength >= bufferLength) {
87-
std::memcpy(buffer, msg, bufferLength);
87+
Fortran::runtime::memcpy(buffer, msg, bufferLength);
8888
} else {
89-
std::memcpy(buffer, msg, msgLength);
90-
std::memset(buffer + msgLength, ' ', bufferLength - msgLength);
89+
Fortran::runtime::memcpy(buffer, msg, msgLength);
90+
Fortran::runtime::memset(buffer + msgLength, ' ', bufferLength - msgLength);
9191
}
9292
}
9393
}

flang/runtime/tools.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ RT_API_ATTRS OwningPtr<char> SaveDefaultCharacter(
2828
const char *s, std::size_t length, const Terminator &terminator) {
2929
if (s) {
3030
auto *p{static_cast<char *>(AllocateMemoryOrCrash(terminator, length + 1))};
31-
std::memcpy(p, s, length);
31+
Fortran::runtime::memcpy(p, s, length);
3232
p[length] = '\0';
3333
return OwningPtr<char>{p};
3434
} else {
@@ -75,10 +75,10 @@ RT_API_ATTRS void ToFortranDefaultCharacter(
7575
char *to, std::size_t toLength, const char *from) {
7676
std::size_t len{Fortran::runtime::strlen(from)};
7777
if (len < toLength) {
78-
std::memcpy(to, from, len);
79-
std::memset(to + len, ' ', toLength - len);
78+
Fortran::runtime::memcpy(to, from, len);
79+
Fortran::runtime::memset(to + len, ' ', toLength - len);
8080
} else {
81-
std::memcpy(to, from, toLength);
81+
Fortran::runtime::memcpy(to, from, toLength);
8282
}
8383
}
8484

@@ -122,7 +122,7 @@ RT_API_ATTRS void ShallowCopyDiscontiguousToDiscontiguous(
122122
std::size_t elementBytes{to.ElementBytes()};
123123
for (std::size_t n{to.Elements()}; n-- > 0;
124124
to.IncrementSubscripts(toAt), from.IncrementSubscripts(fromAt)) {
125-
std::memcpy(
125+
Fortran::runtime::memcpy(
126126
to.Element<char>(toAt), from.Element<char>(fromAt), elementBytes);
127127
}
128128
}
@@ -135,7 +135,7 @@ RT_API_ATTRS void ShallowCopyDiscontiguousToContiguous(
135135
std::size_t elementBytes{to.ElementBytes()};
136136
for (std::size_t n{to.Elements()}; n-- > 0;
137137
toAt += elementBytes, from.IncrementSubscripts(fromAt)) {
138-
std::memcpy(toAt, from.Element<char>(fromAt), elementBytes);
138+
Fortran::runtime::memcpy(toAt, from.Element<char>(fromAt), elementBytes);
139139
}
140140
}
141141

@@ -147,15 +147,15 @@ RT_API_ATTRS void ShallowCopyContiguousToDiscontiguous(
147147
std::size_t elementBytes{to.ElementBytes()};
148148
for (std::size_t n{to.Elements()}; n-- > 0;
149149
to.IncrementSubscripts(toAt), fromAt += elementBytes) {
150-
std::memcpy(to.Element<char>(toAt), fromAt, elementBytes);
150+
Fortran::runtime::memcpy(to.Element<char>(toAt), fromAt, elementBytes);
151151
}
152152
}
153153

154154
RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from,
155155
bool toIsContiguous, bool fromIsContiguous) {
156156
if (toIsContiguous) {
157157
if (fromIsContiguous) {
158-
std::memcpy(to.OffsetElement(), from.OffsetElement(),
158+
Fortran::runtime::memcpy(to.OffsetElement(), from.OffsetElement(),
159159
to.Elements() * to.ElementBytes());
160160
} else {
161161
ShallowCopyDiscontiguousToContiguous(to, from);
@@ -177,7 +177,7 @@ RT_API_ATTRS char *EnsureNullTerminated(
177177
char *str, std::size_t length, Terminator &terminator) {
178178
if (runtime::memchr(str, '\0', length) == nullptr) {
179179
char *newCmd{(char *)AllocateMemoryOrCrash(terminator, length + 1)};
180-
std::memcpy(newCmd, str, length);
180+
Fortran::runtime::memcpy(newCmd, str, length);
181181
newCmd[length] = '\0';
182182
return newCmd;
183183
} else {
@@ -209,7 +209,7 @@ RT_API_ATTRS std::int32_t CopyCharsToDescriptor(const Descriptor &value,
209209
return ToErrmsg(errmsg, StatValueTooShort);
210210
}
211211

212-
std::memcpy(value.OffsetElement(offset), rawValue, toCopy);
212+
Fortran::runtime::memcpy(value.OffsetElement(offset), rawValue, toCopy);
213213

214214
if (static_cast<std::int64_t>(rawValueLength) > toCopy) {
215215
return ToErrmsg(errmsg, StatValueTooShort);

0 commit comments

Comments
 (0)