diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
commit | 344a3780b2e33f6ca763666c380202b18aab72a3 (patch) | |
tree | f0b203ee6eb71d7fdd792373e3c81eb18d6934dd /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) |
vendor/llvm-project/llvmorg-13-init-16847-g88e66fa60ae5vendor/llvm-project/llvmorg-12.0.1-rc2-0-ge7dac564cd0evendor/llvm-project/llvmorg-12.0.1-0-gfed41342a82f
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 654 |
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(); +} |