Skip to content

Commit aff99b1

Browse files
jhuber6tru
authored andcommitted
[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: #64133 Reviewed By: tianshilei1992 Differential Revision: https://reviews.llvm.org/D156368 (cherry picked from commit 141c4e7)
1 parent 90321b4 commit aff99b1

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
@@ -10151,6 +10151,13 @@ void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD,
1015110151

1015210152
std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
1015310153
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
10154+
10155+
// If this is an 'extern' declaration we defer to the canonical definition and
10156+
// do not emit an offloading entry.
10157+
if (Res && *Res != OMPDeclareTargetDeclAttr::MT_Link &&
10158+
VD->hasExternalStorage())
10159+
return;
10160+
1015410161
if (!Res) {
1015510162
if (CGM.getLangOpts().OpenMPIsTargetDevice) {
1015610163
// 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)