Files
clang-p2996/offload/DeviceRTL/src/LibC.cpp
Joseph Huber 3c50cbfda4 [DeviceRTL] Make defined 'libc' functions weak in OpenMP (#97356)
Summary:
These functions provide special-case implementations internal to the
OpenMP device runtime. This can potentially conflict with the symbols
pulled in from the actual GPU `libc`. This patch makes these weak, so in
the case that the GPU libc functions exist they will be overridden. This
should not impact performance in the average case because the old
`-mlink-builtin-bitcode` version does internalization, deleting weak,
and the new LTO path will resolve to the strong reference and then
internalize it.
2024-07-02 13:23:53 -05:00

76 lines
2.3 KiB
C++

//===------- LibC.cpp - Simple implementation of libc functions --- C++ ---===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "LibC.h"
#pragma omp begin declare target device_type(nohost)
namespace impl {
int32_t omp_vprintf(const char *Format, void *Arguments, uint32_t);
}
#pragma omp begin declare variant match( \
device = {arch(nvptx, nvptx64)}, \
implementation = {extension(match_any)})
extern "C" int32_t vprintf(const char *, void *);
namespace impl {
int32_t omp_vprintf(const char *Format, void *Arguments, uint32_t) {
return vprintf(Format, Arguments);
}
} // namespace impl
#pragma omp end declare variant
#pragma omp begin declare variant match(device = {arch(amdgcn)})
#ifdef OMPTARGET_HAS_LIBC
// TODO: Remove this handling once we have varargs support.
extern "C" struct FILE *stdout;
extern "C" int32_t rpc_fprintf(FILE *, const char *, void *, uint64_t);
namespace impl {
int32_t omp_vprintf(const char *Format, void *Arguments, uint32_t Size) {
return rpc_fprintf(stdout, Format, Arguments, Size);
}
} // namespace impl
#else
// We do not have a vprintf implementation for AMD GPU so we use a stub.
namespace impl {
int32_t omp_vprintf(const char *Format, void *Arguments, uint32_t) {
return -1;
}
} // namespace impl
#endif
#pragma omp end declare variant
extern "C" {
[[gnu::weak]] int memcmp(const void *lhs, const void *rhs, size_t count) {
auto *L = reinterpret_cast<const unsigned char *>(lhs);
auto *R = reinterpret_cast<const unsigned char *>(rhs);
for (size_t I = 0; I < count; ++I)
if (L[I] != R[I])
return (int)L[I] - (int)R[I];
return 0;
}
[[gnu::weak]] void memset(void *dst, int C, size_t count) {
auto *dstc = reinterpret_cast<char *>(dst);
for (size_t I = 0; I < count; ++I)
dstc[I] = C;
}
/// printf() calls are rewritten by CGGPUBuiltin to __llvm_omp_vprintf
int32_t __llvm_omp_vprintf(const char *Format, void *Arguments, uint32_t Size) {
return impl::omp_vprintf(Format, Arguments, Size);
}
}
#pragma omp end declare target