Skip to content

[clang] Modify linkage and register initialization of device_global #15148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
49 changes: 32 additions & 17 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,7 @@ void CodeGenModule::Release() {
DeferredDecls.insert(EmittedDeferredDecls.begin(),
EmittedDeferredDecls.end());
EmittedDeferredDecls.clear();
RenameSYCLStaticDeviceGlobalVariablesDeferred();
EmitVTablesOpportunistically();
applyGlobalValReplacements();
applyReplacements();
Expand Down Expand Up @@ -2816,19 +2817,6 @@ void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) {
(CodeGenOpts.KeepStaticConsts && VD->getStorageDuration() == SD_Static &&
VD->getType().isConstQualified())))
addUsedOrCompilerUsedGlobal(GV);

if (getLangOpts().SYCLIsDevice) {
// Add internal device_global variables to llvm.compiler.used array to
// prevent early optimizations from removing these variables from the
// module.
if (D && isa<VarDecl>(D)) {
const auto *VD = cast<VarDecl>(D);
const RecordDecl *RD = VD->getType()->getAsRecordDecl();
if (RD && RD->hasAttr<SYCLDeviceGlobalAttr>() &&
VD->getFormalLinkage() == Linkage::Internal)
addUsedOrCompilerUsedGlobal(GV);
}
}
}

bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD,
Expand Down Expand Up @@ -3566,6 +3554,11 @@ void CodeGenModule::EmitVTablesOpportunistically() {
OpportunisticVTables.clear();
}

void CodeGenModule::RenameSYCLStaticDeviceGlobalVariablesDeferred() {
for (auto &Entry : SYCLStaticDeviceGlobalsToRename)
Entry.second->setName(Entry.first());
}

void CodeGenModule::EmitGlobalAnnotations() {
for (const auto& [MangledName, VD] : DeferredAnnotations) {
llvm::GlobalValue *GV = GetGlobalValue(MangledName);
Expand Down Expand Up @@ -6186,6 +6179,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
if (getLangOpts().SYCLIsDevice)
addGlobalIntelFPGAAnnotation(D, GV);

// Set the llvm linkage type as appropriate.
llvm::GlobalValue::LinkageTypes Linkage = getLLVMLinkageVarDefinition(D);

if (getLangOpts().SYCLIsDevice) {
const RecordDecl *RD = D->getType()->getAsRecordDecl();

Expand All @@ -6196,8 +6192,30 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
AddGlobalSYCLIRAttributes(GV, RD);
// If VarDecl has a type decorated with SYCL device_global attribute
// emit IR attribute 'sycl-unique-id'.
if (RD->hasAttr<SYCLDeviceGlobalAttr>())
if (RD->hasAttr<SYCLDeviceGlobalAttr>()) {
addSYCLUniqueID(GV, D, Context);
if (Linkage == llvm::GlobalValue::InternalLinkage) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm....This seems ok to me but I am not sure if there are repercussions I am not thinking of . @AaronBallman can you weigh in here?

// Despite being `static`, static device globals need to be linked
// externally as symbols must persist across the host-device boundary
// and not removed or tampered with in later optimizations. Since we
// are linking these symbols externally we need a way to 'hide' the
// static device global symbols from other TUs that may have the same
// static symbols. We can 'hide' the symbols from other TUs despite
// being linked externally by prefixing the symbol with a UID string.
//
// Also prefix the symbol with __ so the symbol is not in user space.
//
// Global vars will be renamed at the end of module codegen in
// RenameSYCLStaticDeviceGlobalVariablesDeferred()
auto builtinString =
"__" + SYCLUniqueStableIdExpr::ComputeName(Context, D);
SYCLStaticDeviceGlobalsToRename[builtinString] = GV;
Linkage = llvm::GlobalValue::ExternalLinkage;
}
// SYCL device globals are initialized externally
GV->setExternallyInitialized(true);
}

// If VarDecl type is SYCLTypeAttr::host_pipe, emit the IR attribute
// 'sycl-unique-id'.
if (const auto *Attr = RD->getAttr<SYCLTypeAttr>())
Expand All @@ -6217,9 +6235,6 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
GlobalsRestrict->addOperand(Node);
}

// Set the llvm linkage type as appropriate.
llvm::GlobalValue::LinkageTypes Linkage = getLLVMLinkageVarDefinition(D);

// CUDA B.2.1 "The __device__ qualifier declares a variable that resides on
// the device. [...]"
// CUDA B.2.2 "The __constant__ qualifier, optionally used together with
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,10 @@ class CodeGenModule : public CodeGenTypeCache {
/// A queue of (optional) vtables to consider emitting.
std::vector<const CXXRecordDecl*> DeferredVTables;

/// A queue of static SYCL device global vars to rename once module has been
/// parsed
llvm::StringMap<llvm::GlobalVariable *> SYCLStaticDeviceGlobalsToRename;

/// A queue of (optional) vtables that may be emitted opportunistically.
std::vector<const CXXRecordDecl *> OpportunisticVTables;

Expand Down Expand Up @@ -1809,6 +1813,10 @@ class CodeGenModule : public CodeGenTypeCache {
/// lazily.
void EmitVTablesOpportunistically();

// SYCL static device global vars need to be renamed at the end of module
// codegen
void RenameSYCLStaticDeviceGlobalVariablesDeferred();

/// Call replaceAllUsesWith on all pairs in Replacements.
void applyReplacements();

Expand Down
Loading
Loading