aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /clang/lib/CodeGen/CodeGenModule.cpp
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp654
1 files changed, 391 insertions, 263 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 31afbc6b4262..9b40b88ea3c9 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -75,7 +75,7 @@ static llvm::cl::opt<bool> LimitedCoverage(
static const char AnnotationSection[] = "llvm.metadata";
static CGCXXABI *createCXXABI(CodeGenModule &CGM) {
- switch (CGM.getTarget().getCXXABI().getKind()) {
+ switch (CGM.getContext().getCXXABIKind()) {
case TargetCXXABI::AppleARM64:
case TargetCXXABI::Fuchsia:
case TargetCXXABI::GenericAArch64:
@@ -180,6 +180,34 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO,
// CoverageMappingModuleGen object.
if (CodeGenOpts.CoverageMapping)
CoverageMapping.reset(new CoverageMappingModuleGen(*this, *CoverageInfo));
+
+ // Generate the module name hash here if needed.
+ if (CodeGenOpts.UniqueInternalLinkageNames &&
+ !getModule().getSourceFileName().empty()) {
+ std::string Path = getModule().getSourceFileName();
+ // Check if a path substitution is needed from the MacroPrefixMap.
+ for (const auto &Entry : PPO.MacroPrefixMap)
+ if (Path.rfind(Entry.first, 0) != std::string::npos) {
+ Path = Entry.second + Path.substr(Entry.first.size());
+ break;
+ }
+ llvm::MD5 Md5;
+ Md5.update(Path);
+ llvm::MD5::MD5Result R;
+ Md5.final(R);
+ SmallString<32> Str;
+ llvm::MD5::stringifyResult(R, Str);
+ // Convert MD5hash to Decimal. Demangler suffixes can either contain
+ // numbers or characters but not both.
+ llvm::APInt IntHash(128, Str.str(), 16);
+ // Prepend "__uniq" before the hash for tools like profilers to understand
+ // that this symbol is of internal linkage type. The "__uniq" is the
+ // pre-determined prefix that is used to tell tools that this symbol was
+ // created with -funique-internal-linakge-symbols and the tools can strip or
+ // keep the prefix as needed.
+ ModuleNameHash = (Twine(".__uniq.") +
+ Twine(toString(IntHash, /* Radix = */ 10, /* Signed = */false))).str();
+ }
}
CodeGenModule::~CodeGenModule() {}
@@ -459,10 +487,8 @@ void CodeGenModule::Release() {
if (ObjCRuntime)
if (llvm::Function *ObjCInitFunction = ObjCRuntime->ModuleInitFunction())
AddGlobalCtor(ObjCInitFunction);
- if (Context.getLangOpts().CUDA && !Context.getLangOpts().CUDAIsDevice &&
- CUDARuntime) {
- if (llvm::Function *CudaCtorFunction =
- CUDARuntime->makeModuleCtorFunction())
+ if (Context.getLangOpts().CUDA && CUDARuntime) {
+ if (llvm::Function *CudaCtorFunction = CUDARuntime->finalizeModule())
AddGlobalCtor(CudaCtorFunction);
}
if (OpenMPRuntime) {
@@ -485,6 +511,7 @@ void CodeGenModule::Release() {
EmitGlobalAnnotations();
EmitStaticExternCAliases();
EmitDeferredUnusedCoverageMappings();
+ CodeGenPGO(*this).setValueProfilingFlag(getModule());
if (CoverageMapping)
CoverageMapping->emit();
if (CodeGenOpts.SanitizeCfiCrossDso) {
@@ -496,6 +523,22 @@ void CodeGenModule::Release() {
!Context.getTargetInfo().getTriple().isOSEmscripten()) {
EmitMainVoidAlias();
}
+
+ // Emit reference of __amdgpu_device_library_preserve_asan_functions to
+ // preserve ASAN functions in bitcode libraries.
+ if (LangOpts.Sanitize.has(SanitizerKind::Address) && getTriple().isAMDGPU()) {
+ auto *FT = llvm::FunctionType::get(VoidTy, {});
+ auto *F = llvm::Function::Create(
+ FT, llvm::GlobalValue::ExternalLinkage,
+ "__amdgpu_device_library_preserve_asan_functions", &getModule());
+ auto *Var = new llvm::GlobalVariable(
+ getModule(), FT->getPointerTo(),
+ /*isConstant=*/true, llvm::GlobalValue::WeakAnyLinkage, F,
+ "__amdgpu_device_library_preserve_asan_functions_ptr", nullptr,
+ llvm::GlobalVariable::NotThreadLocal);
+ addCompilerUsedGlobal(Var);
+ }
+
emitLLVMUsed();
if (SanStats)
SanStats->finish();
@@ -533,6 +576,9 @@ void CodeGenModule::Release() {
CodeGenOpts.DwarfVersion);
}
+ if (CodeGenOpts.Dwarf64)
+ getModule().addModuleFlag(llvm::Module::Max, "DWARF64", 1);
+
if (Context.getLangOpts().SemanticInterposition)
// Require various optimization to respect semantic interposition.
getModule().setSemanticInterposition(1);
@@ -551,6 +597,10 @@ void CodeGenModule::Release() {
// Function ID tables for Control Flow Guard (cfguard=1).
getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 1);
}
+ if (CodeGenOpts.EHContGuard) {
+ // Function ID tables for EH Continuation Guard.
+ getModule().addModuleFlag(llvm::Module::Warning, "ehcontguard", 1);
+ }
if (CodeGenOpts.OptimizationLevel > 0 && CodeGenOpts.StrictVTablePointers) {
// We don't support LTO with 2 with different StrictVTablePointers
// FIXME: we could support it by stripping all the information introduced
@@ -664,6 +714,16 @@ void CodeGenModule::Release() {
llvm::DenormalMode::IEEE);
}
+ if (LangOpts.EHAsynch)
+ getModule().addModuleFlag(llvm::Module::Warning, "eh-asynch", 1);
+
+ // Indicate whether this Module was compiled with -fopenmp
+ if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd)
+ getModule().addModuleFlag(llvm::Module::Max, "openmp", LangOpts.OpenMP);
+ if (getLangOpts().OpenMPIsDevice)
+ getModule().addModuleFlag(llvm::Module::Max, "openmp-device",
+ LangOpts.OpenMP);
+
// Emit OpenCL specific module metadata: OpenCL/SPIR version.
if (LangOpts.OpenCL) {
EmitOpenCLMetadata();
@@ -708,6 +768,20 @@ void CodeGenModule::Release() {
if (CodeGenOpts.NoPLT)
getModule().setRtLibUseGOT();
+ if (CodeGenOpts.UnwindTables)
+ getModule().setUwtable();
+
+ switch (CodeGenOpts.getFramePointer()) {
+ case CodeGenOptions::FramePointerKind::None:
+ // 0 ("none") is the default.
+ break;
+ case CodeGenOptions::FramePointerKind::NonLeaf:
+ getModule().setFramePointer(llvm::FramePointerKind::NonLeaf);
+ break;
+ case CodeGenOptions::FramePointerKind::All:
+ getModule().setFramePointer(llvm::FramePointerKind::All);
+ break;
+ }
SimplifyPersonality();
@@ -726,6 +800,17 @@ void CodeGenModule::Release() {
if (!getCodeGenOpts().RecordCommandLine.empty())
EmitCommandLineMetadata();
+ if (!getCodeGenOpts().StackProtectorGuard.empty())
+ getModule().setStackProtectorGuard(getCodeGenOpts().StackProtectorGuard);
+ if (!getCodeGenOpts().StackProtectorGuardReg.empty())
+ getModule().setStackProtectorGuardReg(
+ getCodeGenOpts().StackProtectorGuardReg);
+ if (getCodeGenOpts().StackProtectorGuardOffset != INT_MAX)
+ getModule().setStackProtectorGuardOffset(
+ getCodeGenOpts().StackProtectorGuardOffset);
+ if (getCodeGenOpts().StackAlignment)
+ getModule().setOverrideStackAlignment(getCodeGenOpts().StackAlignment);
+
getTargetCodeGenInfo().emitTargetMetadata(*this, MangledDeclNames);
EmitBackendOptionsMetadata(getCodeGenOpts());
@@ -926,8 +1011,13 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM,
// In MinGW, variables without DLLImport can still be automatically
// imported from a DLL by the linker; don't mark variables that
// potentially could come from another DLL as DSO local.
+
+ // With EmulatedTLS, TLS variables can be autoimported from other DLLs
+ // (and this actually happens in the public interface of libstdc++), so
+ // such variables can't be marked as DSO local. (Native TLS variables
+ // can't be dllimported at all, though.)
if (GV->isDeclarationForLinker() && isa<llvm::GlobalVariable>(GV) &&
- !GV->isThreadLocal())
+ (!GV->isThreadLocal() || CGM.getCodeGenOpts().EmulatedTLS))
return false;
}
@@ -945,27 +1035,21 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM,
if (TT.isOSBinFormatCOFF() || (TT.isOSWindows() && TT.isOSBinFormatMachO()))
return true;
- const auto &CGOpts = CGM.getCodeGenOpts();
- llvm::Reloc::Model RM = CGOpts.RelocationModel;
- const auto &LOpts = CGM.getLangOpts();
-
- if (TT.isOSBinFormatMachO()) {
- if (RM == llvm::Reloc::Static)
- return true;
- return GV->isStrongDefinitionForLinker();
- }
-
// Only handle COFF and ELF for now.
if (!TT.isOSBinFormatELF())
return false;
+ // If this is not an executable, don't assume anything is local.
+ const auto &CGOpts = CGM.getCodeGenOpts();
+ llvm::Reloc::Model RM = CGOpts.RelocationModel;
+ const auto &LOpts = CGM.getLangOpts();
if (RM != llvm::Reloc::Static && !LOpts.PIE) {
// On ELF, if -fno-semantic-interposition is specified and the target
// supports local aliases, there will be neither CC1
// -fsemantic-interposition nor -fhalf-no-semantic-interposition. Set
- // dso_local if using a local alias is preferable (can avoid GOT
- // indirection).
- if (!GV->canBenefitFromLocalAlias())
+ // dso_local on the function if using a local alias is preferable (can avoid
+ // PLT indirection).
+ if (!(isa<llvm::Function>(GV) && GV->canBenefitFromLocalAlias()))
return false;
return !(CGM.getLangOpts().SemanticInterposition ||
CGM.getLangOpts().HalfNoSemanticInterposition);
@@ -1142,13 +1226,25 @@ static void AppendTargetMangling(const CodeGenModule &CGM,
}
}
-static std::string getMangledNameImpl(const CodeGenModule &CGM, GlobalDecl GD,
+// Returns true if GD is a function decl with internal linkage and
+// needs a unique suffix after the mangled name.
+static bool isUniqueInternalLinkageDecl(GlobalDecl GD,
+ CodeGenModule &CGM) {
+ const Decl *D = GD.getDecl();
+ return !CGM.getModuleNameHash().empty() && isa<FunctionDecl>(D) &&
+ (CGM.getFunctionLinkage(GD) == llvm::GlobalValue::InternalLinkage);
+}
+
+static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD,
const NamedDecl *ND,
bool OmitMultiVersionMangling = false) {
SmallString<256> Buffer;
llvm::raw_svector_ostream Out(Buffer);
MangleContext &MC = CGM.getCXXABI().getMangleContext();
- if (MC.shouldMangleDeclName(ND))
+ if (!CGM.getModuleNameHash().empty())
+ MC.needsUniqueInternalLinkageNames();
+ bool ShouldMangle = MC.shouldMangleDeclName(ND);
+ if (ShouldMangle)
MC.mangleName(GD.getWithDecl(ND), Out);
else {
IdentifierInfo *II = ND->getIdentifier();
@@ -1166,6 +1262,20 @@ static std::string getMangledNameImpl(const CodeGenModule &CGM, GlobalDecl GD,
}
}
+ // Check if the module name hash should be appended for internal linkage
+ // symbols. This should come before multi-version target suffixes are
+ // appended. This is to keep the name and module hash suffix of the
+ // internal linkage function together. The unique suffix should only be
+ // added when name mangling is done to make sure that the final name can
+ // be properly demangled. For example, for C functions without prototypes,
+ // name mangling is not done and the unique suffix should not be appeneded
+ // then.
+ if (ShouldMangle && isUniqueInternalLinkageDecl(GD, CGM)) {
+ assert(CGM.getCodeGenOpts().UniqueInternalLinkageNames &&
+ "Hash computed when not explicitly requested");
+ Out << CGM.getModuleNameHash();
+ }
+
if (const auto *FD = dyn_cast<FunctionDecl>(ND))
if (FD->isMultiVersion() && !OmitMultiVersionMangling) {
switch (FD->getMultiVersionKind()) {
@@ -1183,6 +1293,11 @@ static std::string getMangledNameImpl(const CodeGenModule &CGM, GlobalDecl GD,
}
}
+ // Make unique name for device side static file-scope variable for HIP.
+ if (CGM.getContext().shouldExternalizeStaticVar(ND) &&
+ CGM.getLangOpts().GPURelocatableDeviceCode &&
+ CGM.getLangOpts().CUDAIsDevice && !CGM.getLangOpts().CUID.empty())
+ CGM.printPostfixForExternalizedStaticVar(Out);
return std::string(Out.str());
}
@@ -1240,9 +1355,16 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
}
}
- auto FoundName = MangledDeclNames.find(CanonicalGD);
- if (FoundName != MangledDeclNames.end())
- return FoundName->second;
+ // In CUDA/HIP device compilation with -fgpu-rdc, the mangled name of a
+ // static device variable depends on whether the variable is referenced by
+ // a host or device host function. Therefore the mangled name cannot be
+ // cached.
+ if (!LangOpts.CUDAIsDevice ||
+ !getContext().mayExternalizeStaticVar(GD.getDecl())) {
+ auto FoundName = MangledDeclNames.find(CanonicalGD);
+ if (FoundName != MangledDeclNames.end())
+ return FoundName->second;
+ }
// Keep the first result in the case of a mangling collision.
const auto *ND = cast<NamedDecl>(GD.getDecl());
@@ -1387,10 +1509,11 @@ llvm::ConstantInt *CodeGenModule::CreateCrossDsoCfiTypeId(llvm::Metadata *MD) {
void CodeGenModule::SetLLVMFunctionAttributes(GlobalDecl GD,
const CGFunctionInfo &Info,
- llvm::Function *F) {
+ llvm::Function *F, bool IsThunk) {
unsigned CallingConv;
llvm::AttributeList PAL;
- ConstructAttributeList(F->getName(), Info, GD, PAL, CallingConv, false);
+ ConstructAttributeList(F->getName(), Info, GD, PAL, CallingConv,
+ /*AttrOnCallSite=*/false, IsThunk);
F->setAttributes(PAL);
F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
}
@@ -1475,6 +1598,39 @@ void CodeGenModule::GenOpenCLArgMetadata(llvm::Function *Fn,
QualType ty = parm->getType();
std::string typeQuals;
+ // Get image and pipe access qualifier:
+ if (ty->isImageType() || ty->isPipeType()) {
+ const Decl *PDecl = parm;
+ if (auto *TD = dyn_cast<TypedefType>(ty))
+ PDecl = TD->getDecl();
+ const OpenCLAccessAttr *A = PDecl->getAttr<OpenCLAccessAttr>();
+ if (A && A->isWriteOnly())
+ accessQuals.push_back(llvm::MDString::get(VMContext, "write_only"));
+ else if (A && A->isReadWrite())
+ accessQuals.push_back(llvm::MDString::get(VMContext, "read_write"));
+ else
+ accessQuals.push_back(llvm::MDString::get(VMContext, "read_only"));
+ } else
+ accessQuals.push_back(llvm::MDString::get(VMContext, "none"));
+
+ // Get argument name.
+ argNames.push_back(llvm::MDString::get(VMContext, parm->getName()));
+
+ auto getTypeSpelling = [&](QualType Ty) {
+ auto typeName = Ty.getUnqualifiedType().getAsString(Policy);
+
+ if (Ty.isCanonical()) {
+ StringRef typeNameRef = typeName;
+ // Turn "unsigned type" to "utype"
+ if (typeNameRef.consume_front("unsigned "))
+ return std::string("u") + typeNameRef.str();
+ if (typeNameRef.consume_front("signed "))
+ return typeNameRef.str();
+ }
+
+ return typeName;
+ };
+
if (ty->isPointerType()) {
QualType pointeeTy = ty->getPointeeType();
@@ -1484,26 +1640,10 @@ void CodeGenModule::GenOpenCLArgMetadata(llvm::Function *Fn,
ArgInfoAddressSpace(pointeeTy.getAddressSpace()))));
// Get argument type name.
- std::string typeName =
- pointeeTy.getUnqualifiedType().getAsString(Policy) + "*";
-
- // Turn "unsigned type" to "utype"
- std::string::size_type pos = typeName.find("unsigned");
- if (pointeeTy.isCanonical() && pos != std::string::npos)
- typeName.erase(pos + 1, 8);
-
- argTypeNames.push_back(llvm::MDString::get(VMContext, typeName));
-
+ std::string typeName = getTypeSpelling(pointeeTy) + "*";
std::string baseTypeName =
- pointeeTy.getUnqualifiedType().getCanonicalType().getAsString(
- Policy) +
- "*";
-
- // Turn "unsigned type" to "utype"
- pos = baseTypeName.find("unsigned");
- if (pos != std::string::npos)
- baseTypeName.erase(pos + 1, 8);
-
+ getTypeSpelling(pointeeTy.getCanonicalType()) + "*";
+ argTypeNames.push_back(llvm::MDString::get(VMContext, typeName));
argBaseTypeNames.push_back(
llvm::MDString::get(VMContext, baseTypeName));
@@ -1525,30 +1665,9 @@ void CodeGenModule::GenOpenCLArgMetadata(llvm::Function *Fn,
llvm::ConstantAsMetadata::get(CGF->Builder.getInt32(AddrSpc)));
// Get argument type name.
- std::string typeName;
- if (isPipe)
- typeName = ty.getCanonicalType()
- ->castAs<PipeType>()
- ->getElementType()
- .getAsString(Policy);
- else
- typeName = ty.getUnqualifiedType().getAsString(Policy);
-
- // Turn "unsigned type" to "utype"
- std::string::size_type pos = typeName.find("unsigned");
- if (ty.isCanonical() && pos != std::string::npos)
- typeName.erase(pos + 1, 8);
-
- std::string baseTypeName;
- if (isPipe)
- baseTypeName = ty.getCanonicalType()
- ->castAs<PipeType>()
- ->getElementType()
- .getCanonicalType()
- .getAsString(Policy);
- else
- baseTypeName =
- ty.getUnqualifiedType().getCanonicalType().getAsString(Policy);
+ ty = isPipe ? ty->castAs<PipeType>()->getElementType() : ty;
+ std::string typeName = getTypeSpelling(ty);
+ std::string baseTypeName = getTypeSpelling(ty.getCanonicalType());
// Remove access qualifiers on images
// (as they are inseparable from type in clang implementation,
@@ -1560,38 +1679,13 @@ void CodeGenModule::GenOpenCLArgMetadata(llvm::Function *Fn,
}
argTypeNames.push_back(llvm::MDString::get(VMContext, typeName));
-
- // Turn "unsigned type" to "utype"
- pos = baseTypeName.find("unsigned");
- if (pos != std::string::npos)
- baseTypeName.erase(pos + 1, 8);
-
argBaseTypeNames.push_back(
llvm::MDString::get(VMContext, baseTypeName));
if (isPipe)
typeQuals = "pipe";
}
-
argTypeQuals.push_back(llvm::MDString::get(VMContext, typeQuals));
-
- // Get image and pipe access qualifier:
- if (ty->isImageType() || ty->isPipeType()) {
- const Decl *PDecl = parm;
- if (auto *TD = dyn_cast<TypedefType>(ty))
- PDecl = TD->getDecl();
- const OpenCLAccessAttr *A = PDecl->getAttr<OpenCLAccessAttr>();
- if (A && A->isWriteOnly())
- accessQuals.push_back(llvm::MDString::get(VMContext, "write_only"));
- else if (A && A->isReadWrite())
- accessQuals.push_back(llvm::MDString::get(VMContext, "read_write"));
- else
- accessQuals.push_back(llvm::MDString::get(VMContext, "read_only"));
- } else
- accessQuals.push_back(llvm::MDString::get(VMContext, "none"));
-
- // Get argument name.
- argNames.push_back(llvm::MDString::get(VMContext, parm->getName()));
}
Fn->setMetadata("kernel_arg_addr_space",
@@ -1836,13 +1930,13 @@ void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) {
GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
if (D && D->hasAttr<UsedAttr>())
- addUsedGlobal(GV);
+ addUsedOrCompilerUsedGlobal(GV);
if (CodeGenOpts.KeepStaticConsts && D && isa<VarDecl>(D)) {
const auto *VD = cast<VarDecl>(D);
if (VD->getType().isConstQualified() &&
VD->getStorageDuration() == SD_Static)
- addUsedGlobal(GV);
+ addUsedOrCompilerUsedGlobal(GV);
}
}
@@ -1912,6 +2006,8 @@ void CodeGenModule::setNonAliasAttributes(GlobalDecl GD,
if (D) {
if (auto *GV = dyn_cast<llvm::GlobalVariable>(GO)) {
+ if (D->hasAttr<RetainAttr>())
+ addUsedGlobal(GV);
if (auto *SA = D->getAttr<PragmaClangBSSSectionAttr>())
GV->addAttribute("bss-section", SA->getName());
if (auto *SA = D->getAttr<PragmaClangDataSectionAttr>())
@@ -1923,6 +2019,8 @@ void CodeGenModule::setNonAliasAttributes(GlobalDecl GD,
}
if (auto *F = dyn_cast<llvm::Function>(GO)) {
+ if (D->hasAttr<RetainAttr>())
+ addUsedGlobal(F);
if (auto *SA = D->getAttr<PragmaClangTextSectionAttr>())
if (!D->getAttr<SectionAttr>())
F->addFnAttr("implicit-section-name", SA->getName());
@@ -1954,7 +2052,7 @@ void CodeGenModule::SetInternalFunctionAttributes(GlobalDecl GD,
llvm::Function *F,
const CGFunctionInfo &FI) {
const Decl *D = GD.getDecl();
- SetLLVMFunctionAttributes(GD, FI, F);
+ SetLLVMFunctionAttributes(GD, FI, F, /*IsThunk=*/false);
SetLLVMFunctionAttributesForDefinition(D, F);
F->setLinkage(llvm::Function::InternalLinkage);
@@ -2008,7 +2106,8 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
const auto *FD = cast<FunctionDecl>(GD.getDecl());
if (!IsIncompleteFunction)
- SetLLVMFunctionAttributes(GD, getTypes().arrangeGlobalDeclaration(GD), F);
+ SetLLVMFunctionAttributes(GD, getTypes().arrangeGlobalDeclaration(GD), F,
+ IsThunk);
// Add the Returned attribute for "this", except for iOS 5 and earlier
// where substantial code, including the libstdc++ dylib, was compiled with
@@ -2103,6 +2202,15 @@ void CodeGenModule::addCompilerUsedGlobal(llvm::GlobalValue *GV) {
LLVMCompilerUsed.emplace_back(GV);
}
+void CodeGenModule::addUsedOrCompilerUsedGlobal(llvm::GlobalValue *GV) {
+ assert((isa<llvm::Function>(GV) || !GV->isDeclaration()) &&
+ "Only globals with definition can force usage.");
+ if (getTriple().isOSBinFormatELF())
+ LLVMCompilerUsed.emplace_back(GV);
+ else
+ LLVMUsed.emplace_back(GV);
+}
+
static void emitUsed(CodeGenModule &CGM, StringRef Name,
std::vector<llvm::WeakTrackingVH> &List) {
// Don't create llvm.used if there is no need.
@@ -2299,8 +2407,10 @@ void CodeGenModule::EmitDeferred() {
}
// Emit CUDA/HIP static device variables referenced by host code only.
- if (getLangOpts().CUDA)
- for (auto V : getContext().CUDAStaticDeviceVarReferencedByHost)
+ // Note we should not clear CUDADeviceVarODRUsedByHost since it is still
+ // needed for further handling.
+ if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice)
+ for (const auto *V : getContext().CUDADeviceVarODRUsedByHost)
DeferredDeclsToEmit.push_back(V);
// Stop if we're out of both deferred vtables and deferred declarations.
@@ -2485,29 +2595,28 @@ void CodeGenModule::AddGlobalAnnotations(const ValueDecl *D,
Annotations.push_back(EmitAnnotateAttr(GV, I, D->getLocation()));
}
-bool CodeGenModule::isInSanitizerBlacklist(SanitizerMask Kind,
- llvm::Function *Fn,
- SourceLocation Loc) const {
- const auto &SanitizerBL = getContext().getSanitizerBlacklist();
- // Blacklist by function name.
- if (SanitizerBL.isBlacklistedFunction(Kind, Fn->getName()))
+bool CodeGenModule::isInNoSanitizeList(SanitizerMask Kind, llvm::Function *Fn,
+ SourceLocation Loc) const {
+ const auto &NoSanitizeL = getContext().getNoSanitizeList();
+ // NoSanitize by function name.
+ if (NoSanitizeL.containsFunction(Kind, Fn->getName()))
return true;
- // Blacklist by location.
+ // NoSanitize by location.
if (Loc.isValid())
- return SanitizerBL.isBlacklistedLocation(Kind, Loc);
+ return NoSanitizeL.containsLocation(Kind, Loc);
// If location is unknown, this may be a compiler-generated function. Assume
// it's located in the main file.
auto &SM = Context.getSourceManager();
if (const auto *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
- return SanitizerBL.isBlacklistedFile(Kind, MainFile->getName());
+ return NoSanitizeL.containsFile(Kind, MainFile->getName());
}
return false;
}
-bool CodeGenModule::isInSanitizerBlacklist(llvm::GlobalVariable *GV,
- SourceLocation Loc, QualType Ty,
- StringRef Category) const {
- // For now globals can be blacklisted only in ASan and KASan.
+bool CodeGenModule::isInNoSanitizeList(llvm::GlobalVariable *GV,
+ SourceLocation Loc, QualType Ty,
+ StringRef Category) const {
+ // For now globals can be ignored only in ASan and KASan.
const SanitizerMask EnabledAsanMask =
LangOpts.Sanitize.Mask &
(SanitizerKind::Address | SanitizerKind::KernelAddress |
@@ -2515,22 +2624,22 @@ bool CodeGenModule::isInSanitizerBlacklist(llvm::GlobalVariable *GV,
SanitizerKind::MemTag);
if (!EnabledAsanMask)
return false;
- const auto &SanitizerBL = getContext().getSanitizerBlacklist();
- if (SanitizerBL.isBlacklistedGlobal(EnabledAsanMask, GV->getName(), Category))
+ const auto &NoSanitizeL = getContext().getNoSanitizeList();
+ if (NoSanitizeL.containsGlobal(EnabledAsanMask, GV->getName(), Category))
return true;
- if (SanitizerBL.isBlacklistedLocation(EnabledAsanMask, Loc, Category))
+ if (NoSanitizeL.containsLocation(EnabledAsanMask, Loc, Category))
return true;
// Check global type.
if (!Ty.isNull()) {
// Drill down the array types: if global variable of a fixed type is
- // blacklisted, we also don't instrument arrays of them.
+ // not sanitized, we also don't instrument arrays of them.
while (auto AT = dyn_cast<ArrayType>(Ty.getTypePtr()))
Ty = AT->getElementType();
Ty = Ty.getCanonicalType().getUnqualifiedType();
- // We allow to blacklist only record types (classes, structs etc.)
+ // Only record types (classes, structs etc.) are ignored.
if (Ty->isRecordType()) {
std::string TypeStr = Ty.getAsString(getContext().getPrintingPolicy());
- if (SanitizerBL.isBlacklistedType(EnabledAsanMask, TypeStr, Category))
+ if (NoSanitizeL.containsType(EnabledAsanMask, TypeStr, Category))
return true;
}
}
@@ -2607,19 +2716,24 @@ bool CodeGenModule::MustBeEmitted(const ValueDecl *Global) {
}
bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) {
+ // In OpenMP 5.0 variables and function may be marked as
+ // device_type(host/nohost) and we should not emit them eagerly unless we sure
+ // that they must be emitted on the host/device. To be sure we need to have
+ // seen a declare target with an explicit mentioning of the function, we know
+ // we have if the level of the declare target attribute is -1. Note that we
+ // check somewhere else if we should emit this at all.
+ if (LangOpts.OpenMP >= 50 && !LangOpts.OpenMPSimd) {
+ llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
+ OMPDeclareTargetDeclAttr::getActiveAttr(Global);
+ if (!ActiveAttr || (*ActiveAttr)->getLevel() != (unsigned)-1)
+ return false;
+ }
+
if (const auto *FD = dyn_cast<FunctionDecl>(Global)) {
if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
// Implicit template instantiations may change linkage if they are later
// explicitly instantiated, so they should not be emitted eagerly.
return false;
- // In OpenMP 5.0 function may be marked as device_type(nohost) and we should
- // not emit them eagerly unless we sure that the function must be emitted on
- // the host.
- if (LangOpts.OpenMP >= 50 && !LangOpts.OpenMPSimd &&
- !LangOpts.OpenMPIsDevice &&
- !OMPDeclareTargetDeclAttr::getDeviceType(FD) &&
- !FD->isUsed(/*CheckUsedAttr=*/false) && !FD->isReferenced())
- return false;
}
if (const auto *VD = dyn_cast<VarDecl>(Global))
if (Context.getInlineVariableDefinitionKind(VD) ==
@@ -2739,9 +2853,7 @@ ConstantAddress CodeGenModule::GetWeakRefReference(const ValueDecl *VD) {
GlobalDecl(cast<FunctionDecl>(VD)),
/*ForVTable=*/false);
else
- Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
- llvm::PointerType::getUnqual(DeclTy),
- nullptr);
+ Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), DeclTy, 0, nullptr);
auto *F = cast<llvm::GlobalValue>(Aliasee);
F->setLinkage(llvm::Function::ExternalWeakLinkage);
@@ -3031,7 +3143,7 @@ bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) {
if (CodeGenOpts.OptimizationLevel == 0 && !F->hasAttr<AlwaysInlineAttr>())
return false;
- if (F->hasAttr<DLLImportAttr>()) {
+ if (F->hasAttr<DLLImportAttr>() && !F->hasAttr<AlwaysInlineAttr>()) {
// Check whether it would be safe to inline this dllimport function.
DLLImportFunctionVisitor Visitor;
Visitor.TraverseFunctionDecl(const_cast<FunctionDecl*>(F));
@@ -3141,7 +3253,9 @@ TargetMVPriority(const TargetInfo &TI,
}
void CodeGenModule::emitMultiVersionFunctions() {
- for (GlobalDecl GD : MultiVersionFuncs) {
+ std::vector<GlobalDecl> MVFuncsToEmit;
+ MultiVersionFuncs.swap(MVFuncsToEmit);
+ for (GlobalDecl GD : MVFuncsToEmit) {
SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options;
const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
getContext().forEachMultiversionedFunctionVersion(
@@ -3195,6 +3309,17 @@ void CodeGenModule::emitMultiVersionFunctions() {
CodeGenFunction CGF(*this);
CGF.EmitMultiVersionResolver(ResolverFunc, Options);
}
+
+ // Ensure that any additions to the deferred decls list caused by emitting a
+ // variant are emitted. This can happen when the variant itself is inline and
+ // calls a function without linkage.
+ if (!MVFuncsToEmit.empty())
+ EmitDeferred();
+
+ // Ensure that any additions to the multiversion funcs list from either the
+ // deferred decls or the multiversion functions themselves are emitted.
+ if (!MultiVersionFuncs.empty())
+ emitMultiVersionFunctions();
}
void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
@@ -3269,7 +3394,7 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
++Index;
}
- llvm::sort(
+ llvm::stable_sort(
Options, [](const CodeGenFunction::MultiVersionResolverOption &LHS,
const CodeGenFunction::MultiVersionResolverOption &RHS) {
return CodeGenFunction::GetX86CpuSupportsMask(LHS.Conditions.Features) >
@@ -3575,9 +3700,19 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
}
StringRef MangledName = getMangledName(GD);
- return GetOrCreateLLVMFunction(MangledName, Ty, GD, ForVTable, DontDefer,
- /*IsThunk=*/false, llvm::AttributeList(),
- IsForDefinition);
+ auto *F = GetOrCreateLLVMFunction(MangledName, Ty, GD, ForVTable, DontDefer,
+ /*IsThunk=*/false, llvm::AttributeList(),
+ IsForDefinition);
+ // Returns kernel handle for HIP kernel stub function.
+ if (LangOpts.CUDA && !LangOpts.CUDAIsDevice &&
+ cast<FunctionDecl>(GD.getDecl())->hasAttr<CUDAGlobalAttr>()) {
+ auto *Handle = getCUDARuntime().getKernelHandle(
+ cast<llvm::Function>(F->stripPointerCasts()), GD);
+ if (IsForDefinition)
+ return F;
+ return llvm::ConstantExpr::getBitCast(Handle, Ty->getPointerTo());
+ }
+ return F;
}
static const FunctionDecl *
@@ -3586,8 +3721,8 @@ GetRuntimeFunctionDecl(ASTContext &C, StringRef Name) {
DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
IdentifierInfo &CII = C.Idents.get(Name);
- for (const auto &Result : DC->lookup(&CII))
- if (const auto FD = dyn_cast<FunctionDecl>(Result))
+ for (const auto *Result : DC->lookup(&CII))
+ if (const auto *FD = dyn_cast<FunctionDecl>(Result))
return FD;
if (!C.getLangOpts().CPlusPlus)
@@ -3601,15 +3736,15 @@ GetRuntimeFunctionDecl(ASTContext &C, StringRef Name) {
for (const auto &N : {"__cxxabiv1", "std"}) {
IdentifierInfo &NS = C.Idents.get(N);
- for (const auto &Result : DC->lookup(&NS)) {
- NamespaceDecl *ND = dyn_cast<NamespaceDecl>(Result);
- if (auto LSD = dyn_cast<LinkageSpecDecl>(Result))
- for (const auto &Result : LSD->lookup(&NS))
+ for (const auto *Result : DC->lookup(&NS)) {
+ const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(Result);
+ if (auto *LSD = dyn_cast<LinkageSpecDecl>(Result))
+ for (const auto *Result : LSD->lookup(&NS))
if ((ND = dyn_cast<NamespaceDecl>(Result)))
break;
if (ND)
- for (const auto &Result : ND->lookup(&CXXII))
+ for (const auto *Result : ND->lookup(&CXXII))
if (const auto *FD = dyn_cast<FunctionDecl>(Result))
return FD;
}
@@ -3680,9 +3815,9 @@ bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor) {
}
/// GetOrCreateLLVMGlobal - If the specified mangled name is not in the module,
-/// create and return an llvm GlobalVariable with the specified type. If there
-/// is something in the module with the specified name, return it potentially
-/// bitcasted to the right type.
+/// create and return an llvm GlobalVariable with the specified type and address
+/// space. If there is something in the module with the specified name, return
+/// it potentially bitcasted to the right type.
///
/// If D is non-null, it specifies a decl that correspond to this. This is used
/// to set the attributes on the global when it is first created.
@@ -3691,9 +3826,8 @@ bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor) {
/// type Ty will be returned, not conversion of a variable with the same
/// mangled name but some other type.
llvm::Constant *
-CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
- llvm::PointerType *Ty,
- const VarDecl *D,
+CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty,
+ unsigned AddrSpace, const VarDecl *D,
ForDefinition_t IsForDefinition) {
// Lookup the entry, lazily creating it if necessary.
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
@@ -3710,7 +3844,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
if (LangOpts.OpenMP && !LangOpts.OpenMPSimd && D)
getOpenMPRuntime().registerTargetGlobalVariable(D, Entry);
- if (Entry->getType() == Ty)
+ if (Entry->getValueType() == Ty && Entry->getAddressSpace() == AddrSpace)
return Entry;
// If there are two attempts to define the same mangled name, issue an
@@ -3734,22 +3868,24 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
}
// Make sure the result is of the correct type.
- if (Entry->getType()->getAddressSpace() != Ty->getAddressSpace())
- return llvm::ConstantExpr::getAddrSpaceCast(Entry, Ty);
+ if (Entry->getType()->getAddressSpace() != AddrSpace) {
+ return llvm::ConstantExpr::getAddrSpaceCast(Entry,
+ Ty->getPointerTo(AddrSpace));
+ }
// (If global is requested for a definition, we always need to create a new
// global, not just return a bitcast.)
if (!IsForDefinition)
- return llvm::ConstantExpr::getBitCast(Entry, Ty);
+ return llvm::ConstantExpr::getBitCast(Entry, Ty->getPointerTo(AddrSpace));
}
- auto AddrSpace = GetGlobalVarAddressSpace(D);
- auto TargetAddrSpace = getContext().getTargetAddressSpace(AddrSpace);
+ auto DAddrSpace = GetGlobalVarAddressSpace(D);
+ auto TargetAddrSpace = getContext().getTargetAddressSpace(DAddrSpace);
auto *GV = new llvm::GlobalVariable(
- getModule(), Ty->getElementType(), false,
- llvm::GlobalValue::ExternalLinkage, nullptr, MangledName, nullptr,
- llvm::GlobalVariable::NotThreadLocal, TargetAddrSpace);
+ getModule(), Ty, false, llvm::GlobalValue::ExternalLinkage, nullptr,
+ MangledName, nullptr, llvm::GlobalVariable::NotThreadLocal,
+ TargetAddrSpace);
// If we already created a global with the same mangled name (but different
// type) before, take its name and remove it from its parent.
@@ -3860,17 +3996,23 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
}
}
- if (GV->isDeclaration())
+ if (GV->isDeclaration()) {
getTargetCodeGenInfo().setTargetAttributes(D, GV, *this);
+ // External HIP managed variables needed to be recorded for transformation
+ // in both device and host compilations.
+ if (getLangOpts().CUDA && D && D->hasAttr<HIPManagedAttr>() &&
+ D->hasExternalStorage())
+ getCUDARuntime().handleVarRegistration(D, *GV);
+ }
LangAS ExpectedAS =
D ? D->getType().getAddressSpace()
: (LangOpts.OpenCL ? LangAS::opencl_global : LangAS::Default);
- assert(getContext().getTargetAddressSpace(ExpectedAS) ==
- Ty->getPointerAddressSpace());
- if (AddrSpace != ExpectedAS)
- return getTargetCodeGenInfo().performAddrSpaceCast(*this, GV, AddrSpace,
- ExpectedAS, Ty);
+ assert(getContext().getTargetAddressSpace(ExpectedAS) == AddrSpace);
+ if (DAddrSpace != ExpectedAS) {
+ return getTargetCodeGenInfo().performAddrSpaceCast(
+ *this, GV, DAddrSpace, ExpectedAS, Ty->getPointerTo(AddrSpace));
+ }
return GV;
}
@@ -3958,11 +4100,10 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
if (!Ty)
Ty = getTypes().ConvertTypeForMem(ASTTy);
- llvm::PointerType *PTy =
- llvm::PointerType::get(Ty, getContext().getTargetAddressSpace(ASTTy));
-
StringRef MangledName = getMangledName(D);
- return GetOrCreateLLVMGlobal(MangledName, PTy, D, IsForDefinition);
+ return GetOrCreateLLVMGlobal(MangledName, Ty,
+ getContext().getTargetAddressSpace(ASTTy), D,
+ IsForDefinition);
}
/// CreateRuntimeVariable - Create a new runtime global variable with the
@@ -3970,12 +4111,11 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
llvm::Constant *
CodeGenModule::CreateRuntimeVariable(llvm::Type *Ty,
StringRef Name) {
- auto PtrTy =
+ auto AddrSpace =
getContext().getLangOpts().OpenCL
- ? llvm::PointerType::get(
- Ty, getContext().getTargetAddressSpace(LangAS::opencl_global))
- : llvm::PointerType::getUnqual(Ty);
- auto *Ret = GetOrCreateLLVMGlobal(Name, PtrTy, nullptr);
+ ? getContext().getTargetAddressSpace(LangAS::opencl_global)
+ : 0;
+ auto *Ret = GetOrCreateLLVMGlobal(Name, Ty, AddrSpace, nullptr);
setDSOLocal(cast<llvm::GlobalValue>(Ret->stripPointerCasts()));
return Ret;
}
@@ -4025,6 +4165,10 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
return AddrSpace;
}
+ if (LangOpts.SYCLIsDevice &&
+ (!D || D->getType().getAddressSpace() == LangAS::Default))
+ return LangAS::sycl_global;
+
if (LangOpts.CUDA && LangOpts.CUDAIsDevice) {
if (D && D->hasAttr<CUDAConstantAttr>())
return LangAS::cuda_constant;
@@ -4046,10 +4190,12 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
return getTargetCodeGenInfo().getGlobalVarAddressSpace(*this, D);
}
-LangAS CodeGenModule::getStringLiteralAddressSpace() const {
+LangAS CodeGenModule::GetGlobalConstantAddressSpace() const {
// OpenCL v1.2 s6.5.3: a string literal is in the constant address space.
if (LangOpts.OpenCL)
return LangAS::opencl_constant;
+ if (LangOpts.SYCLIsDevice)
+ return LangAS::sycl_global;
if (auto AS = getTarget().getConstantAddressSpace())
return AS.getValue();
return LangAS::Default;
@@ -4068,13 +4214,12 @@ castStringLiteralToDefaultAddressSpace(CodeGenModule &CGM,
llvm::GlobalVariable *GV) {
llvm::Constant *Cast = GV;
if (!CGM.getLangOpts().OpenCL) {
- if (auto AS = CGM.getTarget().getConstantAddressSpace()) {
- if (AS != LangAS::Default)
- Cast = CGM.getTargetCodeGenInfo().performAddrSpaceCast(
- CGM, GV, AS.getValue(), LangAS::Default,
- GV->getValueType()->getPointerTo(
- CGM.getContext().getTargetAddressSpace(LangAS::Default)));
- }
+ auto AS = CGM.GetGlobalConstantAddressSpace();
+ if (AS != LangAS::Default)
+ Cast = CGM.getTargetCodeGenInfo().performAddrSpaceCast(
+ CGM, GV, AS, LangAS::Default,
+ GV->getValueType()->getPointerTo(
+ CGM.getContext().getTargetAddressSpace(LangAS::Default)));
}
return Cast;
}
@@ -4164,7 +4309,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
OpenMPRuntime->emitTargetGlobalVariable(D))
return;
- llvm::Constant *Init = nullptr;
+ llvm::TrackingVH<llvm::Constant> Init;
bool NeedsGlobalCtor = false;
bool NeedsGlobalDtor =
D->needsDestruction(getContext()) == QualType::DK_cxx_destructor;
@@ -4181,22 +4326,20 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
getLangOpts().CUDAIsDevice && D->hasAttr<CUDASharedAttr>();
// Shadows of initialized device-side global variables are also left
// undefined.
+ // Managed Variables should be initialized on both host side and device side.
bool IsCUDAShadowVar =
!getLangOpts().CUDAIsDevice && !D->hasAttr<HIPManagedAttr>() &&
(D->hasAttr<CUDAConstantAttr>() || D->hasAttr<CUDADeviceAttr>() ||
D->hasAttr<CUDASharedAttr>());
bool IsCUDADeviceShadowVar =
- getLangOpts().CUDAIsDevice &&
+ getLangOpts().CUDAIsDevice && !D->hasAttr<HIPManagedAttr>() &&
(D->getType()->isCUDADeviceBuiltinSurfaceType() ||
- D->getType()->isCUDADeviceBuiltinTextureType() ||
- D->hasAttr<HIPManagedAttr>());
- // HIP pinned shadow of initialized host-side global variables are also
- // left undefined.
+ D->getType()->isCUDADeviceBuiltinTextureType());
if (getLangOpts().CUDA &&
(IsCUDASharedVar || IsCUDAShadowVar || IsCUDADeviceShadowVar))
- Init = llvm::UndefValue::get(getTypes().ConvertType(ASTTy));
+ Init = llvm::UndefValue::get(getTypes().ConvertTypeForMem(ASTTy));
else if (D->hasAttr<LoaderUninitializedAttr>())
- Init = llvm::UndefValue::get(getTypes().ConvertType(ASTTy));
+ Init = llvm::UndefValue::get(getTypes().ConvertTypeForMem(ASTTy));
else if (!InitExpr) {
// This is a tentative definition; tentative definitions are
// implicitly initialized with { 0 }.
@@ -4212,9 +4355,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
} else {
initializedGlobalDecl = GlobalDecl(D);
emitter.emplace(*this);
- Init = emitter->tryEmitForInitializer(*InitDecl);
-
- if (!Init) {
+ llvm::Constant *Initializer = emitter->tryEmitForInitializer(*InitDecl);
+ if (!Initializer) {
QualType T = InitExpr->getType();
if (D->getType()->isReferenceType())
T = D->getType();
@@ -4227,6 +4369,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
Init = llvm::UndefValue::get(getTypes().ConvertType(T));
}
} else {
+ Init = Initializer;
// We don't need an initializer, so remove the entry for the delayed
// initializer position (just in case this entry was delayed) if we
// also don't need to register a destructor.
@@ -4268,7 +4411,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
// Replace all uses of the old global with the new global
llvm::Constant *NewPtrForOldDecl =
- llvm::ConstantExpr::getBitCast(GV, Entry->getType());
+ llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV,
+ Entry->getType());
Entry->replaceAllUsesWith(NewPtrForOldDecl);
// Erase the old global, since it is no longer used.
@@ -4297,60 +4441,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
(D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDAConstantAttr>()))
GV->setExternallyInitialized(true);
} else {
- // Host-side shadows of external declarations of device-side
- // global variables become internal definitions. These have to
- // be internal in order to prevent name conflicts with global
- // host variables with the same name in a different TUs.
- if (D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDAConstantAttr>()) {
- Linkage = llvm::GlobalValue::InternalLinkage;
- // Shadow variables and their properties must be registered with CUDA
- // runtime. Skip Extern global variables, which will be registered in
- // the TU where they are defined.
- //
- // Don't register a C++17 inline variable. The local symbol can be
- // discarded and referencing a discarded local symbol from outside the
- // comdat (__cuda_register_globals) is disallowed by the ELF spec.
- // TODO: Reject __device__ constexpr and __device__ inline in Sema.
- if (!D->hasExternalStorage() && !D->isInline())
- getCUDARuntime().registerDeviceVar(D, *GV, !D->hasDefinition(),
- D->hasAttr<CUDAConstantAttr>());
- } else if (D->hasAttr<CUDASharedAttr>()) {
- // __shared__ variables are odd. Shadows do get created, but
- // they are not registered with the CUDA runtime, so they
- // can't really be used to access their device-side
- // counterparts. It's not clear yet whether it's nvcc's bug or
- // a feature, but we've got to do the same for compatibility.
- Linkage = llvm::GlobalValue::InternalLinkage;
- } else if (D->getType()->isCUDADeviceBuiltinSurfaceType() ||
- D->getType()->isCUDADeviceBuiltinTextureType()) {
- // Builtin surfaces and textures and their template arguments are
- // also registered with CUDA runtime.
- Linkage = llvm::GlobalValue::InternalLinkage;
- const ClassTemplateSpecializationDecl *TD =
- cast<ClassTemplateSpecializationDecl>(
- D->getType()->getAs<RecordType>()->getDecl());
- const TemplateArgumentList &Args = TD->getTemplateArgs();
- if (TD->hasAttr<CUDADeviceBuiltinSurfaceTypeAttr>()) {
- assert(Args.size() == 2 &&
- "Unexpected number of template arguments of CUDA device "
- "builtin surface type.");
- auto SurfType = Args[1].getAsIntegral();
- if (!D->hasExternalStorage())
- getCUDARuntime().registerDeviceSurf(D, *GV, !D->hasDefinition(),
- SurfType.getSExtValue());
- } else {
- assert(Args.size() == 3 &&
- "Unexpected number of template arguments of CUDA device "
- "builtin texture type.");
- auto TexType = Args[1].getAsIntegral();
- auto Normalized = Args[2].getAsIntegral();
- if (!D->hasExternalStorage())
- getCUDARuntime().registerDeviceTex(D, *GV, !D->hasDefinition(),
- TexType.getSExtValue(),
- Normalized.getZExtValue());
- }
- }
+ getCUDARuntime().internalizeDeviceSideVar(D, Linkage);
}
+ getCUDARuntime().handleVarRegistration(D, *GV);
}
GV->setInitializer(Init);
@@ -4436,9 +4529,8 @@ void CodeGenModule::EmitExternalVarDeclaration(const VarDecl *D) {
if (getCodeGenOpts().hasReducedDebugInfo()) {
QualType ASTTy = D->getType();
llvm::Type *Ty = getTypes().ConvertTypeForMem(D->getType());
- llvm::PointerType *PTy =
- llvm::PointerType::get(Ty, getContext().getTargetAddressSpace(ASTTy));
- llvm::Constant *GV = GetOrCreateLLVMGlobal(D->getName(), PTy, D);
+ llvm::Constant *GV = GetOrCreateLLVMGlobal(
+ D->getName(), Ty, getContext().getTargetAddressSpace(ASTTy), D);
DI->EmitExternalVariable(
cast<llvm::GlobalVariable>(GV->stripPointerCasts()), D);
}
@@ -4610,7 +4702,6 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
llvm::Type *newRetTy = newFn->getReturnType();
SmallVector<llvm::Value*, 4> newArgs;
- SmallVector<llvm::OperandBundleDef, 1> newBundles;
for (llvm::Value::use_iterator ui = old->use_begin(), ue = old->use_end();
ui != ue; ) {
@@ -4667,6 +4758,7 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
newArgs.append(callSite->arg_begin(), callSite->arg_begin() + argNo);
// Copy over any operand bundles.
+ SmallVector<llvm::OperandBundleDef, 1> newBundles;
callSite->getOperandBundlesAsDefs(newBundles);
llvm::CallBase *newCall;
@@ -4810,8 +4902,7 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
/*ForVTable=*/false);
LT = getFunctionLinkage(GD);
} else {
- Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
- llvm::PointerType::getUnqual(DeclTy),
+ Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), DeclTy, 0,
/*D=*/nullptr);
if (const auto *VD = dyn_cast<VarDecl>(GD.getDecl()))
LT = getLLVMLinkageVarDefinition(VD, D->getType().isConstQualified());
@@ -5027,7 +5118,7 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) {
DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
const VarDecl *VD = nullptr;
- for (const auto &Result : DC->lookup(&II))
+ for (const auto *Result : DC->lookup(&II))
if ((VD = dyn_cast<VarDecl>(Result)))
break;
@@ -5239,7 +5330,7 @@ GenerateStringLiteral(llvm::Constant *C, llvm::GlobalValue::LinkageTypes LT,
CodeGenModule &CGM, StringRef GlobalName,
CharUnits Alignment) {
unsigned AddrSpace = CGM.getContext().getTargetAddressSpace(
- CGM.getStringLiteralAddressSpace());
+ CGM.GetGlobalConstantAddressSpace());
llvm::Module &M = CGM.getModule();
// Create a global variable for this string
@@ -5366,8 +5457,21 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
CharUnits Align = getContext().getTypeAlignInChars(MaterializedType);
- if (llvm::Constant *Slot = MaterializedGlobalTemporaryMap[E])
- return ConstantAddress(Slot, Align);
+ auto InsertResult = MaterializedGlobalTemporaryMap.insert({E, nullptr});
+ if (!InsertResult.second) {
+ // We've seen this before: either we already created it or we're in the
+ // process of doing so.
+ if (!InsertResult.first->second) {
+ // We recursively re-entered this function, probably during emission of
+ // the initializer. Create a placeholder. We'll clean this up in the
+ // outer call, at the end of this function.
+ llvm::Type *Type = getTypes().ConvertTypeForMem(MaterializedType);
+ InsertResult.first->second = new llvm::GlobalVariable(
+ getModule(), Type, false, llvm::GlobalVariable::InternalLinkage,
+ nullptr);
+ }
+ return ConstantAddress(InsertResult.first->second, Align);
+ }
// FIXME: If an externally-visible declaration extends multiple temporaries,
// we need to give each temporary the same name in every translation unit (and
@@ -5446,7 +5550,17 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
*this, GV, AddrSpace, LangAS::Default,
Type->getPointerTo(
getContext().getTargetAddressSpace(LangAS::Default)));
- MaterializedGlobalTemporaryMap[E] = CV;
+
+ // Update the map with the new temporary. If we created a placeholder above,
+ // replace it with the new global now.
+ llvm::Constant *&Entry = MaterializedGlobalTemporaryMap[E];
+ if (Entry) {
+ Entry->replaceAllUsesWith(
+ llvm::ConstantExpr::getBitCast(CV, Entry->getType()));
+ llvm::cast<llvm::GlobalVariable>(Entry)->eraseFromParent();
+ }
+ Entry = CV;
+
return ConstantAddress(CV, Align);
}
@@ -5649,6 +5763,10 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
if (CGDebugInfo *DI = getModuleDebugInfo())
DI->EmitUsingDecl(cast<UsingDecl>(*D));
break;
+ case Decl::UsingEnum: // using enum X; [C++]
+ if (CGDebugInfo *DI = getModuleDebugInfo())
+ DI->EmitUsingEnumDecl(cast<UsingEnumDecl>(*D));
+ break;
case Decl::NamespaceAlias:
if (CGDebugInfo *DI = getModuleDebugInfo())
DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(*D));
@@ -5747,6 +5865,9 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
// File-scope asm is ignored during device-side OpenMP compilation.
if (LangOpts.OpenMPIsDevice)
break;
+ // File-scope asm is ignored during device-side SYCL compilation.
+ if (LangOpts.SYCLIsDevice)
+ break;
auto *AD = cast<FileScopeAsmDecl>(D);
getModule().appendModuleInlineAsm(AD->getAsmString()->getString());
break;
@@ -5804,6 +5925,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
break;
case Decl::OMPAllocate:
+ EmitOMPAllocateDecl(cast<OMPAllocateDecl>(D));
break;
case Decl::OMPDeclareReduction:
@@ -5973,7 +6095,7 @@ void CodeGenModule::EmitStaticExternCAliases() {
IdentifierInfo *Name = I.first;
llvm::GlobalValue *Val = I.second;
if (Val && !getModule().getNamedValue(Name->getName()))
- addUsedGlobal(llvm::GlobalAlias::create(Name->getName(), Val));
+ addCompilerUsedGlobal(llvm::GlobalAlias::create(Name->getName(), Val));
}
}
@@ -6215,15 +6337,16 @@ llvm::SanitizerStatReport &CodeGenModule::getSanStats() {
return *SanStats;
}
+
llvm::Value *
CodeGenModule::createOpenCLIntToSamplerConversion(const Expr *E,
CodeGenFunction &CGF) {
llvm::Constant *C = ConstantEmitter(CGF).emitAbstract(E, E->getType());
- auto SamplerT = getOpenCLRuntime().getSamplerType(E->getType().getTypePtr());
- auto FTy = llvm::FunctionType::get(SamplerT, {C->getType()}, false);
- return CGF.Builder.CreateCall(CreateRuntimeFunction(FTy,
- "__translate_sampler_initializer"),
- {C});
+ auto *SamplerT = getOpenCLRuntime().getSamplerType(E->getType().getTypePtr());
+ auto *FTy = llvm::FunctionType::get(SamplerT, {C->getType()}, false);
+ auto *Call = CGF.EmitRuntimeCall(
+ CreateRuntimeFunction(FTy, "__translate_sampler_initializer"), {C});
+ return Call;
}
CharUnits CodeGenModule::getNaturalPointeeTypeAlignment(
@@ -6322,3 +6445,8 @@ bool CodeGenModule::stopAutoInit() {
}
return false;
}
+
+void CodeGenModule::printPostfixForExternalizedStaticVar(
+ llvm::raw_ostream &OS) const {
+ OS << ".static." << getContext().getCUIDHash();
+}