Skip to content

Commit fea5914

Browse files
committed
Revert "[OpenMP][libc] Remove special handling for OpenMP printf (#98940)"
This reverts commit 069e8bc. Summary: Some tests failing, revert this for now.
1 parent 1978c21 commit fea5914

File tree

11 files changed

+183
-16
lines changed

11 files changed

+183
-16
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5986,6 +5986,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
59865986
getTarget().getTriple().isAMDGCN() ||
59875987
(getTarget().getTriple().isSPIRV() &&
59885988
getTarget().getTriple().getVendor() == Triple::VendorType::AMD)) {
5989+
if (getLangOpts().OpenMPIsTargetDevice)
5990+
return EmitOpenMPDevicePrintfCallExpr(E);
59895991
if (getTarget().getTriple().isNVPTX())
59905992
return EmitNVPTXDevicePrintfCallExpr(E);
59915993
if ((getTarget().getTriple().isAMDGCN() ||

clang/lib/CodeGen/CGGPUBuiltin.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,28 @@ llvm::Function *GetVprintfDeclaration(llvm::Module &M) {
4242
VprintfFuncType, llvm::GlobalVariable::ExternalLinkage, "vprintf", &M);
4343
}
4444

45+
llvm::Function *GetOpenMPVprintfDeclaration(CodeGenModule &CGM) {
46+
const char *Name = "__llvm_omp_vprintf";
47+
llvm::Module &M = CGM.getModule();
48+
llvm::Type *ArgTypes[] = {llvm::PointerType::getUnqual(M.getContext()),
49+
llvm::PointerType::getUnqual(M.getContext()),
50+
llvm::Type::getInt32Ty(M.getContext())};
51+
llvm::FunctionType *VprintfFuncType = llvm::FunctionType::get(
52+
llvm::Type::getInt32Ty(M.getContext()), ArgTypes, false);
53+
54+
if (auto *F = M.getFunction(Name)) {
55+
if (F->getFunctionType() != VprintfFuncType) {
56+
CGM.Error(SourceLocation(),
57+
"Invalid type declaration for __llvm_omp_vprintf");
58+
return nullptr;
59+
}
60+
return F;
61+
}
62+
63+
return llvm::Function::Create(
64+
VprintfFuncType, llvm::GlobalVariable::ExternalLinkage, Name, &M);
65+
}
66+
4567
// Transforms a call to printf into a call to the NVPTX vprintf syscall (which
4668
// isn't particularly special; it's invoked just like a regular function).
4769
// vprintf takes two args: A format string, and a pointer to a buffer containing
@@ -191,3 +213,10 @@ RValue CodeGenFunction::EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E) {
191213
Builder.SetInsertPoint(IRB.GetInsertBlock(), IRB.GetInsertPoint());
192214
return RValue::get(Printf);
193215
}
216+
217+
RValue CodeGenFunction::EmitOpenMPDevicePrintfCallExpr(const CallExpr *E) {
218+
assert(getTarget().getTriple().isNVPTX() ||
219+
getTarget().getTriple().isAMDGCN());
220+
return EmitDevicePrintfCallExpr(E, this, GetOpenMPVprintfDeclaration(CGM),
221+
true);
222+
}

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4536,6 +4536,7 @@ class CodeGenFunction : public CodeGenTypeCache {
45364536

45374537
RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E);
45384538
RValue EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E);
4539+
RValue EmitOpenMPDevicePrintfCallExpr(const CallExpr *E);
45394540

45404541
RValue EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
45414542
const CallExpr *E, ReturnValueSlot ReturnValue);

libc/config/gpu/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ set(TARGET_LIBC_ENTRYPOINTS
226226

227227
# gpu/rpc.h entrypoints
228228
libc.src.gpu.rpc_host_call
229+
libc.src.gpu.rpc_fprintf
229230
)
230231

