Skip to content

Commit e8c0ae6

Browse files
authored
[OpenMP] Add optimization to remove the RPC client (#70683)
Summary: Part of the work done in the `libc` project is to provide host services for things like `printf` or `malloc`, or generally any syscall-like behaviour. This scheme works by emitting an externally visible global called `__llvm_libc_rpc_client` that the host runtime can pick up to get a handle to the global memory associated with the client. We use the presence of this symbol to indicate whether or not we need to run an RPC server. Normally, this symbol is only present if something requiring an RPC server was linked in, such as `printf`. However, if this call to `printf` was subsequently optimizated out, the symbol would remain and cannot be removed (rightfully so) because of its linkage. This patch adds a special-case optimization to remove this symbol so we can indicate that an RPC server is no longer needed. This patch puts this logic in `OpenMPOpt` as the most readily available place for it. In the future, we should think how to move this somewhere more generic. Furthermore, we use a hard-coded runtime name (which isn't uncommon given all the other magic symbol names). But it might be nice to abstract that part away.
1 parent ef6014e commit e8c0ae6

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

llvm/lib/Transforms/IPO/OpenMPOpt.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,9 @@ struct OpenMPOpt {
978978
}
979979
}
980980

981+
if (OMPInfoCache.OpenMPPostLink)
982+
Changed |= removeRuntimeSymbols();
983+
981984
return Changed;
982985
}
983986

@@ -1507,6 +1510,37 @@ struct OpenMPOpt {
15071510
return Changed;
15081511
}
15091512

1513+
/// Tries to remove known runtime symbols that are optional from the module.
1514+
bool removeRuntimeSymbols() {
1515+
// The RPC client symbol is defined in `libc` and indicates that something
1516+
// required an RPC server. If its users were all optimized out then we can
1517+
// safely remove it.
1518+
// TODO: This should be somewhere more common in the future.
1519+
if (GlobalVariable *GV = M.getNamedGlobal("__llvm_libc_rpc_client")) {
1520+
if (!GV->getType()->isPointerTy())
1521+
return false;
1522+
1523+
Constant *C = GV->getInitializer();
1524+
if (!C)
1525+
return false;
1526+
1527+
// Check to see if the only user of the RPC client is the external handle.
1528+
GlobalVariable *Client = dyn_cast<GlobalVariable>(C->stripPointerCasts());
1529+
if (!Client || Client->getNumUses() > 1 ||
1530+
Client->user_back() != GV->getInitializer())
1531+
return false;
1532+
1533+
Client->replaceAllUsesWith(PoisonValue::get(Client->getType()));
1534+
Client->eraseFromParent();
1535+
1536+
GV->replaceAllUsesWith(PoisonValue::get(GV->getType()));
1537+
GV->eraseFromParent();
1538+
1539+
return true;
1540+
}
1541+
return false;
1542+
}
1543+
15101544
/// Tries to hide the latency of runtime calls that involve host to
15111545
/// device memory transfers by splitting them into their "issue" and "wait"
15121546
/// versions. The "issue" is moved upwards as much as possible. The "wait" is
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-globals
2+
; RUN: opt -S -passes=openmp-opt-postlink < %s | FileCheck %s --check-prefix=POSTLINK
3+
; RUN: opt -S -passes=openmp-opt < %s | FileCheck %s --check-prefix=PRELINK
4+
5+
@client = internal addrspace(1) global i64 zeroinitializer, align 8
6+
@__llvm_libc_rpc_client = protected local_unnamed_addr addrspace(1) global ptr addrspacecast (ptr addrspace(1) @client to ptr), align 8
7+
8+
;.
9+
; POSTLINK: @[[CLIENT:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(1) global i64 0, align 8
10+
; POSTLINK: @[[__LLVM_LIBC_RPC_CLIENT:[a-zA-Z0-9_$"\\.-]+]] = protected local_unnamed_addr addrspace(1) global ptr addrspacecast (ptr addrspace(1) @client to ptr), align 8
11+
;.
12+
; PRELINK: @[[CLIENT:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(1) global i64 0, align 8
13+
; PRELINK: @[[__LLVM_LIBC_RPC_CLIENT:[a-zA-Z0-9_$"\\.-]+]] = protected local_unnamed_addr addrspace(1) global ptr addrspacecast (ptr addrspace(1) @client to ptr), align 8
14+
;.
15+
define i64 @a() {
16+
; POSTLINK-LABEL: define {{[^@]+}}@a
17+
; POSTLINK-SAME: () #[[ATTR0:[0-9]+]] {
18+
; POSTLINK-NEXT: [[RETVAL:%.*]] = load i64, ptr addrspace(1) @client, align 8
19+
; POSTLINK-NEXT: ret i64 [[RETVAL]]
20+
;
21+
; PRELINK-LABEL: define {{[^@]+}}@a
22+
; PRELINK-SAME: () #[[ATTR0:[0-9]+]] {
23+
; PRELINK-NEXT: [[RETVAL:%.*]] = load i64, ptr addrspace(1) @client, align 8
24+
; PRELINK-NEXT: ret i64 [[RETVAL]]
25+
;
26+
%retval = load i64, ptr addrspace(1) @client, align 8
27+
ret i64 %retval
28+
}
29+
30+
!llvm.module.flags = !{!0, !1, !2}
31+
32+
!0 = !{i32 1, !"wchar_size", i32 4}
33+
!1 = !{i32 7, !"openmp", i32 50}
34+
!2 = !{i32 7, !"openmp-device", i32 50}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-globals
2+
; RUN: opt -S -passes=openmp-opt-postlink < %s | FileCheck %s --check-prefix=POSTLINK
3+
; RUN: opt -S -passes=openmp-opt < %s | FileCheck %s --check-prefix=PRELINK
4+
5+
@client = internal addrspace(1) global i32 zeroinitializer, align 8
6+
@__llvm_libc_rpc_client = protected local_unnamed_addr addrspace(1) global ptr addrspacecast (ptr addrspace(1) @client to ptr), align 8
7+
8+
;.
9+
; POSTLINK-NOT: @[[CLIENT:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(1) global i32 0, align 8
10+
; POSTLINK-NOT: @[[__LLVM_LIBC_RPC_CLIENT:[a-zA-Z0-9_$"\\.-]+]] = protected local_unnamed_addr addrspace(1) global ptr addrspacecast (ptr addrspace(1) @client to ptr), align 8
11+
;.
12+
; PRELINK: @[[CLIENT:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(1) global i32 0, align 8
13+
; PRELINK: @[[__LLVM_LIBC_RPC_CLIENT:[a-zA-Z0-9_$"\\.-]+]] = protected local_unnamed_addr addrspace(1) global ptr addrspacecast (ptr addrspace(1) @client to ptr), align 8
14+
;.
15+
define void @a() {
16+
; POSTLINK-LABEL: define {{[^@]+}}@a() {
17+
; POSTLINK-NEXT: ret void
18+
;
19+
; PRELINK-LABEL: define {{[^@]+}}@a() {
20+
; PRELINK-NEXT: ret void
21+
;
22+
ret void
23+
}
24+
25+
!llvm.module.flags = !{!0, !1, !2}
26+
27+
!0 = !{i32 1, !"wchar_size", i32 4}
28+
!1 = !{i32 7, !"openmp", i32 50}
29+
!2 = !{i32 7, !"openmp-device", i32 50}

0 commit comments

Comments
 (0)