diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2020-08-03 14:31:34 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2020-08-03 14:31:34 +0000 |
commit | 25a6f5d245dd7dd5c82a5a50d9620fe3f5750027 (patch) | |
tree | 912c58777b333602c19428b70e864d8626ecd988 /gnu/llvm | |
parent | 1ec8ba953b54803f56d3653af5942facaf63062e (diff) |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm')
-rw-r--r-- | gnu/llvm/clang/lib/CodeGen/CodeGenModule.cpp | 1470 |
1 files changed, 469 insertions, 1001 deletions
diff --git a/gnu/llvm/clang/lib/CodeGen/CodeGenModule.cpp b/gnu/llvm/clang/lib/CodeGen/CodeGenModule.cpp index 49a1396b58e..f8866ac4f7f 100644 --- a/gnu/llvm/clang/lib/CodeGen/CodeGenModule.cpp +++ b/gnu/llvm/clang/lib/CodeGen/CodeGenModule.cpp @@ -19,7 +19,6 @@ #include "CGObjCRuntime.h" #include "CGOpenCLRuntime.h" #include "CGOpenMPRuntime.h" -#include "CGOpenMPRuntimeAMDGCN.h" #include "CGOpenMPRuntimeNVPTX.h" #include "CodeGenFunction.h" #include "CodeGenPGO.h" @@ -39,7 +38,6 @@ #include "clang/Basic/CharInfo.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/Diagnostic.h" -#include "clang/Basic/FileManager.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -75,17 +73,16 @@ static llvm::cl::opt<bool> LimitedCoverage( static const char AnnotationSection[] = "llvm.metadata"; static CGCXXABI *createCXXABI(CodeGenModule &CGM) { - switch (CGM.getContext().getCXXABIKind()) { - case TargetCXXABI::AppleARM64: + switch (CGM.getTarget().getCXXABI().getKind()) { case TargetCXXABI::Fuchsia: case TargetCXXABI::GenericAArch64: case TargetCXXABI::GenericARM: case TargetCXXABI::iOS: + case TargetCXXABI::iOS64: case TargetCXXABI::WatchOS: case TargetCXXABI::GenericMIPS: case TargetCXXABI::GenericItanium: case TargetCXXABI::WebAssembly: - case TargetCXXABI::XL: return CreateItaniumCXXABI(CGM); case TargetCXXABI::Microsoft: return CreateMicrosoftCXXABI(CGM); @@ -113,7 +110,6 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO, Int32Ty = llvm::Type::getInt32Ty(LLVMContext); Int64Ty = llvm::Type::getInt64Ty(LLVMContext); HalfTy = llvm::Type::getHalfTy(LLVMContext); - BFloatTy = llvm::Type::getBFloatTy(LLVMContext); FloatTy = llvm::Type::getFloatTy(LLVMContext); DoubleTy = llvm::Type::getDoubleTy(LLVMContext); PointerWidthInBits = C.getTargetInfo().getPointerWidth(0); @@ -123,8 +119,6 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO, C.toCharUnitsFromBits(C.getTargetInfo().getMaxPointerWidth()).getQuantity(); IntAlignInBytes = C.toCharUnitsFromBits(C.getTargetInfo().getIntAlign()).getQuantity(); - CharTy = - llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getCharWidth()); IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth()); IntPtrTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getMaxPointerWidth()); @@ -180,34 +174,6 @@ 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 : LangOpts.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() {} @@ -246,11 +212,6 @@ void CodeGenModule::createOpenMPRuntime() { "OpenMP NVPTX is only prepared to deal with device code."); OpenMPRuntime.reset(new CGOpenMPRuntimeNVPTX(*this)); break; - case llvm::Triple::amdgcn: - assert(getLangOpts().OpenMPIsDevice && - "OpenMP AMDGCN is only prepared to deal with device code."); - OpenMPRuntime.reset(new CGOpenMPRuntimeAMDGCN(*this)); - break; default: if (LangOpts.OpenMPSimd) OpenMPRuntime.reset(new CGOpenMPSIMDRuntime(*this)); @@ -258,6 +219,14 @@ void CodeGenModule::createOpenMPRuntime() { OpenMPRuntime.reset(new CGOpenMPRuntime(*this)); break; } + + // The OpenMP-IR-Builder should eventually replace the above runtime codegens + // but we are not there yet so they both reside in CGModule for now and the + // OpenMP-IR-Builder is opt-in only. + if (LangOpts.OpenMPIRBuilder) { + OMPBuilder.reset(new llvm::OpenMPIRBuilder(TheModule)); + OMPBuilder->initialize(); + } } void CodeGenModule::createCUDARuntime() { @@ -402,7 +371,7 @@ void CodeGenModule::checkAliases() { for (const GlobalDecl &GD : Aliases) { StringRef MangledName = getMangledName(GD); llvm::GlobalValue *Entry = GetGlobalValue(MangledName); - auto *Alias = cast<llvm::GlobalIndirectSymbol>(Entry); + auto *Alias = dyn_cast<llvm::GlobalIndirectSymbol>(Entry); Alias->replaceAllUsesWith(llvm::UndefValue::get(Alias->getType())); Alias->eraseFromParent(); } @@ -431,48 +400,6 @@ void InstrProfStats::reportDiagnostics(DiagnosticsEngine &Diags, } } -static void setVisibilityFromDLLStorageClass(const clang::LangOptions &LO, - llvm::Module &M) { - if (!LO.VisibilityFromDLLStorageClass) - return; - - llvm::GlobalValue::VisibilityTypes DLLExportVisibility = - CodeGenModule::GetLLVMVisibility(LO.getDLLExportVisibility()); - llvm::GlobalValue::VisibilityTypes NoDLLStorageClassVisibility = - CodeGenModule::GetLLVMVisibility(LO.getNoDLLStorageClassVisibility()); - llvm::GlobalValue::VisibilityTypes ExternDeclDLLImportVisibility = - CodeGenModule::GetLLVMVisibility(LO.getExternDeclDLLImportVisibility()); - llvm::GlobalValue::VisibilityTypes ExternDeclNoDLLStorageClassVisibility = - CodeGenModule::GetLLVMVisibility( - LO.getExternDeclNoDLLStorageClassVisibility()); - - for (llvm::GlobalValue &GV : M.global_values()) { - if (GV.hasAppendingLinkage() || GV.hasLocalLinkage()) - continue; - - // Reset DSO locality before setting the visibility. This removes - // any effects that visibility options and annotations may have - // had on the DSO locality. Setting the visibility will implicitly set - // appropriate globals to DSO Local; however, this will be pessimistic - // w.r.t. to the normal compiler IRGen. - GV.setDSOLocal(false); - - if (GV.isDeclarationForLinker()) { - GV.setVisibility(GV.getDLLStorageClass() == - llvm::GlobalValue::DLLImportStorageClass - ? ExternDeclDLLImportVisibility - : ExternDeclNoDLLStorageClassVisibility); - } else { - GV.setVisibility(GV.getDLLStorageClass() == - llvm::GlobalValue::DLLExportStorageClass - ? DLLExportVisibility - : NoDLLStorageClassVisibility); - } - - GV.setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); - } -} - void CodeGenModule::Release() { EmitDeferred(); EmitVTablesOpportunistically(); @@ -481,14 +408,16 @@ void CodeGenModule::Release() { checkAliases(); emitMultiVersionFunctions(); EmitCXXGlobalInitFunc(); - EmitCXXGlobalCleanUpFunc(); + EmitCXXGlobalDtorFunc(); registerGlobalDtorsWithAtExit(); EmitCXXThreadLocalInitFunc(); if (ObjCRuntime) if (llvm::Function *ObjCInitFunction = ObjCRuntime->ModuleInitFunction()) AddGlobalCtor(ObjCInitFunction); - if (Context.getLangOpts().CUDA && CUDARuntime) { - if (llvm::Function *CudaCtorFunction = CUDARuntime->finalizeModule()) + if (Context.getLangOpts().CUDA && !Context.getLangOpts().CUDAIsDevice && + CUDARuntime) { + if (llvm::Function *CudaCtorFunction = + CUDARuntime->makeModuleCtorFunction()) AddGlobalCtor(CudaCtorFunction); } if (OpenMPRuntime) { @@ -511,7 +440,6 @@ void CodeGenModule::Release() { EmitGlobalAnnotations(); EmitStaticExternCAliases(); EmitDeferredUnusedCoverageMappings(); - CodeGenPGO(*this).setValueProfilingFlag(getModule()); if (CoverageMapping) CoverageMapping->emit(); if (CodeGenOpts.SanitizeCfiCrossDso) { @@ -519,26 +447,6 @@ void CodeGenModule::Release() { CodeGenFunction(*this).EmitCfiCheckStub(); } emitAtAvailableLinkGuard(); - if (Context.getTargetInfo().getTriple().isWasm() && - !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(); @@ -575,14 +483,6 @@ void CodeGenModule::Release() { getModule().addModuleFlag(llvm::Module::Max, "Dwarf Version", 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); - if (CodeGenOpts.EmitCodeView) { // Indicate that we want CodeView in the metadata. getModule().addModuleFlag(llvm::Module::Warning, "CodeView", 1); @@ -597,10 +497,6 @@ 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 @@ -617,7 +513,7 @@ void CodeGenModule::Release() { "StrictVTablePointersRequirement", llvm::MDNode::get(VMContext, Ops)); } - if (getModuleDebugInfo()) + if (DebugInfo) // We support a single version in the linked module. The LLVM // parser will drop debug info with a different version number // (and warn about it, too). @@ -653,14 +549,6 @@ void CodeGenModule::Release() { getModule().addModuleFlag(llvm::Module::Override, "Cross-DSO CFI", 1); } - if (CodeGenOpts.WholeProgramVTables) { - // Indicate whether VFE was enabled for this module, so that the - // vcall_visibility metadata added under whole program vtables is handled - // appropriately in the optimizer. - getModule().addModuleFlag(llvm::Module::Error, "Virtual Function Elim", - CodeGenOpts.VirtualFunctionElimination); - } - if (LangOpts.Sanitize.has(SanitizerKind::CFIICall)) { getModule().addModuleFlag(llvm::Module::Override, "CFI Canonical Jump Tables", @@ -681,49 +569,14 @@ void CodeGenModule::Release() { 1); } - if (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_32 || - Arch == llvm::Triple::aarch64_be) { - getModule().addModuleFlag(llvm::Module::Error, - "branch-target-enforcement", - LangOpts.BranchTargetEnforcement); - - getModule().addModuleFlag(llvm::Module::Error, "sign-return-address", - LangOpts.hasSignReturnAddress()); - - getModule().addModuleFlag(llvm::Module::Error, "sign-return-address-all", - LangOpts.isSignReturnAddressScopeAll()); - - getModule().addModuleFlag(llvm::Module::Error, - "sign-return-address-with-bkey", - !LangOpts.isSignReturnAddressWithAKey()); - } - - if (!CodeGenOpts.MemoryProfileOutput.empty()) { - llvm::LLVMContext &Ctx = TheModule.getContext(); - getModule().addModuleFlag( - llvm::Module::Error, "MemProfProfileFilename", - llvm::MDString::get(Ctx, CodeGenOpts.MemoryProfileOutput)); - } - if (LangOpts.CUDAIsDevice && getTriple().isNVPTX()) { // Indicate whether __nvvm_reflect should be configured to flush denormal // floating point values to 0. (This corresponds to its "__CUDA_FTZ" // property.) getModule().addModuleFlag(llvm::Module::Override, "nvvm-reflect-ftz", - CodeGenOpts.FP32DenormalMode.Output != - llvm::DenormalMode::IEEE); + CodeGenOpts.FlushDenorm ? 1 : 0); } - 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(); @@ -768,20 +621,6 @@ 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(); @@ -791,8 +630,8 @@ void CodeGenModule::Release() { if (getCodeGenOpts().EmitGcovArcs || getCodeGenOpts().EmitGcovNotes) EmitCoverageFile(); - if (CGDebugInfo *DI = getModuleDebugInfo()) - DI->finalize(); + if (DebugInfo) + DebugInfo->finalize(); if (getCodeGenOpts().EmitVersionIdentMetadata) EmitVersionIdentMetadata(); @@ -800,26 +639,7 @@ 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()); - - // Set visibility from DLL storage class - // We do this at the end of LLVM IR generation; after any operation - // that might affect the DLL storage class or the visibility, and - // before anything that might act on these. - setVisibilityFromDLLStorageClass(LangOpts, getModule()); + EmitTargetMetadata(); } void CodeGenModule::EmitOpenCLMetadata() { @@ -839,19 +659,6 @@ void CodeGenModule::EmitOpenCLMetadata() { OCLVerMD->addOperand(llvm::MDNode::get(Ctx, OCLVerElts)); } -void CodeGenModule::EmitBackendOptionsMetadata( - const CodeGenOptions CodeGenOpts) { - switch (getTriple().getArch()) { - default: - break; - case llvm::Triple::riscv32: - case llvm::Triple::riscv64: - getModule().addModuleFlag(llvm::Module::Error, "SmallDataLimit", - CodeGenOpts.SmallDataLimit); - break; - } -} - void CodeGenModule::UpdateCompletedType(const TagDecl *TD) { // Make sure that this type is translated. Types.UpdateCompletedType(TD); @@ -871,19 +678,6 @@ llvm::MDNode *CodeGenModule::getTBAATypeInfo(QualType QTy) { TBAAAccessInfo CodeGenModule::getTBAAAccessInfo(QualType AccessType) { if (!TBAA) return TBAAAccessInfo(); - if (getLangOpts().CUDAIsDevice) { - // As CUDA builtin surface/texture types are replaced, skip generating TBAA - // access info. - if (AccessType->isCUDADeviceBuiltinSurfaceType()) { - if (getTargetCodeGenInfo().getCUDADeviceBuiltinSurfaceDeviceType() != - nullptr) - return TBAAAccessInfo(); - } else if (AccessType->isCUDADeviceBuiltinTextureType()) { - if (getTargetCodeGenInfo().getCUDADeviceBuiltinTextureDeviceType() != - nullptr) - return TBAAAccessInfo(); - } - } return TBAA->getAccessInfo(AccessType); } @@ -1011,13 +805,8 @@ 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() || CGM.getCodeGenOpts().EmulatedTLS)) + !GV->isThreadLocal()) return false; } @@ -1043,17 +832,8 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM, 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 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); - } + if (RM != llvm::Reloc::Static && !LOpts.PIE) + return false; // A definition cannot be preempted from an executable. if (!GV->isDeclarationForLinker()) @@ -1065,33 +845,25 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM, if (RM == llvm::Reloc::PIC_ && GV->hasExternalWeakLinkage()) return false; - // PowerPC64 prefers TOC indirection to avoid copy relocations. - if (TT.isPPC64()) + // PPC has no copy relocations and cannot use a plt entry as a symbol address. + llvm::Triple::ArchType Arch = TT.getArch(); + if (Arch == llvm::Triple::ppc || Arch == llvm::Triple::ppc64 || + Arch == llvm::Triple::ppc64le) return false; - if (CGOpts.DirectAccessExternalData) { - // If -fdirect-access-external-data (default for -fno-pic), set dso_local - // for non-thread-local variables. If the symbol is not defined in the - // executable, a copy relocation will be needed at link time. dso_local is - // excluded for thread-local variables because they generally don't support - // copy relocations. - if (auto *Var = dyn_cast<llvm::GlobalVariable>(GV)) - if (!Var->isThreadLocal()) - return true; - - // -fno-pic sets dso_local on a function declaration to allow direct - // accesses when taking its address (similar to a data symbol). If the - // function is not defined in the executable, a canonical PLT entry will be - // needed at link time. -fno-direct-access-external-data can avoid the - // canonical PLT entry. We don't generalize this condition to -fpie/-fpic as - // it could just cause trouble without providing perceptible benefits. - if (isa<llvm::Function>(GV) && !CGOpts.NoPLT && RM == llvm::Reloc::Static) + // If we can use copy relocations we can assume it is local. + if (auto *Var = dyn_cast<llvm::GlobalVariable>(GV)) + if (!Var->isThreadLocal() && + (RM == llvm::Reloc::Static || CGOpts.PIECopyRelocations)) return true; - } - // If we can use copy relocations we can assume it is local. + // If we can use a plt entry as the symbol address we can assume it + // is local. + // FIXME: This should work for PIE, but the gold linker doesn't support it. + if (isa<llvm::Function>(GV) && !CGOpts.NoPLT && RM == llvm::Reloc::Static) + return true; - // Otherwise don't assume it is local. + // Otherwise don't assue it is local. return false; } @@ -1147,9 +919,9 @@ static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(StringRef S) { .Case("local-exec", llvm::GlobalVariable::LocalExecTLSModel); } -llvm::GlobalVariable::ThreadLocalMode -CodeGenModule::GetDefaultLLVMTLSModel() const { - switch (CodeGenOpts.getDefaultTLSModel()) { +static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel( + CodeGenOptions::TLSModel M) { + switch (M) { case CodeGenOptions::GeneralDynamicTLSModel: return llvm::GlobalVariable::GeneralDynamicTLSModel; case CodeGenOptions::LocalDynamicTLSModel: @@ -1166,7 +938,7 @@ void CodeGenModule::setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const { assert(D.getTLSKind() && "setting TLS mode on non-TLS var!"); llvm::GlobalValue::ThreadLocalMode TLM; - TLM = GetDefaultLLVMTLSModel(); + TLM = GetLLVMTLSModel(CodeGenOpts.getDefaultTLSModel()); // Override the TLS model if it is explicitly specified. if (const TLSModelAttr *Attr = D.getAttr<TLSModelAttr>()) { @@ -1226,56 +998,34 @@ static void AppendTargetMangling(const CodeGenModule &CGM, } } -// 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, +static std::string getMangledNameImpl(const 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 (!CGM.getModuleNameHash().empty()) - MC.needsUniqueInternalLinkageNames(); - bool ShouldMangle = MC.shouldMangleDeclName(ND); - if (ShouldMangle) - MC.mangleName(GD.getWithDecl(ND), Out); - else { + if (MC.shouldMangleDeclName(ND)) { + llvm::raw_svector_ostream Out(Buffer); + if (const auto *D = dyn_cast<CXXConstructorDecl>(ND)) + MC.mangleCXXCtor(D, GD.getCtorType(), Out); + else if (const auto *D = dyn_cast<CXXDestructorDecl>(ND)) + MC.mangleCXXDtor(D, GD.getDtorType(), Out); + else + MC.mangleName(ND, Out); + } else { IdentifierInfo *II = ND->getIdentifier(); assert(II && "Attempt to mangle unnamed decl."); const auto *FD = dyn_cast<FunctionDecl>(ND); if (FD && FD->getType()->castAs<FunctionType>()->getCallConv() == CC_X86RegCall) { + llvm::raw_svector_ostream Out(Buffer); Out << "__regcall3__" << II->getName(); - } else if (FD && FD->hasAttr<CUDAGlobalAttr>() && - GD.getKernelReferenceKind() == KernelReferenceKind::Stub) { - Out << "__device_stub__" << II->getName(); } else { Out << II->getName(); } } - // 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()) { @@ -1293,12 +1043,7 @@ static std::string getMangledNameImpl(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()); + return Out.str(); } void CodeGenModule::UpdateMultiVersionNames(GlobalDecl GD, @@ -1355,40 +1100,19 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) { } } - // 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; - } + 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()); std::string MangledName = getMangledNameImpl(*this, GD, ND); - // Ensure either we have different ABIs between host and device compilations, - // says host compilation following MSVC ABI but device compilation follows - // Itanium C++ ABI or, if they follow the same ABI, kernel names after - // mangling should be the same after name stubbing. The later checking is - // very important as the device kernel name being mangled in host-compilation - // is used to resolve the device binaries to be executed. Inconsistent naming - // result in undefined behavior. Even though we cannot check that naming - // directly between host- and device-compilations, the host- and - // device-mangling in host compilation could help catching certain ones. - assert(!isa<FunctionDecl>(ND) || !ND->hasAttr<CUDAGlobalAttr>() || - getLangOpts().CUDAIsDevice || - (getContext().getAuxTargetInfo() && - (getContext().getAuxTargetInfo()->getCXXABI() != - getContext().getTargetInfo().getCXXABI())) || - getCUDARuntime().getDeviceSideName(ND) == - getMangledNameImpl( - *this, - GD.getWithKernelReferenceKind(KernelReferenceKind::Kernel), - ND)); + // Adjust kernel stub mangling as we may need to be able to differentiate + // them from the kernel itself (e.g., for HIP). + if (auto *FD = dyn_cast<FunctionDecl>(GD.getDecl())) + if (!getLangOpts().CUDAIsDevice && FD->hasAttr<CUDAGlobalAttr>()) + MangledName = getCUDARuntime().getDeviceStubName(MangledName); auto Result = Manglings.insert(std::make_pair(MangledName, GD)); return MangledDeclNames[CanonicalGD] = Result.first->first(); @@ -1429,10 +1153,8 @@ void CodeGenModule::AddGlobalCtor(llvm::Function *Ctor, int Priority, /// AddGlobalDtor - Add a function to the list that will be called /// when the module is unloaded. -void CodeGenModule::AddGlobalDtor(llvm::Function *Dtor, int Priority, - bool IsDtorAttrFunc) { - if (CodeGenOpts.RegisterGlobalDtorsWithAtExit && - (!getContext().getTargetInfo().getTriple().isOSAIX() || IsDtorAttrFunc)) { +void CodeGenModule::AddGlobalDtor(llvm::Function *Dtor, int Priority) { + if (CodeGenOpts.RegisterGlobalDtorsWithAtExit) { DtorsUsingAtExit[Priority].push_back(Dtor); return; } @@ -1509,11 +1231,10 @@ llvm::ConstantInt *CodeGenModule::CreateCrossDsoCfiTypeId(llvm::Metadata *MD) { void CodeGenModule::SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, - llvm::Function *F, bool IsThunk) { + llvm::Function *F) { unsigned CallingConv; llvm::AttributeList PAL; - ConstructAttributeList(F->getName(), Info, GD, PAL, CallingConv, - /*AttrOnCallSite=*/false, IsThunk); + ConstructAttributeList(F->getName(), Info, GD, PAL, CallingConv, false); F->setAttributes(PAL); F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv)); } @@ -1546,18 +1267,10 @@ static void removeImageAccessQualifier(std::string& TyName) { // (basically all single AS CPUs). static unsigned ArgInfoAddressSpace(LangAS AS) { switch (AS) { - case LangAS::opencl_global: - return 1; - case LangAS::opencl_constant: - return 2; - case LangAS::opencl_local: - return 3; - case LangAS::opencl_generic: - return 4; // Not in SPIR 2.0 specs. - case LangAS::opencl_global_device: - return 5; - case LangAS::opencl_global_host: - return 6; + case LangAS::opencl_global: return 1; + case LangAS::opencl_constant: return 2; + case LangAS::opencl_local: return 3; + case LangAS::opencl_generic: return 4; // Not in SPIR 2.0 specs. default: return 0; // Assume private. } @@ -1598,39 +1311,6 @@ 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(); @@ -1640,10 +1320,26 @@ void CodeGenModule::GenOpenCLArgMetadata(llvm::Function *Fn, ArgInfoAddressSpace(pointeeTy.getAddressSpace())))); // Get argument type name. - std::string typeName = getTypeSpelling(pointeeTy) + "*"; - std::string baseTypeName = - getTypeSpelling(pointeeTy.getCanonicalType()) + "*"; + 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 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); + argBaseTypeNames.push_back( llvm::MDString::get(VMContext, baseTypeName)); @@ -1665,9 +1361,30 @@ void CodeGenModule::GenOpenCLArgMetadata(llvm::Function *Fn, llvm::ConstantAsMetadata::get(CGF->Builder.getInt32(AddrSpc))); // Get argument type name. - ty = isPipe ? ty->castAs<PipeType>()->getElementType() : ty; - std::string typeName = getTypeSpelling(ty); - std::string baseTypeName = getTypeSpelling(ty.getCanonicalType()); + std::string typeName; + if (isPipe) + typeName = ty.getCanonicalType() + ->getAs<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() + ->getAs<PipeType>() + ->getElementType() + .getCanonicalType() + .getAsString(Policy); + else + baseTypeName = + ty.getUnqualifiedType().getCanonicalType().getAsString(Policy); // Remove access qualifiers on images // (as they are inseparable from type in clang implementation, @@ -1679,13 +1396,38 @@ 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", @@ -1758,9 +1500,6 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, if (CodeGenOpts.UnwindTables) B.addAttribute(llvm::Attribute::UWTable); - if (CodeGenOpts.StackClashProtector) - B.addAttribute("probe-stack", "inline-asm"); - if (!hasUnwindExceptions(LangOpts)) B.addAttribute(llvm::Attribute::NoUnwind); @@ -1862,8 +1601,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, B.addAttribute(llvm::Attribute::OptimizeForSize); B.addAttribute(llvm::Attribute::Cold); } - if (D->hasAttr<HotAttr>()) - B.addAttribute(llvm::Attribute::Hot); + if (D->hasAttr<MinSizeAttr>()) B.addAttribute(llvm::Attribute::MinSize); } @@ -1913,15 +1651,6 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, } } -void CodeGenModule::setLLVMFunctionFEnvAttributes(const FunctionDecl *D, - llvm::Function *F) { - if (D->hasAttr<StrictFPAttr>()) { - llvm::AttrBuilder FuncAttrs; - FuncAttrs.addAttribute("strictfp"); - F->addAttributes(llvm::AttributeList::FunctionIndex, FuncAttrs); - } -} - void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) { const Decl *D = GD.getDecl(); if (dyn_cast_or_null<NamedDecl>(D)) @@ -1930,13 +1659,13 @@ void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) { GV->setVisibility(llvm::GlobalValue::DefaultVisibility); if (D && D->hasAttr<UsedAttr>()) - addUsedOrCompilerUsedGlobal(GV); + addUsedGlobal(GV); if (CodeGenOpts.KeepStaticConsts && D && isa<VarDecl>(D)) { const auto *VD = cast<VarDecl>(D); if (VD->getType().isConstQualified() && VD->getStorageDuration() == SD_Static) - addUsedOrCompilerUsedGlobal(GV); + addUsedGlobal(GV); } } @@ -1946,7 +1675,6 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, // we have a decl for the function and it has a target attribute then // parse that and add it to the feature set. StringRef TargetCPU = getTarget().getTargetOpts().CPU; - StringRef TuneCPU = getTarget().getTargetOpts().TuneCPU; std::vector<std::string> Features; const auto *FD = dyn_cast_or_null<FunctionDecl>(GD.getDecl()); FD = FD ? FD->getMostRecentDecl() : FD; @@ -1967,14 +1695,9 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, // the function. if (TD) { ParsedTargetAttr ParsedAttr = TD->parse(); - if (!ParsedAttr.Architecture.empty() && - getTarget().isValidCPUName(ParsedAttr.Architecture)) { + if (ParsedAttr.Architecture != "" && + getTarget().isValidCPUName(ParsedAttr.Architecture)) TargetCPU = ParsedAttr.Architecture; - TuneCPU = ""; // Clear the tune CPU. - } - if (!ParsedAttr.Tune.empty() && - getTarget().isValidCPUName(ParsedAttr.Tune)) - TuneCPU = ParsedAttr.Tune; } } else { // Otherwise just add the existing target cpu and target features to the @@ -1982,14 +1705,10 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, Features = getTarget().getTargetOpts().Features; } - if (!TargetCPU.empty()) { + if (TargetCPU != "") { Attrs.addAttribute("target-cpu", TargetCPU); AddedAttr = true; } - if (!TuneCPU.empty()) { - Attrs.addAttribute("tune-cpu", TuneCPU); - AddedAttr = true; - } if (!Features.empty()) { llvm::sort(Features); Attrs.addAttribute("target-features", llvm::join(Features, ",")); @@ -2006,8 +1725,6 @@ 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>()) @@ -2019,8 +1736,6 @@ 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()); @@ -2030,11 +1745,8 @@ void CodeGenModule::setNonAliasAttributes(GlobalDecl GD, // We know that GetCPUAndFeaturesAttributes will always have the // newest set, since it has the newest possible FunctionDecl, so the // new ones should replace the old. - llvm::AttrBuilder RemoveAttrs; - RemoveAttrs.addAttribute("target-cpu"); - RemoveAttrs.addAttribute("target-features"); - RemoveAttrs.addAttribute("tune-cpu"); - F->removeAttributes(llvm::AttributeList::FunctionIndex, RemoveAttrs); + F->removeFnAttr("target-cpu"); + F->removeFnAttr("target-features"); F->addAttributes(llvm::AttributeList::FunctionIndex, Attrs); } } @@ -2052,7 +1764,7 @@ void CodeGenModule::SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI) { const Decl *D = GD.getDecl(); - SetLLVMFunctionAttributes(GD, FI, F, /*IsThunk=*/false); + SetLLVMFunctionAttributes(GD, FI, F); SetLLVMFunctionAttributesForDefinition(D, F); F->setLinkage(llvm::Function::InternalLinkage); @@ -2106,8 +1818,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, const auto *FD = cast<FunctionDecl>(GD.getDecl()); if (!IsIncompleteFunction) - SetLLVMFunctionAttributes(GD, getTypes().arrangeGlobalDeclaration(GD), F, - IsThunk); + SetLLVMFunctionAttributes(GD, getTypes().arrangeGlobalDeclaration(GD), F); // Add the Returned attribute for "this", except for iOS 5 and earlier // where substantial code, including the libstdc++ dylib, was compiled with @@ -2136,16 +1847,9 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, else if (const auto *SA = FD->getAttr<SectionAttr>()) F->setSection(SA->getName()); - // If we plan on emitting this inline builtin, we can't treat it as a builtin. if (FD->isInlineBuiltinDeclaration()) { - const FunctionDecl *FDBody; - bool HasBody = FD->hasBody(FDBody); - (void)HasBody; - assert(HasBody && "Inline builtin declarations should always have an " - "available body!"); - if (shouldEmitFunction(FDBody)) - F->addAttribute(llvm::AttributeList::FunctionIndex, - llvm::Attribute::NoBuiltin); + F->addAttribute(llvm::AttributeList::FunctionIndex, + llvm::Attribute::NoBuiltin); } if (FD->isReplaceableGlobalAllocationFunction()) { @@ -2153,6 +1857,15 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, // default, only if it is invoked by a new-expression or delete-expression. F->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoBuiltin); + + // A sane operator new returns a non-aliasing pointer. + // FIXME: Also add NonNull attribute to the return value + // for the non-nothrow forms? + auto Kind = FD->getDeclName().getCXXOverloadedOperator(); + if (getCodeGenOpts().AssumeSaneOperatorNew && + (Kind == OO_New || Kind == OO_Array_New)) + F->addAttribute(llvm::AttributeList::ReturnIndex, + llvm::Attribute::NoAlias); } if (isa<CXXConstructorDecl>(FD) || isa<CXXDestructorDecl>(FD)) @@ -2191,7 +1904,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, } void CodeGenModule::addUsedGlobal(llvm::GlobalValue *GV) { - assert((isa<llvm::Function>(GV) || !GV->isDeclaration()) && + assert(!GV->isDeclaration() && "Only globals with definition can force usage."); LLVMUsed.emplace_back(GV); } @@ -2202,15 +1915,6 @@ 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. @@ -2406,13 +2110,6 @@ void CodeGenModule::EmitDeferred() { assert(DeferredVTables.empty()); } - // Emit CUDA/HIP static device variables referenced by host code only. - // 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. if (DeferredDeclsToEmit.empty()) return; @@ -2528,47 +2225,13 @@ llvm::Constant *CodeGenModule::EmitAnnotationLineNo(SourceLocation L) { return llvm::ConstantInt::get(Int32Ty, LineNo); } -llvm::Constant *CodeGenModule::EmitAnnotationArgs(const AnnotateAttr *Attr) { - ArrayRef<Expr *> Exprs = {Attr->args_begin(), Attr->args_size()}; - if (Exprs.empty()) - return llvm::ConstantPointerNull::get(Int8PtrTy); - - llvm::FoldingSetNodeID ID; - for (Expr *E : Exprs) { - ID.Add(cast<clang::ConstantExpr>(E)->getAPValueResult()); - } - llvm::Constant *&Lookup = AnnotationArgs[ID.ComputeHash()]; - if (Lookup) - return Lookup; - - llvm::SmallVector<llvm::Constant *, 4> LLVMArgs; - LLVMArgs.reserve(Exprs.size()); - ConstantEmitter ConstEmiter(*this); - llvm::transform(Exprs, std::back_inserter(LLVMArgs), [&](const Expr *E) { - const auto *CE = cast<clang::ConstantExpr>(E); - return ConstEmiter.emitAbstract(CE->getBeginLoc(), CE->getAPValueResult(), - CE->getType()); - }); - auto *Struct = llvm::ConstantStruct::getAnon(LLVMArgs); - auto *GV = new llvm::GlobalVariable(getModule(), Struct->getType(), true, - llvm::GlobalValue::PrivateLinkage, Struct, - ".args"); - GV->setSection(AnnotationSection); - GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); - auto *Bitcasted = llvm::ConstantExpr::getBitCast(GV, Int8PtrTy); - - Lookup = Bitcasted; - return Bitcasted; -} - llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV, const AnnotateAttr *AA, SourceLocation L) { // Get the globals for file name, annotation, and the line number. llvm::Constant *AnnoGV = EmitAnnotationString(AA->getAnnotation()), *UnitGV = EmitAnnotationUnit(L), - *LineNoCst = EmitAnnotationLineNo(L), - *Args = EmitAnnotationArgs(AA); + *LineNoCst = EmitAnnotationLineNo(L); llvm::Constant *ASZeroGV = GV; if (GV->getAddressSpace() != 0) { @@ -2577,12 +2240,11 @@ llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV, } // Create the ConstantStruct for the global annotation. - llvm::Constant *Fields[] = { - llvm::ConstantExpr::getBitCast(ASZeroGV, Int8PtrTy), - llvm::ConstantExpr::getBitCast(AnnoGV, Int8PtrTy), - llvm::ConstantExpr::getBitCast(UnitGV, Int8PtrTy), - LineNoCst, - Args, + llvm::Constant *Fields[4] = { + llvm::ConstantExpr::getBitCast(ASZeroGV, Int8PtrTy), + llvm::ConstantExpr::getBitCast(AnnoGV, Int8PtrTy), + llvm::ConstantExpr::getBitCast(UnitGV, Int8PtrTy), + LineNoCst }; return llvm::ConstantStruct::getAnon(Fields); } @@ -2595,28 +2257,29 @@ void CodeGenModule::AddGlobalAnnotations(const ValueDecl *D, Annotations.push_back(EmitAnnotateAttr(GV, I, D->getLocation())); } -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())) +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())) return true; - // NoSanitize by location. + // Blacklist by location. if (Loc.isValid()) - return NoSanitizeL.containsLocation(Kind, Loc); + return SanitizerBL.isBlacklistedLocation(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 NoSanitizeL.containsFile(Kind, MainFile->getName()); + return SanitizerBL.isBlacklistedFile(Kind, MainFile->getName()); } return false; } -bool CodeGenModule::isInNoSanitizeList(llvm::GlobalVariable *GV, - SourceLocation Loc, QualType Ty, - StringRef Category) const { - // For now globals can be ignored only in ASan and KASan. +bool CodeGenModule::isInSanitizerBlacklist(llvm::GlobalVariable *GV, + SourceLocation Loc, QualType Ty, + StringRef Category) const { + // For now globals can be blacklisted only in ASan and KASan. const SanitizerMask EnabledAsanMask = LangOpts.Sanitize.Mask & (SanitizerKind::Address | SanitizerKind::KernelAddress | @@ -2624,22 +2287,22 @@ bool CodeGenModule::isInNoSanitizeList(llvm::GlobalVariable *GV, SanitizerKind::MemTag); if (!EnabledAsanMask) return false; - const auto &NoSanitizeL = getContext().getNoSanitizeList(); - if (NoSanitizeL.containsGlobal(EnabledAsanMask, GV->getName(), Category)) + const auto &SanitizerBL = getContext().getSanitizerBlacklist(); + if (SanitizerBL.isBlacklistedGlobal(EnabledAsanMask, GV->getName(), Category)) return true; - if (NoSanitizeL.containsLocation(EnabledAsanMask, Loc, Category)) + if (SanitizerBL.isBlacklistedLocation(EnabledAsanMask, Loc, Category)) return true; // Check global type. if (!Ty.isNull()) { // Drill down the array types: if global variable of a fixed type is - // not sanitized, we also don't instrument arrays of them. + // blacklisted, we also don't instrument arrays of them. while (auto AT = dyn_cast<ArrayType>(Ty.getTypePtr())) Ty = AT->getElementType(); Ty = Ty.getCanonicalType().getUnqualifiedType(); - // Only record types (classes, structs etc.) are ignored. + // We allow to blacklist only record types (classes, structs etc.) if (Ty->isRecordType()) { std::string TypeStr = Ty.getAsString(getContext().getPrintingPolicy()); - if (NoSanitizeL.containsType(EnabledAsanMask, TypeStr, Category)) + if (SanitizerBL.isBlacklistedType(EnabledAsanMask, TypeStr, Category)) return true; } } @@ -2672,34 +2335,6 @@ bool CodeGenModule::imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc, return true; } -bool CodeGenModule::isProfileInstrExcluded(llvm::Function *Fn, - SourceLocation Loc) const { - const auto &ProfileList = getContext().getProfileList(); - // If the profile list is empty, then instrument everything. - if (ProfileList.isEmpty()) - return false; - CodeGenOptions::ProfileInstrKind Kind = getCodeGenOpts().getProfileInstr(); - // First, check the function name. - Optional<bool> V = ProfileList.isFunctionExcluded(Fn->getName(), Kind); - if (V.hasValue()) - return *V; - // Next, check the source location. - if (Loc.isValid()) { - Optional<bool> V = ProfileList.isLocationExcluded(Loc, Kind); - if (V.hasValue()) - return *V; - } - // 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())) { - Optional<bool> V = ProfileList.isFileExcluded(MainFile->getName(), Kind); - if (V.hasValue()) - return *V; - } - return ProfileList.getDefault(); -} - bool CodeGenModule::MustBeEmitted(const ValueDecl *Global) { // Never defer when EmitAllDecls is specified. if (LangOpts.EmitAllDecls) @@ -2716,24 +2351,19 @@ 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) == @@ -2752,8 +2382,13 @@ bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) { return true; } -ConstantAddress CodeGenModule::GetAddrOfMSGuidDecl(const MSGuidDecl *GD) { - StringRef Name = getMangledName(GD); +ConstantAddress CodeGenModule::GetAddrOfUuidDescriptor( + const CXXUuidofExpr* E) { + // Sema has verified that IIDSource has a __declspec(uuid()), and that its + // well-formed. + StringRef Uuid = E->getUuidStr(); + std::string Name = "_GUID_" + Uuid.lower(); + std::replace(Name.begin(), Name.end(), '-', '_'); // The UUID descriptor should be pointer aligned. CharUnits Alignment = CharUnits::fromQuantity(PointerAlignInBytes); @@ -2762,30 +2397,8 @@ ConstantAddress CodeGenModule::GetAddrOfMSGuidDecl(const MSGuidDecl *GD) { if (llvm::GlobalVariable *GV = getModule().getNamedGlobal(Name)) return ConstantAddress(GV, Alignment); - ConstantEmitter Emitter(*this); - llvm::Constant *Init; - - APValue &V = GD->getAsAPValue(); - if (!V.isAbsent()) { - // If possible, emit the APValue version of the initializer. In particular, - // this gets the type of the constant right. - Init = Emitter.emitForInitializer( - GD->getAsAPValue(), GD->getType().getAddressSpace(), GD->getType()); - } else { - // As a fallback, directly construct the constant. - // FIXME: This may get padding wrong under esoteric struct layout rules. - // MSVC appears to create a complete type 'struct __s_GUID' that it - // presumably uses to represent these constants. - MSGuidDecl::Parts Parts = GD->getParts(); - llvm::Constant *Fields[4] = { - llvm::ConstantInt::get(Int32Ty, Parts.Part1), - llvm::ConstantInt::get(Int16Ty, Parts.Part2), - llvm::ConstantInt::get(Int16Ty, Parts.Part3), - llvm::ConstantDataArray::getRaw( - StringRef(reinterpret_cast<char *>(Parts.Part4And5), 8), 8, - Int8Ty)}; - Init = llvm::ConstantStruct::getAnon(Fields); - } + llvm::Constant *Init = EmitUuidofInitializer(Uuid); + assert(Init && "failed to initialize as constant"); auto *GV = new llvm::GlobalVariable( getModule(), Init->getType(), @@ -2793,42 +2406,6 @@ ConstantAddress CodeGenModule::GetAddrOfMSGuidDecl(const MSGuidDecl *GD) { if (supportsCOMDAT()) GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); setDSOLocal(GV); - - llvm::Constant *Addr = GV; - if (!V.isAbsent()) { - Emitter.finalize(GV); - } else { - llvm::Type *Ty = getTypes().ConvertTypeForMem(GD->getType()); - Addr = llvm::ConstantExpr::getBitCast( - GV, Ty->getPointerTo(GV->getAddressSpace())); - } - return ConstantAddress(Addr, Alignment); -} - -ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject( - const TemplateParamObjectDecl *TPO) { - StringRef Name = getMangledName(TPO); - CharUnits Alignment = getNaturalTypeAlignment(TPO->getType()); - - if (llvm::GlobalVariable *GV = getModule().getNamedGlobal(Name)) - return ConstantAddress(GV, Alignment); - - ConstantEmitter Emitter(*this); - llvm::Constant *Init = Emitter.emitForInitializer( - TPO->getValue(), TPO->getType().getAddressSpace(), TPO->getType()); - - if (!Init) { - ErrorUnsupported(TPO, "template parameter object"); - return ConstantAddress::invalid(); - } - - auto *GV = new llvm::GlobalVariable( - getModule(), Init->getType(), - /*isConstant=*/true, llvm::GlobalValue::LinkOnceODRLinkage, Init, Name); - if (supportsCOMDAT()) - GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); - Emitter.finalize(GV); - return ConstantAddress(GV, Alignment); } @@ -2853,7 +2430,9 @@ ConstantAddress CodeGenModule::GetWeakRefReference(const ValueDecl *VD) { GlobalDecl(cast<FunctionDecl>(VD)), /*ForVTable=*/false); else - Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), DeclTy, 0, nullptr); + Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), + llvm::PointerType::getUnqual(DeclTy), + nullptr); auto *F = cast<llvm::GlobalValue>(Aliasee); F->setLinkage(llvm::Function::ExternalWeakLinkage); @@ -2889,8 +2468,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { !Global->hasAttr<CUDAGlobalAttr>() && !Global->hasAttr<CUDAConstantAttr>() && !Global->hasAttr<CUDASharedAttr>() && - !Global->getType()->isCUDADeviceBuiltinSurfaceType() && - !Global->getType()->isCUDADeviceBuiltinTextureType()) + !(LangOpts.HIP && Global->hasAttr<HIPPinnedShadowAttr>())) return; } else { // We need to emit host-side 'shadows' for all global @@ -2983,6 +2561,11 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { return; } + // Check if this must be emitted as declare variant. + if (LangOpts.OpenMP && isa<FunctionDecl>(Global) && OpenMPRuntime && + OpenMPRuntime->emitDeclareVariant(GD, /*IsForDefinition=*/false)) + return; + // If we're deferring emission of a C++ variable with an // initializer, remember the order in which it appeared in the file. if (getLangOpts().CPlusPlus && isa<VarDecl>(Global) && @@ -3143,7 +2726,7 @@ bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) { if (CodeGenOpts.OptimizationLevel == 0 && !F->hasAttr<AlwaysInlineAttr>()) return false; - if (F->hasAttr<DLLImportAttr>() && !F->hasAttr<AlwaysInlineAttr>()) { + if (F->hasAttr<DLLImportAttr>()) { // Check whether it would be safe to inline this dllimport function. DLLImportFunctionVisitor Visitor; Visitor.TraverseFunctionDecl(const_cast<FunctionDecl*>(F)); @@ -3165,8 +2748,8 @@ bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) { // PR9614. Avoid cases where the source code is lying to us. An available // externally function should have an equivalent function somewhere else, - // but a function that calls itself through asm label/`__builtin_` trickery is - // clearly not equivalent to the real implementation. + // but a function that calls itself is clearly not equivalent to the real + // implementation. // This happens in glibc's btowc and in some configure checks. return !isTriviallyRecursive(F); } @@ -3188,6 +2771,50 @@ void CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD, EmitGlobalFunctionDefinition(GD, GV); } +void CodeGenModule::emitOpenMPDeviceFunctionRedefinition( + GlobalDecl OldGD, GlobalDecl NewGD, llvm::GlobalValue *GV) { + assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && + OpenMPRuntime && "Expected OpenMP device mode."); + const auto *D = cast<FunctionDecl>(OldGD.getDecl()); + + // Compute the function info and LLVM type. + const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(OldGD); + llvm::FunctionType *Ty = getTypes().GetFunctionType(FI); + + // Get or create the prototype for the function. + if (!GV || (GV->getType()->getElementType() != Ty)) { + GV = cast<llvm::GlobalValue>(GetOrCreateLLVMFunction( + getMangledName(OldGD), Ty, GlobalDecl(), /*ForVTable=*/false, + /*DontDefer=*/true, /*IsThunk=*/false, llvm::AttributeList(), + ForDefinition)); + SetFunctionAttributes(OldGD, cast<llvm::Function>(GV), + /*IsIncompleteFunction=*/false, + /*IsThunk=*/false); + } + // We need to set linkage and visibility on the function before + // generating code for it because various parts of IR generation + // want to propagate this information down (e.g. to local static + // declarations). + auto *Fn = cast<llvm::Function>(GV); + setFunctionLinkage(OldGD, Fn); + + // FIXME: this is redundant with part of + // setFunctionDefinitionAttributes + setGVProperties(Fn, OldGD); + + MaybeHandleStaticInExternC(D, Fn); + + maybeSetTrivialComdat(*D, *Fn); + + CodeGenFunction(*this).GenerateCode(NewGD, Fn, FI); + + setNonAliasAttributes(OldGD, Fn); + SetLLVMFunctionAttributesForDefinition(D, Fn); + + if (D->hasAttr<AnnotateAttr>()) + AddGlobalAnnotations(D, Fn); +} + void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { const auto *D = cast<ValueDecl>(GD.getDecl()); @@ -3253,9 +2880,7 @@ TargetMVPriority(const TargetInfo &TI, } void CodeGenModule::emitMultiVersionFunctions() { - std::vector<GlobalDecl> MVFuncsToEmit; - MultiVersionFuncs.swap(MVFuncsToEmit); - for (GlobalDecl GD : MVFuncsToEmit) { + for (GlobalDecl GD : MultiVersionFuncs) { SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options; const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); getContext().forEachMultiversionedFunctionVersion( @@ -3309,17 +2934,6 @@ 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) { @@ -3394,7 +3008,7 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { ++Index; } - llvm::stable_sort( + llvm::sort( Options, [](const CodeGenFunction::MultiVersionResolverOption &LHS, const CodeGenFunction::MultiVersionResolverOption &RHS) { return CodeGenFunction::GetX86CpuSupportsMask(LHS.Conditions.Features) > @@ -3515,9 +3129,14 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( EmitGlobal(GDDef); } } + // Check if this must be emitted as declare variant and emit reference to + // the the declare variant function. + if (LangOpts.OpenMP && OpenMPRuntime) + (void)OpenMPRuntime->emitDeclareVariant(GD, /*IsForDefinition=*/true); if (FD->isMultiVersion()) { - if (FD->hasAttr<TargetAttr>()) + const auto *TA = FD->getAttr<TargetAttr>(); + if (TA && TA->isDefaultVersion()) UpdateMultiVersionNames(GD, FD); if (!IsForDefinition) return GetOrCreateMultiVersionResolver(GD, Ty, FD); @@ -3557,7 +3176,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( } if ((isa<llvm::Function>(Entry) || isa<llvm::GlobalAlias>(Entry)) && - (Entry->getValueType() == Ty)) { + (Entry->getType()->getElementType() == Ty)) { return Entry; } @@ -3606,7 +3225,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( } llvm::Constant *BC = llvm::ConstantExpr::getBitCast( - F, Entry->getValueType()->getPointerTo()); + F, Entry->getType()->getElementType()->getPointerTo()); addGlobalValReplacement(Entry, BC); } @@ -3665,7 +3284,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( // Make sure the result is of the requested type. if (!IsIncompleteFunction) { - assert(F->getFunctionType() == Ty); + assert(F->getType()->getElementType() == Ty); return F; } @@ -3681,8 +3300,6 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD, bool ForVTable, bool DontDefer, ForDefinition_t IsForDefinition) { - assert(!cast<FunctionDecl>(GD.getDecl())->isConsteval() && - "consteval function should never be emitted"); // If there was no specific requested type, just convert it now. if (!Ty) { const auto *FD = cast<FunctionDecl>(GD.getDecl()); @@ -3700,19 +3317,9 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD, } StringRef MangledName = getMangledName(GD); - 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; + return GetOrCreateLLVMFunction(MangledName, Ty, GD, ForVTable, DontDefer, + /*IsThunk=*/false, llvm::AttributeList(), + IsForDefinition); } static const FunctionDecl * @@ -3721,8 +3328,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) @@ -3736,15 +3343,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)) { - const 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)) { + 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; } @@ -3815,9 +3422,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 and address -/// space. 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. 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. @@ -3826,8 +3433,9 @@ 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::Type *Ty, - unsigned AddrSpace, const VarDecl *D, +CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, + llvm::PointerType *Ty, + const VarDecl *D, ForDefinition_t IsForDefinition) { // Lookup the entry, lazily creating it if necessary. llvm::GlobalValue *Entry = GetGlobalValue(MangledName); @@ -3844,7 +3452,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, if (LangOpts.OpenMP && !LangOpts.OpenMPSimd && D) getOpenMPRuntime().registerTargetGlobalVariable(D, Entry); - if (Entry->getValueType() == Ty && Entry->getAddressSpace() == AddrSpace) + if (Entry->getType() == Ty) return Entry; // If there are two attempts to define the same mangled name, issue an @@ -3868,24 +3476,22 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, } // Make sure the result is of the correct type. - if (Entry->getType()->getAddressSpace() != AddrSpace) { - return llvm::ConstantExpr::getAddrSpaceCast(Entry, - Ty->getPointerTo(AddrSpace)); - } + if (Entry->getType()->getAddressSpace() != Ty->getAddressSpace()) + return llvm::ConstantExpr::getAddrSpaceCast(Entry, Ty); // (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->getPointerTo(AddrSpace)); + return llvm::ConstantExpr::getBitCast(Entry, Ty); } - auto DAddrSpace = GetGlobalVarAddressSpace(D); - auto TargetAddrSpace = getContext().getTargetAddressSpace(DAddrSpace); + auto AddrSpace = GetGlobalVarAddressSpace(D); + auto TargetAddrSpace = getContext().getTargetAddressSpace(AddrSpace); auto *GV = new llvm::GlobalVariable( - getModule(), Ty, false, llvm::GlobalValue::ExternalLinkage, nullptr, - MangledName, nullptr, llvm::GlobalVariable::NotThreadLocal, - TargetAddrSpace); + getModule(), Ty->getElementType(), 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. @@ -3969,7 +3575,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, llvm::Constant *Init = emitter.tryEmitForInitializer(*InitDecl); if (Init) { auto *InitType = Init->getType(); - if (GV->getValueType() != InitType) { + if (GV->getType()->getElementType() != InitType) { // The type of the initializer does not match the definition. // This happens when an initializer has a different type from // the type of the global (because of padding at the end of a @@ -3996,51 +3602,42 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, } } - 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) == AddrSpace); - if (DAddrSpace != ExpectedAS) { - return getTargetCodeGenInfo().performAddrSpaceCast( - *this, GV, DAddrSpace, ExpectedAS, Ty->getPointerTo(AddrSpace)); - } + assert(getContext().getTargetAddressSpace(ExpectedAS) == + Ty->getPointerAddressSpace()); + if (AddrSpace != ExpectedAS) + return getTargetCodeGenInfo().performAddrSpaceCast(*this, GV, AddrSpace, + ExpectedAS, Ty); return GV; } llvm::Constant * -CodeGenModule::GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition) { +CodeGenModule::GetAddrOfGlobal(GlobalDecl GD, + ForDefinition_t IsForDefinition) { const Decl *D = GD.getDecl(); - if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D)) return getAddrOfCXXStructor(GD, /*FnInfo=*/nullptr, /*FnType=*/nullptr, /*DontDefer=*/false, IsForDefinition); - - if (isa<CXXMethodDecl>(D)) { - auto FInfo = - &getTypes().arrangeCXXMethodDeclaration(cast<CXXMethodDecl>(D)); + else if (isa<CXXMethodDecl>(D)) { + auto FInfo = &getTypes().arrangeCXXMethodDeclaration( + cast<CXXMethodDecl>(D)); auto Ty = getTypes().GetFunctionType(*FInfo); return GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer=*/false, IsForDefinition); - } - - if (isa<FunctionDecl>(D)) { + } else if (isa<FunctionDecl>(D)) { const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD); llvm::FunctionType *Ty = getTypes().GetFunctionType(FI); return GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer=*/false, IsForDefinition); - } - - return GetAddrOfGlobalVar(cast<VarDecl>(D), /*Ty=*/nullptr, IsForDefinition); + } else + return GetAddrOfGlobalVar(cast<VarDecl>(D), /*Ty=*/nullptr, + IsForDefinition); } llvm::GlobalVariable *CodeGenModule::CreateOrReplaceCXXRuntimeVariable( @@ -4051,7 +3648,7 @@ llvm::GlobalVariable *CodeGenModule::CreateOrReplaceCXXRuntimeVariable( if (GV) { // Check if the variable has the right type. - if (GV->getValueType() == Ty) + if (GV->getType()->getElementType() == Ty) return GV; // Because C++ name mangling, the only way we can end up with an already @@ -4100,10 +3697,11 @@ 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, Ty, - getContext().getTargetAddressSpace(ASTTy), D, - IsForDefinition); + return GetOrCreateLLVMGlobal(MangledName, PTy, D, IsForDefinition); } /// CreateRuntimeVariable - Create a new runtime global variable with the @@ -4111,11 +3709,12 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, llvm::Constant * CodeGenModule::CreateRuntimeVariable(llvm::Type *Ty, StringRef Name) { - auto AddrSpace = + auto PtrTy = getContext().getLangOpts().OpenCL - ? getContext().getTargetAddressSpace(LangAS::opencl_global) - : 0; - auto *Ret = GetOrCreateLLVMGlobal(Name, Ty, AddrSpace, nullptr); + ? llvm::PointerType::get( + Ty, getContext().getTargetAddressSpace(LangAS::opencl_global)) + : llvm::PointerType::getUnqual(Ty); + auto *Ret = GetOrCreateLLVMGlobal(Name, PtrTy, nullptr); setDSOLocal(cast<llvm::GlobalValue>(Ret->stripPointerCasts())); return Ret; } @@ -4157,18 +3756,12 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) { if (LangOpts.OpenCL) { AddrSpace = D ? D->getType().getAddressSpace() : LangAS::opencl_global; assert(AddrSpace == LangAS::opencl_global || - AddrSpace == LangAS::opencl_global_device || - AddrSpace == LangAS::opencl_global_host || AddrSpace == LangAS::opencl_constant || AddrSpace == LangAS::opencl_local || AddrSpace >= LangAS::FirstTargetAddressSpace); 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; @@ -4190,12 +3783,10 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) { return getTargetCodeGenInfo().getGlobalVarAddressSpace(*this, D); } -LangAS CodeGenModule::GetGlobalConstantAddressSpace() const { +LangAS CodeGenModule::getStringLiteralAddressSpace() 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; @@ -4214,12 +3805,13 @@ castStringLiteralToDefaultAddressSpace(CodeGenModule &CGM, llvm::GlobalVariable *GV) { llvm::Constant *Cast = GV; if (!CGM.getLangOpts().OpenCL) { - 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))); + 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))); + } } return Cast; } @@ -4309,7 +3901,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, OpenMPRuntime->emitTargetGlobalVariable(D)) return; - llvm::TrackingVH<llvm::Constant> Init; + llvm::Constant *Init = nullptr; bool NeedsGlobalCtor = false; bool NeedsGlobalDtor = D->needsDestruction(getContext()) == QualType::DK_cxx_destructor; @@ -4326,20 +3918,17 @@ 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>() && + !getLangOpts().CUDAIsDevice && (D->hasAttr<CUDAConstantAttr>() || D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDASharedAttr>()); - bool IsCUDADeviceShadowVar = - getLangOpts().CUDAIsDevice && !D->hasAttr<HIPManagedAttr>() && - (D->getType()->isCUDADeviceBuiltinSurfaceType() || - D->getType()->isCUDADeviceBuiltinTextureType()); + // HIP pinned shadow of initialized host-side global variables are also + // left undefined. + bool IsHIPPinnedShadowVar = + getLangOpts().CUDAIsDevice && D->hasAttr<HIPPinnedShadowAttr>(); if (getLangOpts().CUDA && - (IsCUDASharedVar || IsCUDAShadowVar || IsCUDADeviceShadowVar)) - Init = llvm::UndefValue::get(getTypes().ConvertTypeForMem(ASTTy)); - else if (D->hasAttr<LoaderUninitializedAttr>()) - Init = llvm::UndefValue::get(getTypes().ConvertTypeForMem(ASTTy)); + (IsCUDASharedVar || IsCUDAShadowVar || IsHIPPinnedShadowVar)) + Init = llvm::UndefValue::get(getTypes().ConvertType(ASTTy)); else if (!InitExpr) { // This is a tentative definition; tentative definitions are // implicitly initialized with { 0 }. @@ -4355,8 +3944,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, } else { initializedGlobalDecl = GlobalDecl(D); emitter.emplace(*this); - llvm::Constant *Initializer = emitter->tryEmitForInitializer(*InitDecl); - if (!Initializer) { + Init = emitter->tryEmitForInitializer(*InitDecl); + + if (!Init) { QualType T = InitExpr->getType(); if (D->getType()->isReferenceType()) T = D->getType(); @@ -4369,7 +3959,6 @@ 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. @@ -4397,7 +3986,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, // "extern int x[];") and then a definition of a different type (e.g. // "int x[10];"). This also happens when an initializer has a different type // from the type of the global (this happens with unions). - if (!GV || GV->getValueType() != InitType || + if (!GV || GV->getType()->getElementType() != InitType || GV->getType()->getAddressSpace() != getContext().getTargetAddressSpace(GetGlobalVarAddressSpace(D))) { @@ -4411,8 +4000,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, // Replace all uses of the old global with the new global llvm::Constant *NewPtrForOldDecl = - llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, - Entry->getType()); + llvm::ConstantExpr::getBitCast(GV, Entry->getType()); Entry->replaceAllUsesWith(NewPtrForOldDecl); // Erase the old global, since it is no longer used. @@ -4441,14 +4029,38 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, (D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDAConstantAttr>())) GV->setExternallyInitialized(true); } else { - getCUDARuntime().internalizeDeviceSideVar(D, Linkage); + // 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>() || + D->hasAttr<HIPPinnedShadowAttr>()) { + Linkage = llvm::GlobalValue::InternalLinkage; + + // Shadow variables and their properties must be registered + // with CUDA runtime. + unsigned Flags = 0; + if (!D->hasDefinition()) + Flags |= CGCUDARuntime::ExternDeviceVar; + if (D->hasAttr<CUDAConstantAttr>()) + Flags |= CGCUDARuntime::ConstantDeviceVar; + // Extern global variables will be registered in the TU where they are + // defined. + if (!D->hasExternalStorage()) + getCUDARuntime().registerDeviceVar(D, *GV, Flags); + } 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; } - getCUDARuntime().handleVarRegistration(D, *GV); } - GV->setInitializer(Init); - if (emitter) - emitter->finalize(GV); + if (!IsHIPPinnedShadowVar) + GV->setInitializer(Init); + if (emitter) emitter->finalize(GV); // If it is safe to mark the global 'constant', do so now. GV->setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor && @@ -4463,24 +4075,17 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, GV->setAlignment(getContext().getDeclAlign(D).getAsAlign()); - // On Darwin, unlike other Itanium C++ ABI platforms, the thread-wrapper - // function is only defined alongside the variable, not also alongside - // callers. Normally, all accesses to a thread_local go through the - // thread-wrapper in order to ensure initialization has occurred, underlying - // variable will never be used other than the thread-wrapper, so it can be - // converted to internal linkage. - // - // However, if the variable has the 'constinit' attribute, it _can_ be - // referenced directly, without calling the thread-wrapper, so the linkage - // must not be changed. - // - // Additionally, if the variable isn't plain external linkage, e.g. if it's - // weak or linkonce, the de-duplication semantics are important to preserve, - // so we don't change the linkage. - if (D->getTLSKind() == VarDecl::TLS_Dynamic && - Linkage == llvm::GlobalValue::ExternalLinkage && + // On Darwin, if the normal linkage of a C++ thread_local variable is + // LinkOnce or Weak, we keep the normal linkage to prevent multiple + // copies within a linkage unit; otherwise, the backing variable has + // internal linkage and all accesses should just be calls to the + // Itanium-specified entry point, which has the normal linkage of the + // variable. This is to preserve the ability to change the implementation + // behind the scenes. + if (!D->isStaticLocal() && D->getTLSKind() == VarDecl::TLS_Dynamic && Context.getTargetInfo().getTriple().isOSDarwin() && - !D->hasAttr<ConstInitAttr>()) + !llvm::GlobalVariable::isLinkOnceLinkage(Linkage) && + !llvm::GlobalVariable::isWeakLinkage(Linkage)) Linkage = llvm::GlobalValue::InternalLinkage; GV->setLinkage(Linkage); @@ -4529,8 +4134,9 @@ void CodeGenModule::EmitExternalVarDeclaration(const VarDecl *D) { if (getCodeGenOpts().hasReducedDebugInfo()) { QualType ASTTy = D->getType(); llvm::Type *Ty = getTypes().ConvertTypeForMem(D->getType()); - llvm::Constant *GV = GetOrCreateLLVMGlobal( - D->getName(), Ty, getContext().getTargetAddressSpace(ASTTy), D); + llvm::PointerType *PTy = + llvm::PointerType::get(Ty, getContext().getTargetAddressSpace(ASTTy)); + llvm::Constant *GV = GetOrCreateLLVMGlobal(D->getName(), PTy, D); DI->EmitExternalVariable( cast<llvm::GlobalVariable>(GV->stripPointerCasts()), D); } @@ -4653,16 +4259,13 @@ llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator( // and must all be equivalent. However, we are not allowed to // throw away these explicit instantiations. // - // CUDA/HIP: For -fno-gpu-rdc case, device code is limited to one TU, + // We don't currently support CUDA device code spread out across multiple TUs, // so say that CUDA templates are either external (for kernels) or internal. - // This lets llvm perform aggressive inter-procedural optimizations. For - // -fgpu-rdc case, device function calls across multiple TU's are allowed, - // therefore we need to follow the normal linkage paradigm. + // This lets llvm perform aggressive inter-procedural optimizations. if (Linkage == GVA_StrongODR) { - if (getLangOpts().AppleKext) + if (Context.getLangOpts().AppleKext) return llvm::Function::ExternalLinkage; - if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice && - !getLangOpts().GPURelocatableDeviceCode) + if (Context.getLangOpts().CUDA && Context.getLangOpts().CUDAIsDevice) return D->hasAttr<CUDAGlobalAttr>() ? llvm::Function::ExternalLinkage : llvm::Function::InternalLinkage; return llvm::Function::WeakODRLinkage; @@ -4702,6 +4305,7 @@ 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; ) { @@ -4758,7 +4362,6 @@ 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; @@ -4825,6 +4428,11 @@ void CodeGenModule::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { + // Check if this must be emitted as declare variant. + if (LangOpts.OpenMP && OpenMPRuntime && + OpenMPRuntime->emitDeclareVariant(GD, /*IsForDefinition=*/true)) + return; + const auto *D = cast<FunctionDecl>(GD.getDecl()); // Compute the function info and LLVM type. @@ -4832,7 +4440,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::FunctionType *Ty = getTypes().GetFunctionType(FI); // Get or create the prototype for the function. - if (!GV || (GV->getValueType() != Ty)) + if (!GV || (GV->getType()->getElementType() != Ty)) GV = cast<llvm::GlobalValue>(GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer=*/true, ForDefinition)); @@ -4853,12 +4461,10 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, MaybeHandleStaticInExternC(D, Fn); - maybeSetTrivialComdat(*D, *Fn); - // Set CodeGen attributes that represent floating point environment. - setLLVMFunctionFEnvAttributes(D, Fn); + maybeSetTrivialComdat(*D, *Fn); - CodeGenFunction(*this).GenerateCode(GD, Fn, FI); + CodeGenFunction(*this).GenerateCode(D, Fn, FI); setNonAliasAttributes(GD, Fn); SetLLVMFunctionAttributesForDefinition(D, Fn); @@ -4866,7 +4472,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>()) AddGlobalCtor(Fn, CA->getPriority()); if (const DestructorAttr *DA = D->getAttr<DestructorAttr>()) - AddGlobalDtor(Fn, DA->getPriority(), true); + AddGlobalDtor(Fn, DA->getPriority()); if (D->hasAttr<AnnotateAttr>()) AddGlobalAnnotations(D, Fn); } @@ -4902,18 +4508,16 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { /*ForVTable=*/false); LT = getFunctionLinkage(GD); } else { - Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), DeclTy, 0, + Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), + llvm::PointerType::getUnqual(DeclTy), /*D=*/nullptr); - if (const auto *VD = dyn_cast<VarDecl>(GD.getDecl())) - LT = getLLVMLinkageVarDefinition(VD, D->getType().isConstQualified()); - else - LT = getFunctionLinkage(GD); + LT = getLLVMLinkageVarDefinition(cast<VarDecl>(GD.getDecl()), + D->getType().isConstQualified()); } // Create the new alias itself, but don't set a name yet. - unsigned AS = Aliasee->getType()->getPointerAddressSpace(); auto *GA = - llvm::GlobalAlias::create(DeclTy, AS, LT, "", Aliasee, &getModule()); + llvm::GlobalAlias::create(DeclTy, 0, LT, "", Aliasee, &getModule()); if (Entry) { if (GA->getAliasee() == Entry) { @@ -5118,7 +4722,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; @@ -5230,8 +4834,6 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { switch (Triple.getObjectFormat()) { case llvm::Triple::UnknownObjectFormat: llvm_unreachable("unknown file format"); - case llvm::Triple::GOFF: - llvm_unreachable("GOFF is not yet implemented"); case llvm::Triple::XCOFF: llvm_unreachable("XCOFF is not yet implemented"); case llvm::Triple::COFF: @@ -5330,7 +4932,7 @@ GenerateStringLiteral(llvm::Constant *C, llvm::GlobalValue::LinkageTypes LT, CodeGenModule &CGM, StringRef GlobalName, CharUnits Alignment) { unsigned AddrSpace = CGM.getContext().getTargetAddressSpace( - CGM.GetGlobalConstantAddressSpace()); + CGM.getStringLiteralAddressSpace()); llvm::Module &M = CGM.getModule(); // Create a global variable for this string @@ -5457,21 +5059,8 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary( CharUnits Align = getContext().getTypeAlignInChars(MaterializedType); - 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); - } + if (llvm::Constant *Slot = MaterializedGlobalTemporaryMap[E]) + return ConstantAddress(Slot, Align); // FIXME: If an externally-visible declaration extends multiple temporaries, // we need to give each temporary the same name in every translation unit (and @@ -5550,17 +5139,7 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary( *this, GV, AddrSpace, LangAS::Default, Type->getPointerTo( getContext().getTargetAddressSpace(LangAS::Default))); - - // 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; - + MaterializedGlobalTemporaryMap[E] = CV; return ConstantAddress(CV, Align); } @@ -5686,11 +5265,6 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { if (D->isTemplated()) return; - // Consteval function shouldn't be emitted. - if (auto *FD = dyn_cast<FunctionDecl>(D)) - if (FD->isConsteval()) - return; - switch (D->getKind()) { case Decl::CXXConversion: case Decl::CXXMethod: @@ -5726,27 +5300,22 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { break; case Decl::ClassTemplateSpecialization: { const auto *Spec = cast<ClassTemplateSpecializationDecl>(D); - if (CGDebugInfo *DI = getModuleDebugInfo()) - if (Spec->getSpecializationKind() == - TSK_ExplicitInstantiationDefinition && - Spec->hasDefinition()) - DI->completeTemplateDefinition(*Spec); + if (DebugInfo && + Spec->getSpecializationKind() == TSK_ExplicitInstantiationDefinition && + Spec->hasDefinition()) + DebugInfo->completeTemplateDefinition(*Spec); } LLVM_FALLTHROUGH; - case Decl::CXXRecord: { - CXXRecordDecl *CRD = cast<CXXRecordDecl>(D); - if (CGDebugInfo *DI = getModuleDebugInfo()) { - if (CRD->hasDefinition()) - DI->EmitAndRetainType(getContext().getRecordType(cast<RecordDecl>(D))); + case Decl::CXXRecord: + if (DebugInfo) { if (auto *ES = D->getASTContext().getExternalSource()) if (ES->hasExternalDefinitions(D) == ExternalASTSource::EK_Never) - DI->completeUnusedClass(*CRD); + DebugInfo->completeUnusedClass(cast<CXXRecordDecl>(*D)); } // Emit any static data members, they may be definitions. - for (auto *I : CRD->decls()) + for (auto *I : cast<CXXRecordDecl>(D)->decls()) if (isa<VarDecl>(I) || isa<CXXRecordDecl>(I)) EmitTopLevelDecl(I); break; - } // No code generation needed. case Decl::UsingShadow: case Decl::ClassTemplate: @@ -5762,19 +5331,15 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::Using: // using X; [C++] 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; + return; case Decl::NamespaceAlias: if (CGDebugInfo *DI = getModuleDebugInfo()) DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(*D)); - break; + return; case Decl::UsingDirective: // using namespace X; [C++] if (CGDebugInfo *DI = getModuleDebugInfo()) DI->EmitUsingDirective(cast<UsingDirectiveDecl>(*D)); - break; + return; case Decl::CXXConstructor: getCXXABI().EmitCXXConstructors(cast<CXXConstructorDecl>(D)); break; @@ -5865,9 +5430,6 @@ 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; @@ -5925,7 +5487,6 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { break; case Decl::OMPAllocate: - EmitOMPAllocateDecl(cast<OMPAllocateDecl>(D)); break; case Decl::OMPDeclareReduction: @@ -5940,25 +5501,6 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { EmitOMPRequiresDecl(cast<OMPRequiresDecl>(D)); break; - case Decl::Typedef: - case Decl::TypeAlias: // using foo = bar; [C++11] - if (CGDebugInfo *DI = getModuleDebugInfo()) - DI->EmitAndRetainType( - getContext().getTypedefType(cast<TypedefNameDecl>(D))); - break; - - case Decl::Record: - if (CGDebugInfo *DI = getModuleDebugInfo()) - if (cast<RecordDecl>(D)->getDefinition()) - DI->EmitAndRetainType(getContext().getRecordType(cast<RecordDecl>(D))); - break; - - case Decl::Enum: - if (CGDebugInfo *DI = getModuleDebugInfo()) - if (cast<EnumDecl>(D)->getDefinition()) - DI->EmitAndRetainType(getContext().getEnumType(cast<EnumDecl>(D))); - break; - default: // Make sure we handled everything we should, every other kind is a // non-top-level decl. FIXME: Would be nice to have an isTopLevelDeclKind @@ -5980,10 +5522,10 @@ void CodeGenModule::AddDeferredUnusedCoverageMapping(Decl *D) { case Decl::CXXConstructor: case Decl::CXXDestructor: { if (!cast<FunctionDecl>(D)->doesThisDeclarationHaveABody()) - break; + return; SourceManager &SM = getContext().getSourceManager(); if (LimitedCoverage && SM.getMainFileID() != SM.getFileID(D->getBeginLoc())) - break; + return; auto I = DeferredEmptyCoverageMappingDecls.find(D); if (I == DeferredEmptyCoverageMappingDecls.end()) DeferredEmptyCoverageMappingDecls[D] = true; @@ -6049,17 +5591,6 @@ void CodeGenModule::EmitDeferredUnusedCoverageMappings() { } } -void CodeGenModule::EmitMainVoidAlias() { - // In order to transition away from "__original_main" gracefully, emit an - // alias for "main" in the no-argument case so that libc can detect when - // new-style no-argument main is in used. - if (llvm::Function *F = getModule().getFunction("main")) { - if (!F->isDeclaration() && F->arg_size() == 0 && !F->isVarArg() && - F->getReturnType()->isIntegerTy(Context.getTargetInfo().getIntWidth())) - addUsedGlobal(llvm::GlobalAlias::create("__main_void", F)); - } -} - /// Turns the given pointer into a constant. static llvm::Constant *GetPointerConstant(llvm::LLVMContext &Context, const void *Ptr) { @@ -6095,7 +5626,7 @@ void CodeGenModule::EmitStaticExternCAliases() { IdentifierInfo *Name = I.first; llvm::GlobalValue *Val = I.second; if (Val && !getModule().getNamedValue(Name->getName())) - addCompilerUsedGlobal(llvm::GlobalAlias::create(Name->getName(), Val)); + addUsedGlobal(llvm::GlobalAlias::create(Name->getName(), Val)); } } @@ -6174,6 +5705,21 @@ void CodeGenModule::EmitCommandLineMetadata() { CommandLineMetadata->addOperand(llvm::MDNode::get(Ctx, CommandLineNode)); } +void CodeGenModule::EmitTargetMetadata() { + // Warning, new MangledDeclNames may be appended within this loop. + // We rely on MapVector insertions adding new elements to the end + // of the container. + // FIXME: Move this loop into the one target that needs it, and only + // loop over those declarations for which we couldn't emit the target + // metadata when we emitted the declaration. + for (unsigned I = 0; I != MangledDeclNames.size(); ++I) { + auto Val = *(MangledDeclNames.begin() + I); + const Decl *D = Val.first.getDecl()->getMostRecentDecl(); + llvm::GlobalValue *GV = GetGlobalValue(Val.second); + getTargetCodeGenInfo().emitTargetMD(D, GV, *this); + } +} + void CodeGenModule::EmitCoverageFile() { if (getCodeGenOpts().CoverageDataFile.empty() && getCodeGenOpts().CoverageNotesFile.empty()) @@ -6196,14 +5742,39 @@ void CodeGenModule::EmitCoverageFile() { } } +llvm::Constant *CodeGenModule::EmitUuidofInitializer(StringRef Uuid) { + // Sema has checked that all uuid strings are of the form + // "12345678-1234-1234-1234-1234567890ab". + assert(Uuid.size() == 36); + for (unsigned i = 0; i < 36; ++i) { + if (i == 8 || i == 13 || i == 18 || i == 23) assert(Uuid[i] == '-'); + else assert(isHexDigit(Uuid[i])); + } + + // The starts of all bytes of Field3 in Uuid. Field 3 is "1234-1234567890ab". + const unsigned Field3ValueOffsets[8] = { 19, 21, 24, 26, 28, 30, 32, 34 }; + + llvm::Constant *Field3[8]; + for (unsigned Idx = 0; Idx < 8; ++Idx) + Field3[Idx] = llvm::ConstantInt::get( + Int8Ty, Uuid.substr(Field3ValueOffsets[Idx], 2), 16); + + llvm::Constant *Fields[4] = { + llvm::ConstantInt::get(Int32Ty, Uuid.substr(0, 8), 16), + llvm::ConstantInt::get(Int16Ty, Uuid.substr(9, 4), 16), + llvm::ConstantInt::get(Int16Ty, Uuid.substr(14, 4), 16), + llvm::ConstantArray::get(llvm::ArrayType::get(Int8Ty, 8), Field3) + }; + + return llvm::ConstantStruct::getAnon(Fields); +} + llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH) { // Return a bogus pointer if RTTI is disabled, unless it's for EH. // FIXME: should we even be calling this method if RTTI is disabled // and it's not for EH? - if ((!ForEH && !getLangOpts().RTTI) || getLangOpts().CUDAIsDevice || - (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && - getTriple().isNVPTX())) + if ((!ForEH && !getLangOpts().RTTI) || getLangOpts().CUDAIsDevice) return llvm::Constant::getNullValue(Int8PtrTy); if (ForEH && Ty->isObjCObjectPointerType() && @@ -6337,116 +5908,13 @@ 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); - auto *Call = CGF.EmitRuntimeCall( - CreateRuntimeFunction(FTy, "__translate_sampler_initializer"), {C}); - return Call; -} - -CharUnits CodeGenModule::getNaturalPointeeTypeAlignment( - QualType T, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo) { - return getNaturalTypeAlignment(T->getPointeeType(), BaseInfo, TBAAInfo, - /* forPointeeType= */ true); -} - -CharUnits CodeGenModule::getNaturalTypeAlignment(QualType T, - LValueBaseInfo *BaseInfo, - TBAAAccessInfo *TBAAInfo, - bool forPointeeType) { - if (TBAAInfo) - *TBAAInfo = getTBAAAccessInfo(T); - - // FIXME: This duplicates logic in ASTContext::getTypeAlignIfKnown. But - // that doesn't return the information we need to compute BaseInfo. - - // Honor alignment typedef attributes even on incomplete types. - // We also honor them straight for C++ class types, even as pointees; - // there's an expressivity gap here. - if (auto TT = T->getAs<TypedefType>()) { - if (auto Align = TT->getDecl()->getMaxAlignment()) { - if (BaseInfo) - *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType); - return getContext().toCharUnitsFromBits(Align); - } - } - - bool AlignForArray = T->isArrayType(); - - // Analyze the base element type, so we don't get confused by incomplete - // array types. - T = getContext().getBaseElementType(T); - - if (T->isIncompleteType()) { - // We could try to replicate the logic from - // ASTContext::getTypeAlignIfKnown, but nothing uses the alignment if the - // type is incomplete, so it's impossible to test. We could try to reuse - // getTypeAlignIfKnown, but that doesn't return the information we need - // to set BaseInfo. So just ignore the possibility that the alignment is - // greater than one. - if (BaseInfo) - *BaseInfo = LValueBaseInfo(AlignmentSource::Type); - return CharUnits::One(); - } - - if (BaseInfo) - *BaseInfo = LValueBaseInfo(AlignmentSource::Type); - - CharUnits Alignment; - const CXXRecordDecl *RD; - if (T.getQualifiers().hasUnaligned()) { - Alignment = CharUnits::One(); - } else if (forPointeeType && !AlignForArray && - (RD = T->getAsCXXRecordDecl())) { - // For C++ class pointees, we don't know whether we're pointing at a - // base or a complete object, so we generally need to use the - // non-virtual alignment. - Alignment = getClassPointerAlignment(RD); - } else { - Alignment = getContext().getTypeAlignInChars(T); - } - - // Cap to the global maximum type alignment unless the alignment - // was somehow explicit on the type. - if (unsigned MaxAlign = getLangOpts().MaxTypeAlign) { - if (Alignment.getQuantity() > MaxAlign && - !getContext().isAlignmentRequired(T)) - Alignment = CharUnits::fromQuantity(MaxAlign); - } - return Alignment; -} - -bool CodeGenModule::stopAutoInit() { - unsigned StopAfter = getContext().getLangOpts().TrivialAutoVarInitStopAfter; - if (StopAfter) { - // This number is positive only when -ftrivial-auto-var-init-stop-after=* is - // used - if (NumAutoVarInit >= StopAfter) { - return true; - } - if (!NumAutoVarInit) { - unsigned DiagID = getDiags().getCustomDiagID( - DiagnosticsEngine::Warning, - "-ftrivial-auto-var-init-stop-after=%0 has been enabled to limit the " - "number of times ftrivial-auto-var-init=%1 gets applied."); - getDiags().Report(DiagID) - << StopAfter - << (getContext().getLangOpts().getTrivialAutoVarInit() == - LangOptions::TrivialAutoVarInitKind::Zero - ? "zero" - : "pattern"); - } - ++NumAutoVarInit; - } - return false; -} - -void CodeGenModule::printPostfixForExternalizedStaticVar( - llvm::raw_ostream &OS) const { - OS << ".static." << getContext().getCUIDHash(); + 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}); } |