Skip to content

Commit 2a6f3f5

Browse files
committed
[OPENMP]Fix handling of the globals during compilation for the device.
Fixed lookup for the target regions in unused virtual functions + fixed processing of the global variables not marked as declare target but emitted during debug info emission. llvm-svn: 346343
1 parent 37b102d commit 2a6f3f5

File tree

5 files changed

+132
-66
lines changed

5 files changed

+132
-66
lines changed

clang/lib/CodeGen/CGOpenMPRuntime.cpp

Lines changed: 82 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,17 @@ CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM, StringRef FirstSeparator,
12231223

12241224
void CGOpenMPRuntime::clear() {
12251225
InternalVars.clear();
1226+
// Clean non-target variable declarations possibly used only in debug info.
1227+
for (const auto &Data : EmittedNonTargetVariables) {
1228+
if (!Data.getValue().pointsToAliveValue())
1229+
continue;
1230+
auto *GV = dyn_cast<llvm::GlobalVariable>(Data.getValue());
1231+
if (!GV)
1232+
continue;
1233+
if (!GV->isDeclaration() || GV->getNumUses() > 0)
1234+
continue;
1235+
GV->eraseFromParent();
1236+
}
12261237
}
12271238

12281239
std::string CGOpenMPRuntime::getName(ArrayRef<StringRef> Parts) const {
@@ -2501,8 +2512,7 @@ llvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition(
25012512
return nullptr;
25022513

25032514
VD = VD->getDefinition(CGM.getContext());
2504-
if (VD && ThreadPrivateWithDefinition.count(VD) == 0) {
2505-
ThreadPrivateWithDefinition.insert(VD);
2515+
if (VD && ThreadPrivateWithDefinition.insert(CGM.getMangledName(VD)).second) {
25062516
QualType ASTTy = VD->getType();
25072517

25082518
llvm::Value *Ctor = nullptr, *CopyCtor = nullptr, *Dtor = nullptr;
@@ -2648,7 +2658,7 @@ bool CGOpenMPRuntime::emitDeclareTargetVarDefinition(const VarDecl *VD,
26482658
if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link)
26492659
return CGM.getLangOpts().OpenMPIsDevice;
26502660
VD = VD->getDefinition(CGM.getContext());
2651-
if (VD && !DeclareTargetWithDefinition.insert(VD).second)
2661+
if (VD && !DeclareTargetWithDefinition.insert(CGM.getMangledName(VD)).second)
26522662
return CGM.getLangOpts().OpenMPIsDevice;
26532663

26542664
QualType ASTTy = VD->getType();
@@ -3924,6 +3934,8 @@ void CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() {
39243934
llvm::LLVMContext &C = M.getContext();
39253935
SmallVector<const OffloadEntriesInfoManagerTy::OffloadEntryInfo *, 16>
39263936
OrderedEntries(OffloadEntriesInfoManager.size());
3937+
llvm::SmallVector<StringRef, 16> ParentFunctions(
3938+
OffloadEntriesInfoManager.size());
39273939

39283940
// Auxiliary methods to create metadata values and strings.
39293941
auto &&GetMDInt = [this](unsigned V) {
@@ -3938,7 +3950,7 @@ void CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() {
39383950

39393951
// Create function that emits metadata for each target region entry;
39403952
auto &&TargetRegionMetadataEmitter =
3941-
[&C, MD, &OrderedEntries, &GetMDInt, &GetMDString](
3953+
[&C, MD, &OrderedEntries, &ParentFunctions, &GetMDInt, &GetMDString](
39423954
unsigned DeviceID, unsigned FileID, StringRef ParentName,
39433955
unsigned Line,
39443956
const OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion &E) {
@@ -3958,6 +3970,7 @@ void CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() {
39583970

39593971
// Save this entry in the right position of the ordered entries array.
39603972
OrderedEntries[E.getOrder()] = &E;
3973+
ParentFunctions[E.getOrder()] = ParentName;
39613974

39623975
// Add metadata to the named metadata node.
39633976
MD->addOperand(llvm::MDNode::get(C, Ops));
@@ -3999,6 +4012,10 @@ void CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() {
39994012
dyn_cast<OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion>(
40004013
E)) {
40014014
if (!CE->getID() || !CE->getAddress()) {
4015+
// Do not blame the entry if the parent funtion is not emitted.
4016+
StringRef FnName = ParentFunctions[CE->getOrder()];
4017+
if (!CGM.GetGlobalValue(FnName))
4018+
continue;
40024019
unsigned DiagID = CGM.getDiags().getCustomDiagID(
40034020
DiagnosticsEngine::Error,
40044021
"Offloading entry for target region is incorrect: either the "
@@ -8425,14 +8442,15 @@ bool CGOpenMPRuntime::emitTargetFunctions(GlobalDecl GD) {
84258442
if (!CGM.getLangOpts().OpenMPIsDevice)
84268443
return false;
84278444

8428-
// Try to detect target regions in the function.
84298445
const ValueDecl *VD = cast<ValueDecl>(GD.getDecl());
8446+
StringRef Name = CGM.getMangledName(GD);
8447+
// Try to detect target regions in the function.
84308448
if (const auto *FD = dyn_cast<FunctionDecl>(VD))
8431-
scanForTargetRegionsFunctions(FD->getBody(), CGM.getMangledName(GD));
8449+
scanForTargetRegionsFunctions(FD->getBody(), Name);
84328450

84338451
// Do not to emit function if it is not marked as declare target.
84348452
return !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) &&
8435-
AlreadyEmittedTargetFunctions.count(VD->getCanonicalDecl()) == 0;
8453+
AlreadyEmittedTargetFunctions.count(Name) == 0;
84368454
}
84378455

84388456
bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
@@ -8469,54 +8487,62 @@ bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
84698487

84708488
void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD,
84718489
llvm::Constant *Addr) {
8472-
if (llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
8473-
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
8474-
OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind Flags;
8475-
StringRef VarName;
8476-
CharUnits VarSize;
8477-
llvm::GlobalValue::LinkageTypes Linkage;
8478-
switch (*Res) {
8479-
case OMPDeclareTargetDeclAttr::MT_To:
8480-
Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo;
8481-
VarName = CGM.getMangledName(VD);
8482-
if (VD->hasDefinition(CGM.getContext()) != VarDecl::DeclarationOnly) {
8483-
VarSize = CGM.getContext().getTypeSizeInChars(VD->getType());
8484-
assert(!VarSize.isZero() && "Expected non-zero size of the variable");
8485-
} else {
8486-
VarSize = CharUnits::Zero();
8487-
}
8488-
Linkage = CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false);
8489-
// Temp solution to prevent optimizations of the internal variables.
8490-
if (CGM.getLangOpts().OpenMPIsDevice && !VD->isExternallyVisible()) {
8491-
std::string RefName = getName({VarName, "ref"});
8492-
if (!CGM.GetGlobalValue(RefName)) {
8493-
llvm::Constant *AddrRef =
8494-
getOrCreateInternalVariable(Addr->getType(), RefName);
8495-
auto *GVAddrRef = cast<llvm::GlobalVariable>(AddrRef);
8496-
GVAddrRef->setConstant(/*Val=*/true);
8497-
GVAddrRef->setLinkage(llvm::GlobalValue::InternalLinkage);
8498-
GVAddrRef->setInitializer(Addr);
8499-
CGM.addCompilerUsedGlobal(GVAddrRef);
8500-
}
8501-
}
8502-
break;
8503-
case OMPDeclareTargetDeclAttr::MT_Link:
8504-
Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryLink;
8505-
if (CGM.getLangOpts().OpenMPIsDevice) {
8506-
VarName = Addr->getName();
8507-
Addr = nullptr;
8508-
} else {
8509-
VarName = getAddrOfDeclareTargetLink(VD).getName();
8510-
Addr =
8511-
cast<llvm::Constant>(getAddrOfDeclareTargetLink(VD).getPointer());
8490+
llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
8491+
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
8492+
if (!Res) {
8493+
if (CGM.getLangOpts().OpenMPIsDevice) {
8494+
// Register non-target variables being emitted in device code (debug info
8495+
// may cause this).
8496+
StringRef VarName = CGM.getMangledName(VD);
8497+
EmittedNonTargetVariables.try_emplace(VarName, Addr);
8498+
}
8499+
return;
8500+
}
8501+
// Register declare target variables.
8502+
OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind Flags;
8503+
StringRef VarName;
8504+
CharUnits VarSize;
8505+
llvm::GlobalValue::LinkageTypes Linkage;
8506+
switch (*Res) {
8507+
case OMPDeclareTargetDeclAttr::MT_To:
8508+
Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo;
8509+
VarName = CGM.getMangledName(VD);
8510+
if (VD->hasDefinition(CGM.getContext()) != VarDecl::DeclarationOnly) {
8511+
VarSize = CGM.getContext().getTypeSizeInChars(VD->getType());
8512+
assert(!VarSize.isZero() && "Expected non-zero size of the variable");
8513+
} else {
8514+
VarSize = CharUnits::Zero();
8515+
}
8516+
Linkage = CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false);
8517+
// Temp solution to prevent optimizations of the internal variables.
8518+
if (CGM.getLangOpts().OpenMPIsDevice && !VD->isExternallyVisible()) {
8519+
std::string RefName = getName({VarName, "ref"});
8520+
if (!CGM.GetGlobalValue(RefName)) {
8521+
llvm::Constant *AddrRef =
8522+
getOrCreateInternalVariable(Addr->getType(), RefName);
8523+
auto *GVAddrRef = cast<llvm::GlobalVariable>(AddrRef);
8524+
GVAddrRef->setConstant(/*Val=*/true);
8525+
GVAddrRef->setLinkage(llvm::GlobalValue::InternalLinkage);
8526+
GVAddrRef->setInitializer(Addr);
8527+
CGM.addCompilerUsedGlobal(GVAddrRef);
85128528
}
8513-
VarSize = CGM.getPointerSize();
8514-
Linkage = llvm::GlobalValue::WeakAnyLinkage;
8515-
break;
85168529
}
8517-
OffloadEntriesInfoManager.registerDeviceGlobalVarEntryInfo(
8518-
VarName, Addr, VarSize, Flags, Linkage);
8530+
break;
8531+
case OMPDeclareTargetDeclAttr::MT_Link:
8532+
Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryLink;
8533+
if (CGM.getLangOpts().OpenMPIsDevice) {
8534+
VarName = Addr->getName();
8535+
Addr = nullptr;
8536+
} else {
8537+
VarName = getAddrOfDeclareTargetLink(VD).getName();
8538+
Addr = cast<llvm::Constant>(getAddrOfDeclareTargetLink(VD).getPointer());
8539+
}
8540+
VarSize = CGM.getPointerSize();
8541+
Linkage = llvm::GlobalValue::WeakAnyLinkage;
8542+
break;
85198543
}
8544+
OffloadEntriesInfoManager.registerDeviceGlobalVarEntryInfo(
8545+
VarName, Addr, VarSize, Flags, Linkage);
85208546
}
85218547

85228548
bool CGOpenMPRuntime::emitTargetGlobal(GlobalDecl GD) {
@@ -8567,21 +8593,20 @@ bool CGOpenMPRuntime::markAsGlobalTarget(GlobalDecl GD) {
85678593
if (!CGM.getLangOpts().OpenMPIsDevice || !ShouldMarkAsGlobal)
85688594
return true;
85698595

8596+
StringRef Name = CGM.getMangledName(GD);
85708597
const auto *D = cast<FunctionDecl>(GD.getDecl());
8571-
const FunctionDecl *FD = D->getCanonicalDecl();
85728598
// Do not to emit function if it is marked as declare target as it was already
85738599
// emitted.
85748600
if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(D)) {
8575-
if (D->hasBody() && AlreadyEmittedTargetFunctions.count(FD) == 0) {
8576-
if (auto *F = dyn_cast_or_null<llvm::Function>(
8577-
CGM.GetGlobalValue(CGM.getMangledName(GD))))
8601+
if (D->hasBody() && AlreadyEmittedTargetFunctions.count(Name) == 0) {
8602+
if (auto *F = dyn_cast_or_null<llvm::Function>(CGM.GetGlobalValue(Name)))
85788603
return !F->isDeclaration();
85798604
return false;
85808605
}
85818606
return true;
85828607
}
85838608

8584-
return !AlreadyEmittedTargetFunctions.insert(FD).second;
8609+
return !AlreadyEmittedTargetFunctions.insert(Name).second;
85858610
}
85868611

85878612
llvm::Function *CGOpenMPRuntime::emitRegistrationFunction() {

clang/lib/CodeGen/CGOpenMPRuntime.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
#include "clang/Basic/OpenMPKinds.h"
2020
#include "clang/Basic/SourceLocation.h"
2121
#include "llvm/ADT/DenseMap.h"
22-
#include "llvm/ADT/SmallPtrSet.h"
2322
#include "llvm/ADT/StringMap.h"
23+
#include "llvm/ADT/StringSet.h"
2424
#include "llvm/IR/Function.h"
2525
#include "llvm/IR/ValueHandle.h"
2626

@@ -602,7 +602,11 @@ class CGOpenMPRuntime {
602602
OffloadEntriesInfoManagerTy OffloadEntriesInfoManager;
603603

604604
bool ShouldMarkAsGlobal = true;
605-
llvm::SmallDenseSet<const Decl *> AlreadyEmittedTargetFunctions;
605+
/// List of the emitted functions.
606+
llvm::StringSet<> AlreadyEmittedTargetFunctions;
607+
/// List of the global variables with their addresses that should not be
608+
/// emitted for the target.
609+
llvm::StringMap<llvm::WeakTrackingVH> EmittedNonTargetVariables;
606610

607611
/// List of variables that can become declare target implicitly and, thus,
608612
/// must be emitted.
@@ -679,10 +683,10 @@ class CGOpenMPRuntime {
679683
const llvm::Twine &Name);
680684

681685
/// Set of threadprivate variables with the generated initializer.
682-
llvm::SmallPtrSet<const VarDecl *, 4> ThreadPrivateWithDefinition;
686+
llvm::StringSet<> ThreadPrivateWithDefinition;
683687

684688
/// Set of declare target variables with the generated initializer.
685-
llvm::SmallPtrSet<const VarDecl *, 4> DeclareTargetWithDefinition;
689+
llvm::StringSet<> DeclareTargetWithDefinition;
686690

687691
/// Emits initialization code for the threadprivate variables.
688692
/// \param VDAddr Address of the global variable \a VD.

clang/test/OpenMP/declare_target_codegen.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
// SIMD-ONLY-NOT: {{__kmpc|__tgt}}
1414

15-
// CHECK-NOT: define {{.*}}{{baz1|baz4|maini1|Base}}
15+
// CHECK-NOT: define {{.*}}{{baz1|baz4|maini1|Base|virtual_}}
1616
// CHECK-DAG: Bake
1717
// CHECK-NOT: @{{hhh|ggg|fff|eee}} =
1818
// CHECK-DAG: @aaa = external global i32,
@@ -167,11 +167,25 @@ struct BakeNonT {
167167
};
168168
#pragma omp end declare target
169169

170+
template <typename T>
171+
struct B {
172+
virtual void virtual_foo();
173+
};
174+
175+
void new_bar() { new B<int>(); }
176+
177+
template <typename T>
178+
void B<T>::virtual_foo() {
179+
#pragma omp target
180+
{}
181+
}
182+
170183
// CHECK-DAG: declare extern_weak signext i32 @__create()
171184

172-
// CHECK-NOT: define {{.*}}{{baz1|baz4|maini1|Base}}
185+
// CHECK-NOT: define {{.*}}{{baz1|baz4|maini1|Base|virtual_}}
173186

174187
// CHECK-DAG: !{i32 1, !"aaa", i32 0, i32 {{[0-9]+}}}
175188
// CHECK-DAG: !{i32 1, !"ccc", i32 0, i32 {{[0-9]+}}}
189+
// CHECK-DAG: !{{{.+}}virtual_foo
176190

177191
#endif // HEADER

clang/test/OpenMP/target_messages.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc -DREGION_HOST
1616
// RUN: not %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -DREGION_DEVICE 2>&1 | FileCheck %s --check-prefix NO-REGION
1717
// NO-REGION: Offloading entry for target region is incorrect: either the address or the ID is invalid.
18+
// NO-REGION-NOT: Offloading entry for target region is incorrect: either the address or the ID is invalid.
1819

1920
#if defined(REGION_HOST) || defined(REGION_DEVICE)
2021
void foo() {
@@ -27,6 +28,17 @@ void foo() {
2728
;
2829
#endif
2930
}
31+
#pragma omp declare target to(foo)
32+
void bar() {
33+
#ifdef REGION_HOST
34+
#pragma omp target
35+
;
36+
#endif
37+
#ifdef REGION_DEVICE
38+
#pragma omp target
39+
;
40+
#endif
41+
}
3042
#else
3143
void foo() {
3244
}

clang/test/OpenMP/target_parallel_debug_codegen.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -fopenmp-cuda-mode -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -debug-info-kind=limited -fopenmp-version=45 | FileCheck %s
33
// expected-no-diagnostics
44

5+
template <unsigned *ddd>
6+
struct S {
7+
static int a;
8+
};
9+
10+
extern unsigned aaa;
11+
template<> int S<&aaa>::a;
12+
13+
template struct S<&aaa>;
14+
// CHECK-NOT: @aaa
15+
516
int main() {
617
/* int(*b)[a]; */
718
/* int *(**c)[a]; */
@@ -116,11 +127,11 @@ int main() {
116127
// CHECK: !DILocalVariable(name: ".bound_tid.",
117128
// CHECK-SAME: DIFlagArtificial
118129
// CHECK: !DILocalVariable(name: "c",
119-
// CHECK-SAME: line: 11
130+
// CHECK-SAME: line: 22
120131
// CHECK: !DILocalVariable(name: "a",
121-
// CHECK-SAME: line: 9
132+
// CHECK-SAME: line: 20
122133
// CHECK: !DILocalVariable(name: "b",
123-
// CHECK-SAME: line: 10
134+
// CHECK-SAME: line: 21
124135

125136
// CHECK-DAG: distinct !DISubprogram(name: "[[NONDEBUG_WRAPPER]]",
126137
// CHECK-DAG: distinct !DISubprogram(name: "[[DEBUG_PARALLEL]]",

0 commit comments

Comments
 (0)