231232
set(TARGET_LIBM_ENTRYPOINTS

libc/spec/gpu_ext.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ def GPUExtensions : StandardSpec<"GPUExtensions"> {
1010
RetValSpec<VoidType>,
1111
[ArgSpec<VoidPtr>, ArgSpec<VoidPtr>, ArgSpec<SizeTType>]
1212
>,
13+
FunctionSpec<
14+
"rpc_fprintf",
15+
RetValSpec<IntType>,
16+
[ArgSpec<FILERestrictedPtr>,
17+
ArgSpec<ConstCharRestrictedPtr>,
18+
ArgSpec<VoidPtr>,
19+
ArgSpec<SizeTType>]
20+
>,
1321
]
1422
>;
1523
let Headers = [

libc/src/gpu/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,15 @@ add_entrypoint_object(
88
libc.src.__support.RPC.rpc_client
99
libc.src.__support.GPU.utils
1010
)
11+
12+
add_entrypoint_object(
13+
rpc_fprintf
14+
SRCS
15+
rpc_fprintf.cpp
16+
HDRS
17+
rpc_fprintf.h
18+
DEPENDS
19+
libc.src.stdio.gpu.gpu_file
20+
libc.src.__support.RPC.rpc_client
21+
libc.src.__support.GPU.utils
22+
)

libc/src/gpu/rpc_fprintf.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//===-- GPU implementation of fprintf -------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "rpc_fprintf.h"
10+
11+
#include "src/__support/CPP/string_view.h"
12+
#include "src/__support/GPU/utils.h"
13+
#include "src/__support/RPC/rpc_client.h"
14+
#include "src/__support/common.h"
15+
#include "src/__support/macros/config.h"
16+
#include "src/stdio/gpu/file.h"
17+
18+
namespace LIBC_NAMESPACE_DECL {
19+
20+
template <uint16_t opcode>
21+
int fprintf_impl(::FILE *__restrict file, const char *__restrict format,
22+
size_t format_size, void *args, size_t args_size) {
23+
uint64_t mask = gpu::get_lane_mask();
24+
rpc::Client::Port port = rpc::client.open<opcode>();
25+
26+
if constexpr (opcode == RPC_PRINTF_TO_STREAM) {
27+
port.send([&](rpc::Buffer *buffer) {
28+
buffer->data[0] = reinterpret_cast<uintptr_t>(file);
29+
});
30+
}
31+
32+
port.send_n(format, format_size);
33+
port.recv([&](rpc::Buffer *buffer) {
34+
args_size = static_cast<size_t>(buffer->data[0]);
35+
});
36+
port.send_n(args, args_size);
37+
38+
uint32_t ret = 0;
39+
for (;;) {
40+
const char *str = nullptr;
41+
port.recv([&](rpc::Buffer *buffer) {
42+
ret = static_cast<uint32_t>(buffer->data[0]);
43+
str = reinterpret_cast<const char *>(buffer->data[1]);
44+
});
45+
// If any lanes have a string argument it needs to be copied back.
46+
if (!gpu::ballot(mask, str))
47+
break;
48+
49+
uint64_t size = str ? internal::string_length(str) + 1 : 0;
50+
port.send_n(str, size);
51+
}
52+
53+
port.close();
54+
return ret;
55+
}
56+
57+
// TODO: Delete this and port OpenMP to use `printf`.
58+
// place of varargs. Once varargs support is added we will use that to
59+
// implement the real version.
60+
LLVM_LIBC_FUNCTION(int, rpc_fprintf,
61+
(::FILE *__restrict stream, const char *__restrict format,
62+
void *args, size_t size)) {
63+
cpp::string_view str(format);
64+
if (stream == stdout)
65+
return fprintf_impl<RPC_PRINTF_TO_STDOUT>(stream, format, str.size() + 1,
66+
args, size);
67+
else if (stream == stderr)
68+
return fprintf_impl<RPC_PRINTF_TO_STDERR>(stream, format, str.size() + 1,
69+
args, size);
70+
else
71+
return fprintf_impl<RPC_PRINTF_TO_STREAM>(stream, format, str.size() + 1,
72+
args, size);
73+
}
74+
75+
} // namespace LIBC_NAMESPACE_DECL

libc/src/gpu/rpc_fprintf.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- Implementation header for RPC functions -----------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_GPU_RPC_HOST_CALL_H
10+
#define LLVM_LIBC_SRC_GPU_RPC_HOST_CALL_H
11+
12+
#include "hdr/types/FILE.h"
13+
#include "src/__support/macros/config.h"
14+
#include <stddef.h>
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
int rpc_fprintf(::FILE *__restrict stream, const char *__restrict format,
19+
void *argc, size_t size);
20+
21+
} // namespace LIBC_NAMESPACE_DECL
22+
23+
#endif // LLVM_LIBC_SRC_GPU_RPC_HOST_CALL_H

llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,7 @@ bool AMDGPUPrintfRuntimeBindingImpl::run(Module &M) {
437437
return false;
438438

439439
auto PrintfFunction = M.getFunction("printf");
440-
if (!PrintfFunction || !PrintfFunction->isDeclaration() ||
441-
M.getModuleFlag("openmp"))
440+
if (!PrintfFunction || !PrintfFunction->isDeclaration())
442441
return false;
443442

444443
for (auto &U : PrintfFunction->uses()) {

offload/DeviceRTL/include/LibC.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ extern "C" {
1818

1919
int memcmp(const void *lhs, const void *rhs, size_t count);
2020
void memset(void *dst, int C, size_t count);
21+
2122
int printf(const char *format, ...);
2223
}
2324

offload/DeviceRTL/src/LibC.cpp

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,44 @@
1111
#pragma omp begin declare target device_type(nohost)
1212

1313
namespace impl {
14-
int32_t omp_vprintf(const char *Format, __builtin_va_list vlist);
14+
int32_t omp_vprintf(const char *Format, void *Arguments, uint32_t);
1515
}
1616

17-
#ifndef OMPTARGET_HAS_LIBC
18-
namespace impl {
1917
#pragma omp begin declare variant match( \
2018
device = {arch(nvptx, nvptx64)}, \
2119
implementation = {extension(match_any)})
22-
extern "C" int vprintf(const char *format, ...);
23-
int omp_vprintf(const char *Format, __builtin_va_list vlist) {
24-
return vprintf(Format, vlist);
20+
extern "C" int32_t vprintf(const char *, void *);
21+
namespace impl {
22+
int32_t omp_vprintf(const char *Format, void *Arguments, uint32_t) {
23+
return vprintf(Format, Arguments);
2524
}
25+
} // namespace impl
2626
#pragma omp end declare variant
2727

2828
#pragma omp begin declare variant match(device = {arch(amdgcn)})
29-
int omp_vprintf(const char *Format, __builtin_va_list) { return -1; }
30-
#pragma omp end declare variant
31-
} // namespace impl
3229

33-
extern "C" int printf(const char *Format, ...) {
34-
__builtin_va_list vlist;
35-
__builtin_va_start(vlist, Format);
36-
return impl::omp_vprintf(Format, vlist);
30+
#ifdef OMPTARGET_HAS_LIBC
31+
// TODO: Remove this handling once we have varargs support.
32+
extern "C" struct FILE *stdout;
33+
extern "C" int32_t rpc_fprintf(FILE *, const char *, void *, uint64_t);
34+
35+
namespace impl {
36+
int32_t omp_vprintf(const char *Format, void *Arguments, uint32_t Size) {
37+
return rpc_fprintf(stdout, Format, Arguments, Size);
3738
}
38-
#endif // OMPTARGET_HAS_LIBC
39+
} // namespace impl
40+
#else
41+
// We do not have a vprintf implementation for AMD GPU so we use a stub.
42+
namespace impl {
43+
int32_t omp_vprintf(const char *Format, void *Arguments, uint32_t) {
44+
return -1;
45+
}
46+
} // namespace impl
47+
#endif
48+
#pragma omp end declare variant
3949

4050
extern "C" {
51+
4152
[[gnu::weak]] int memcmp(const void *lhs, const void *rhs, size_t count) {
4253
auto *L = reinterpret_cast<const unsigned char *>(lhs);
4354
auto *R = reinterpret_cast<const unsigned char *>(rhs);
@@ -54,6 +65,11 @@ extern "C" {
5465
for (size_t I = 0; I < count; ++I)
5566
dstc[I] = C;
5667
}
68+
69+
/// printf() calls are rewritten by CGGPUBuiltin to __llvm_omp_vprintf
70+
int32_t __llvm_omp_vprintf(const char *Format, void *Arguments, uint32_t Size) {
71+
return impl::omp_vprintf(Format, Arguments, Size);
72+
}
5773
}
5874

5975
#pragma omp end declare target

0 commit comments

Comments
 (0)