Skip to content

Commit 141c4e7

Browse files
committed
[OpenMP] Do not always emit unused extern variables
Currently, the precense of the OpenMP target declare metadata requires that we always codegen a global declaration. This is undesirable in the case that we could defer or omit this declaration as is common with unused extern variables. This is important as it allows us, in the runtime, to rely on static linking semantics to omit unused symbols so they are not included when the user links it in. This patch changes the check for always emitting these variables. Because of this we also need to extend this logic to the generation of the offloading entries. This has the result of derring the offload entry generation to the canonical definitoin. So we are effectively assuming whoever owns the storage for this variable will perform that operation. This makes an exception for `link` attributes as those require their own special handling. Let me know if this is sound in the implementation, I do not have the largest view of the standards here. Fixes: llvm#64133 Reviewed By: tianshilei1992 Differential Revision: https://reviews.llvm.org/D156368
1 parent 391249d commit 141c4e7

File tree

4 files changed

+42
-4
lines changed

4 files changed

+42
-4
lines changed

clang/lib/CodeGen/CGOpenMPRuntime.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10166,6 +10166,13 @@ void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD,
1016610166

1016710167
std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
1016810168
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
10169+
10170+
// If this is an 'extern' declaration we defer to the canonical definition and
10171+
// do not emit an offloading entry.
10172+
if (Res && *Res != OMPDeclareTargetDeclAttr::MT_Link &&
10173+
VD->hasExternalStorage())
10174+
return;
10175+
1016910176
if (!Res) {
1017010177
if (CGM.getLangOpts().OpenMPIsTargetDevice) {
1017110178
// Register non-target variables being emitted in device code (debug info

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3605,6 +3605,13 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
36053605
// Emit declaration of the must-be-emitted declare target variable.
36063606
if (std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
36073607
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
3608+
3609+
// If this variable has external storage and doesn't require special
3610+
// link handling we defer to its canonical definition.
3611+
if (VD->hasExternalStorage() &&
3612+
Res != OMPDeclareTargetDeclAttr::MT_Link)
3613+
return;
3614+
36083615
bool UnifiedMemoryEnabled =
36093616
getOpenMPRuntime().hasRequiresUnifiedSharedMemory();
36103617
if ((*Res == OMPDeclareTargetDeclAttr::MT_To ||

clang/test/OpenMP/declare_target_codegen.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
// CHECK-DAG: @flag = protected global i8 undef,
3030
// CHECK-DAG: @dx = {{protected | }}global i32 0,
3131
// CHECK-DAG: @dy = {{protected | }}global i32 0,
32-
// CHECK-DAG: @aaa = external global i32,
3332
// CHECK-DAG: @bbb = {{protected | }}global i32 0,
3433
// CHECK-DAG: weak constant %struct.__tgt_offload_entry { ptr @bbb,
3534
// CHECK-DAG: @ccc = external global i32,
@@ -80,7 +79,7 @@ extern int bbb;
8079
extern int aaa;
8180
int bbb = 0;
8281
extern int ccc;
83-
int ddd = 0;
82+
int ddd = ccc;
8483
#pragma omp end declare target
8584

8685
#pragma omp declare target
@@ -260,8 +259,6 @@ struct TTT {
260259

261260
// CHECK-NOT: define {{.*}}{{baz1|baz4|maini1|Base|virtual_}}
262261

263-
// CHECK-DAG: !{i32 1, !"aaa", i32 0, i32 {{[0-9]+}}}
264-
// CHECK-DAG: !{i32 1, !"ccc", i32 0, i32 {{[0-9]+}}}
265262
// CHECK-DAG: !{{{.+}}virtual_foo
266263

267264
#ifdef OMP5
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %libomptarget-compile-generic -DVAR -c -o %t.o
2+
// RUN: %libomptarget-compile-generic %t.o && %libomptarget-run-generic | %fcheck-generic
3+
4+
#ifdef VAR
5+
int x = 1;
6+
#else
7+
#include <stdio.h>
8+
#include <assert.h>
9+
extern int x;
10+
11+
int main() {
12+
int value = 0;
13+
#pragma omp target map(from : value)
14+
value = x;
15+
assert(value == 1);
16+
17+
x = 999;
18+
#pragma omp target update to(x)
19+
20+
#pragma omp target map(from : value)
21+
value = x;
22+
assert(value == 999);
23+
24+
// CHECK: PASS
25+
printf ("PASS\n");
26+
}
27+
#endif

0 commit comments

Comments
 (0)