diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-09-02 21:17:18 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-08 17:34:50 +0000 |
commit | 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch) | |
tree | 62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp | |
parent | cf037972ea8863e2bab7461d77345367d2c1e054 (diff) | |
parent | 7fa27ce4a07f19b07799a767fc29416f3b625afb (diff) |
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp | 538 |
1 files changed, 397 insertions, 141 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp index 12d602fed693..07a9dec12f6f 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp @@ -50,9 +50,9 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/ADT/Triple.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Frontend/OpenMP/OMPIRBuilder.h" +#include "llvm/IR/AttributeMask.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Intrinsics.h" @@ -67,8 +67,9 @@ #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TimeProfiler.h" -#include "llvm/Support/X86TargetParser.h" #include "llvm/Support/xxhash.h" +#include "llvm/TargetParser/Triple.h" +#include "llvm/TargetParser/X86TargetParser.h" #include <optional> using namespace clang; @@ -100,6 +101,228 @@ static CGCXXABI *createCXXABI(CodeGenModule &CGM) { llvm_unreachable("invalid C++ ABI kind"); } +static std::unique_ptr<TargetCodeGenInfo> +createTargetCodeGenInfo(CodeGenModule &CGM) { + const TargetInfo &Target = CGM.getTarget(); + const llvm::Triple &Triple = Target.getTriple(); + const CodeGenOptions &CodeGenOpts = CGM.getCodeGenOpts(); + + switch (Triple.getArch()) { + default: + return createDefaultTargetCodeGenInfo(CGM); + + case llvm::Triple::le32: + return createPNaClTargetCodeGenInfo(CGM); + case llvm::Triple::m68k: + return createM68kTargetCodeGenInfo(CGM); + case llvm::Triple::mips: + case llvm::Triple::mipsel: + if (Triple.getOS() == llvm::Triple::NaCl) + return createPNaClTargetCodeGenInfo(CGM); + return createMIPSTargetCodeGenInfo(CGM, /*IsOS32=*/true); + + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + return createMIPSTargetCodeGenInfo(CGM, /*IsOS32=*/false); + + case llvm::Triple::avr: { + // For passing parameters, R8~R25 are used on avr, and R18~R25 are used + // on avrtiny. For passing return value, R18~R25 are used on avr, and + // R22~R25 are used on avrtiny. + unsigned NPR = Target.getABI() == "avrtiny" ? 6 : 18; + unsigned NRR = Target.getABI() == "avrtiny" ? 4 : 8; + return createAVRTargetCodeGenInfo(CGM, NPR, NRR); + } + + case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: + case llvm::Triple::aarch64_be: { + AArch64ABIKind Kind = AArch64ABIKind::AAPCS; + if (Target.getABI() == "darwinpcs") + Kind = AArch64ABIKind::DarwinPCS; + else if (Triple.isOSWindows()) + return createWindowsAArch64TargetCodeGenInfo(CGM, AArch64ABIKind::Win64); + + return createAArch64TargetCodeGenInfo(CGM, Kind); + } + + case llvm::Triple::wasm32: + case llvm::Triple::wasm64: { + WebAssemblyABIKind Kind = WebAssemblyABIKind::MVP; + if (Target.getABI() == "experimental-mv") + Kind = WebAssemblyABIKind::ExperimentalMV; + return createWebAssemblyTargetCodeGenInfo(CGM, Kind); + } + + case llvm::Triple::arm: + case llvm::Triple::armeb: + case llvm::Triple::thumb: + case llvm::Triple::thumbeb: { + if (Triple.getOS() == llvm::Triple::Win32) + return createWindowsARMTargetCodeGenInfo(CGM, ARMABIKind::AAPCS_VFP); + + ARMABIKind Kind = ARMABIKind::AAPCS; + StringRef ABIStr = Target.getABI(); + if (ABIStr == "apcs-gnu") + Kind = ARMABIKind::APCS; + else if (ABIStr == "aapcs16") + Kind = ARMABIKind::AAPCS16_VFP; + else if (CodeGenOpts.FloatABI == "hard" || + (CodeGenOpts.FloatABI != "soft" && + (Triple.getEnvironment() == llvm::Triple::GNUEABIHF || + Triple.getEnvironment() == llvm::Triple::MuslEABIHF || + Triple.getEnvironment() == llvm::Triple::EABIHF))) + Kind = ARMABIKind::AAPCS_VFP; + + return createARMTargetCodeGenInfo(CGM, Kind); + } + + case llvm::Triple::ppc: { + if (Triple.isOSAIX()) + return createAIXTargetCodeGenInfo(CGM, /*Is64Bit=*/false); + + bool IsSoftFloat = + CodeGenOpts.FloatABI == "soft" || Target.hasFeature("spe"); + return createPPC32TargetCodeGenInfo(CGM, IsSoftFloat); + } + case llvm::Triple::ppcle: { + bool IsSoftFloat = CodeGenOpts.FloatABI == "soft"; + return createPPC32TargetCodeGenInfo(CGM, IsSoftFloat); + } + case llvm::Triple::ppc64: + if (Triple.isOSAIX()) + return createAIXTargetCodeGenInfo(CGM, /*Is64Bit=*/true); + + if (Triple.isOSBinFormatELF()) { + PPC64_SVR4_ABIKind Kind = PPC64_SVR4_ABIKind::ELFv1; + if (Target.getABI() == "elfv2") + Kind = PPC64_SVR4_ABIKind::ELFv2; + bool IsSoftFloat = CodeGenOpts.FloatABI == "soft"; + + return createPPC64_SVR4_TargetCodeGenInfo(CGM, Kind, IsSoftFloat); + } + return createPPC64TargetCodeGenInfo(CGM); + case llvm::Triple::ppc64le: { + assert(Triple.isOSBinFormatELF() && "PPC64 LE non-ELF not supported!"); + PPC64_SVR4_ABIKind Kind = PPC64_SVR4_ABIKind::ELFv2; + if (Target.getABI() == "elfv1") + Kind = PPC64_SVR4_ABIKind::ELFv1; + bool IsSoftFloat = CodeGenOpts.FloatABI == "soft"; + + return createPPC64_SVR4_TargetCodeGenInfo(CGM, Kind, IsSoftFloat); + } + + case llvm::Triple::nvptx: + case llvm::Triple::nvptx64: + return createNVPTXTargetCodeGenInfo(CGM); + + case llvm::Triple::msp430: + return createMSP430TargetCodeGenInfo(CGM); + + case llvm::Triple::riscv32: + case llvm::Triple::riscv64: { + StringRef ABIStr = Target.getABI(); + unsigned XLen = Target.getPointerWidth(LangAS::Default); + unsigned ABIFLen = 0; + if (ABIStr.endswith("f")) + ABIFLen = 32; + else if (ABIStr.endswith("d")) + ABIFLen = 64; + return createRISCVTargetCodeGenInfo(CGM, XLen, ABIFLen); + } + + case llvm::Triple::systemz: { + bool SoftFloat = CodeGenOpts.FloatABI == "soft"; + bool HasVector = !SoftFloat && Target.getABI() == "vector"; + return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); + } + + case llvm::Triple::tce: + case llvm::Triple::tcele: + return createTCETargetCodeGenInfo(CGM); + + case llvm::Triple::x86: { + bool IsDarwinVectorABI = Triple.isOSDarwin(); + bool IsWin32FloatStructABI = Triple.isOSWindows() && !Triple.isOSCygMing(); + + if (Triple.getOS() == llvm::Triple::Win32) { + return createWinX86_32TargetCodeGenInfo( + CGM, IsDarwinVectorABI, IsWin32FloatStructABI, + CodeGenOpts.NumRegisterParameters); + } + return createX86_32TargetCodeGenInfo( + CGM, IsDarwinVectorABI, IsWin32FloatStructABI, + CodeGenOpts.NumRegisterParameters, CodeGenOpts.FloatABI == "soft"); + } + + case llvm::Triple::x86_64: { + StringRef ABI = Target.getABI(); + X86AVXABILevel AVXLevel = (ABI == "avx512" ? X86AVXABILevel::AVX512 + : ABI == "avx" ? X86AVXABILevel::AVX + : X86AVXABILevel::None); + + switch (Triple.getOS()) { + case llvm::Triple::Win32: + return createWinX86_64TargetCodeGenInfo(CGM, AVXLevel); + default: + return createX86_64TargetCodeGenInfo(CGM, AVXLevel); + } + } + case llvm::Triple::hexagon: + return createHexagonTargetCodeGenInfo(CGM); + case llvm::Triple::lanai: + return createLanaiTargetCodeGenInfo(CGM); + case llvm::Triple::r600: + return createAMDGPUTargetCodeGenInfo(CGM); + case llvm::Triple::amdgcn: + return createAMDGPUTargetCodeGenInfo(CGM); + case llvm::Triple::sparc: + return createSparcV8TargetCodeGenInfo(CGM); + case llvm::Triple::sparcv9: + return createSparcV9TargetCodeGenInfo(CGM); + case llvm::Triple::xcore: + return createXCoreTargetCodeGenInfo(CGM); + case llvm::Triple::arc: + return createARCTargetCodeGenInfo(CGM); + case llvm::Triple::spir: + case llvm::Triple::spir64: + return createCommonSPIRTargetCodeGenInfo(CGM); + case llvm::Triple::spirv32: + case llvm::Triple::spirv64: + return createSPIRVTargetCodeGenInfo(CGM); + case llvm::Triple::ve: + return createVETargetCodeGenInfo(CGM); + case llvm::Triple::csky: { + bool IsSoftFloat = !Target.hasFeature("hard-float-abi"); + bool hasFP64 = + Target.hasFeature("fpuv2_df") || Target.hasFeature("fpuv3_df"); + return createCSKYTargetCodeGenInfo(CGM, IsSoftFloat ? 0 + : hasFP64 ? 64 + : 32); + } + case llvm::Triple::bpfeb: + case llvm::Triple::bpfel: + return createBPFTargetCodeGenInfo(CGM); + case llvm::Triple::loongarch32: + case llvm::Triple::loongarch64: { + StringRef ABIStr = Target.getABI(); + unsigned ABIFRLen = 0; + if (ABIStr.endswith("f")) + ABIFRLen = 32; + else if (ABIStr.endswith("d")) + ABIFRLen = 64; + return createLoongArchTargetCodeGenInfo( + CGM, Target.getPointerWidth(LangAS::Default), ABIFRLen); + } + } +} + +const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { + if (!TheTargetCodeGenInfo) + TheTargetCodeGenInfo = createTargetCodeGenInfo(*this); + return *TheTargetCodeGenInfo; +} + CodeGenModule::CodeGenModule(ASTContext &C, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, const HeaderSearchOptions &HSO, @@ -107,11 +330,11 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, llvm::Module &M, DiagnosticsEngine &diags, CoverageSourceInfo *CoverageInfo) - : Context(C), LangOpts(C.getLangOpts()), FS(std::move(FS)), - HeaderSearchOpts(HSO), PreprocessorOpts(PPO), CodeGenOpts(CGO), - TheModule(M), Diags(diags), Target(C.getTargetInfo()), - ABI(createCXXABI(*this)), VMContext(M.getContext()), Types(*this), - VTables(*this), SanitizerMD(new SanitizerMetadata(*this)) { + : Context(C), LangOpts(C.getLangOpts()), FS(FS), HeaderSearchOpts(HSO), + PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags), + Target(C.getTargetInfo()), ABI(createCXXABI(*this)), + VMContext(M.getContext()), Types(*this), VTables(*this), + SanitizerMD(new SanitizerMetadata(*this)) { // Initialize the type cache. llvm::LLVMContext &LLVMContext = M.getContext(); @@ -174,8 +397,9 @@ CodeGenModule::CodeGenModule(ASTContext &C, // If debug info or coverage generation is enabled, create the CGDebugInfo // object. - if (CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo || - CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes) + if (CodeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo || + CodeGenOpts.CoverageNotesFile.size() || + CodeGenOpts.CoverageDataFile.size()) DebugInfo.reset(new CGDebugInfo(*this)); Block.GlobalUniqueCount = 0; @@ -185,7 +409,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, if (CodeGenOpts.hasProfileClangUse()) { auto ReaderOrErr = llvm::IndexedInstrProfReader::create( - CodeGenOpts.ProfileInstrumentUsePath, CodeGenOpts.ProfileRemappingFile); + CodeGenOpts.ProfileInstrumentUsePath, *FS, + CodeGenOpts.ProfileRemappingFile); // We're checking for profile read errors in CompilerInvocation, so if // there was an error it should've already been caught. If it hasn't been // somehow, trip an assertion. @@ -245,7 +470,7 @@ void CodeGenModule::createOpenMPRuntime() { case llvm::Triple::nvptx: case llvm::Triple::nvptx64: case llvm::Triple::amdgcn: - assert(getLangOpts().OpenMPIsDevice && + assert(getLangOpts().OpenMPIsTargetDevice && "OpenMP AMDGPU/NVPTX is only prepared to deal with device code."); OpenMPRuntime.reset(new CGOpenMPRuntimeGPU(*this)); break; @@ -272,7 +497,7 @@ void CodeGenModule::addReplacement(StringRef Name, llvm::Constant *C) { void CodeGenModule::applyReplacements() { for (auto &I : Replacements) { - StringRef MangledName = I.first(); + StringRef MangledName = I.first; llvm::Constant *Replacement = I.second; llvm::GlobalValue *Entry = GetGlobalValue(MangledName); if (!Entry) @@ -337,10 +562,11 @@ static const llvm::GlobalValue *getAliasedGlobal(const llvm::GlobalValue *GV) { return FinalGV; } -static bool checkAliasedGlobal(DiagnosticsEngine &Diags, - SourceLocation Location, bool IsIFunc, - const llvm::GlobalValue *Alias, - const llvm::GlobalValue *&GV) { +static bool checkAliasedGlobal( + DiagnosticsEngine &Diags, SourceLocation Location, bool IsIFunc, + const llvm::GlobalValue *Alias, const llvm::GlobalValue *&GV, + const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames, + SourceRange AliasRange) { GV = getAliasedGlobal(Alias); if (!GV) { Diags.Report(Location, diag::err_cyclic_alias) << IsIFunc; @@ -349,6 +575,22 @@ static bool checkAliasedGlobal(DiagnosticsEngine &Diags, if (GV->isDeclaration()) { Diags.Report(Location, diag::err_alias_to_undefined) << IsIFunc << IsIFunc; + Diags.Report(Location, diag::note_alias_requires_mangled_name) + << IsIFunc << IsIFunc; + // Provide a note if the given function is not found and exists as a + // mangled name. + for (const auto &[Decl, Name] : MangledDeclNames) { + if (const auto *ND = dyn_cast<NamedDecl>(Decl.getDecl())) { + if (ND->getName() == GV->getName()) { + Diags.Report(Location, diag::note_alias_mangled_name_alternative) + << Name + << FixItHint::CreateReplacement( + AliasRange, + (Twine(IsIFunc ? "ifunc" : "alias") + "(\"" + Name + "\")") + .str()); + } + } + } return false; } @@ -380,16 +622,19 @@ void CodeGenModule::checkAliases() { for (const GlobalDecl &GD : Aliases) { const auto *D = cast<ValueDecl>(GD.getDecl()); SourceLocation Location; + SourceRange Range; bool IsIFunc = D->hasAttr<IFuncAttr>(); - if (const Attr *A = D->getDefiningAttr()) + if (const Attr *A = D->getDefiningAttr()) { Location = A->getLocation(); - else + Range = A->getRange(); + } else llvm_unreachable("Not an alias or ifunc?"); StringRef MangledName = getMangledName(GD); llvm::GlobalValue *Alias = GetGlobalValue(MangledName); const llvm::GlobalValue *GV = nullptr; - if (!checkAliasedGlobal(Diags, Location, IsIFunc, Alias, GV)) { + if (!checkAliasedGlobal(Diags, Location, IsIFunc, Alias, GV, + MangledDeclNames, Range)) { Error = true; continue; } @@ -508,7 +753,7 @@ static void setVisibilityFromDLLStorageClass(const clang::LangOptions &LO, } void CodeGenModule::Release() { - Module *Primary = getContext().getModuleForCodeGen(); + Module *Primary = getContext().getCurrentNamedModule(); if (CXX20ModuleInits && Primary && !Primary->isHeaderLikeModule()) EmitModuleInitializers(Primary); EmitDeferred(); @@ -527,6 +772,8 @@ void CodeGenModule::Release() { GlobalTopLevelStmtBlockInFlight = {nullptr, nullptr}; } + // Module implementations are initialized the same way as a regular TU that + // imports one or more modules. if (CXX20ModuleInits && Primary && Primary->isInterfaceOrPartition()) EmitCXXModuleInitFunc(Primary); else @@ -579,20 +826,6 @@ void CodeGenModule::Release() { EmitMainVoidAlias(); if (getTriple().isAMDGPU()) { - // Emit reference of __amdgpu_device_library_preserve_asan_functions to - // preserve ASAN functions in bitcode libraries. - if (LangOpts.Sanitize.has(SanitizerKind::Address)) { - 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); - } // Emit amdgpu_code_object_version module flag, which is code object version // times 100. if (getTarget().getTargetOpts().CodeObjectVersion != @@ -601,6 +834,17 @@ void CodeGenModule::Release() { "amdgpu_code_object_version", getTarget().getTargetOpts().CodeObjectVersion); } + + // Currently, "-mprintf-kind" option is only supported for HIP + if (LangOpts.HIP) { + auto *MDStr = llvm::MDString::get( + getLLVMContext(), (getTarget().getTargetOpts().AMDGPUPrintfKindVal == + TargetOptions::AMDGPUPrintfKind::Hostcall) + ? "hostcall" + : "buffered"); + getModule().addModuleFlag(llvm::Module::Error, "amdgpu_printf_kind", + MDStr); + } } // Emit a global array containing all external kernels or device variables @@ -845,7 +1089,7 @@ void CodeGenModule::Release() { // Indicate whether this Module was compiled with -fopenmp if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd) getModule().addModuleFlag(llvm::Module::Max, "openmp", LangOpts.OpenMP); - if (getLangOpts().OpenMPIsDevice) + if (getLangOpts().OpenMPIsTargetDevice) getModule().addModuleFlag(llvm::Module::Max, "openmp-device", LangOpts.OpenMP); @@ -898,6 +1142,12 @@ void CodeGenModule::Release() { if (CodeGenOpts.NoPLT) getModule().setRtLibUseGOT(); + if (getTriple().isOSBinFormatELF() && + CodeGenOpts.DirectAccessExternalData != + getModule().getDirectAccessExternalData()) { + getModule().setDirectAccessExternalData( + CodeGenOpts.DirectAccessExternalData); + } if (CodeGenOpts.UnwindTables) getModule().setUwtable(llvm::UWTableKind(CodeGenOpts.UnwindTables)); @@ -918,7 +1168,8 @@ void CodeGenModule::Release() { if (getCodeGenOpts().EmitDeclMetadata) EmitDeclMetadata(); - if (getCodeGenOpts().EmitGcovArcs || getCodeGenOpts().EmitGcovNotes) + if (getCodeGenOpts().CoverageNotesFile.size() || + getCodeGenOpts().CoverageDataFile.size()) EmitCoverageFile(); if (CGDebugInfo *DI = getModuleDebugInfo()) @@ -946,6 +1197,10 @@ void CodeGenModule::Release() { if (getCodeGenOpts().SkipRaxSetup) getModule().addModuleFlag(llvm::Module::Override, "SkipRaxSetup", 1); + if (getContext().getTargetInfo().getMaxTLSAlign()) + getModule().addModuleFlag(llvm::Module::Error, "MaxTLSAlign", + getContext().getTargetInfo().getMaxTLSAlign()); + getTargetCodeGenInfo().emitTargetMetadata(*this, MangledDeclNames); EmitBackendOptionsMetadata(getCodeGenOpts()); @@ -977,9 +1232,9 @@ void CodeGenModule::EmitOpenCLMetadata() { } void CodeGenModule::EmitBackendOptionsMetadata( - const CodeGenOptions CodeGenOpts) { + const CodeGenOptions &CodeGenOpts) { if (getTriple().isRISCV()) { - getModule().addModuleFlag(llvm::Module::Error, "SmallDataLimit", + getModule().addModuleFlag(llvm::Module::Min, "SmallDataLimit", CodeGenOpts.SmallDataLimit); } } @@ -1347,8 +1602,13 @@ static void AppendTargetVersionMangling(const CodeGenModule &CGM, if (Attr->isDefaultVersion()) return; Out << "._"; + const TargetInfo &TI = CGM.getTarget(); llvm::SmallVector<StringRef, 8> Feats; Attr->getFeatures(Feats); + llvm::stable_sort(Feats, [&TI](const StringRef FeatL, const StringRef FeatR) { + return TI.multiVersionSortPriority(FeatL) < + TI.multiVersionSortPriority(FeatR); + }); for (const auto &Feat : Feats) { Out << 'M'; Out << Feat; @@ -1400,13 +1660,19 @@ static void AppendTargetClonesMangling(const CodeGenModule &CGM, const TargetClonesAttr *Attr, unsigned VersionIndex, raw_ostream &Out) { - if (CGM.getTarget().getTriple().isAArch64()) { + const TargetInfo &TI = CGM.getTarget(); + if (TI.getTriple().isAArch64()) { StringRef FeatureStr = Attr->getFeatureStr(VersionIndex); if (FeatureStr == "default") return; Out << "._"; SmallVector<StringRef, 8> Features; FeatureStr.split(Features, "+"); + llvm::stable_sort(Features, + [&TI](const StringRef FeatL, const StringRef FeatR) { + return TI.multiVersionSortPriority(FeatL) < + TI.multiVersionSortPriority(FeatR); + }); for (auto &Feat : Features) { Out << 'M'; Out << Feat; @@ -1726,7 +1992,11 @@ llvm::ConstantInt *CodeGenModule::CreateKCFITypeId(QualType T) { std::string OutName; llvm::raw_string_ostream Out(OutName); - getCXXABI().getMangleContext().mangleTypeName(T, Out); + getCXXABI().getMangleContext().mangleTypeName( + T, Out, getCodeGenOpts().SanitizeCfiICallNormalizeIntegers); + + if (getCodeGenOpts().SanitizeCfiICallNormalizeIntegers) + Out << ".normalized"; return llvm::ConstantInt::get(Int32Ty, static_cast<uint32_t>(llvm::xxHash64(OutName))); @@ -1981,22 +2251,6 @@ CodeGenModule::getMostBaseClasses(const CXXRecordDecl *RD) { return MostBases.takeVector(); } -llvm::GlobalVariable * -CodeGenModule::GetOrCreateRTTIProxyGlobalVariable(llvm::Constant *Addr) { - auto It = RTTIProxyMap.find(Addr); - if (It != RTTIProxyMap.end()) - return It->second; - - auto *FTRTTIProxy = new llvm::GlobalVariable( - TheModule, Addr->getType(), - /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, Addr, - "__llvm_rtti_proxy"); - FTRTTIProxy->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); - - RTTIProxyMap[Addr] = FTRTTIProxy; - return FTRTTIProxy; -} - void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F) { llvm::AttrBuilder B(F->getContext()); @@ -2132,8 +2386,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, // functions. If the current target's C++ ABI requires this and this is a // member function, set its alignment accordingly. if (getTarget().getCXXABI().areMemberFunctionsAligned()) { - if (F->getAlignment() < 2 && isa<CXXMethodDecl>(D)) - F->setAlignment(llvm::Align(2)); + if (F->getPointerAlignment(getDataLayout()) < 2 && isa<CXXMethodDecl>(D)) + F->setAlignment(std::max(llvm::Align(2), F->getAlign().valueOrOne())); } // In the cross-dso CFI mode with canonical jump tables, we want !type @@ -2162,15 +2416,6 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, } } -void CodeGenModule::setLLVMFunctionFEnvAttributes(const FunctionDecl *D, - llvm::Function *F) { - if (D->hasAttr<StrictFPAttr>()) { - llvm::AttrBuilder FuncAttrs(F->getContext()); - FuncAttrs.addAttribute("strictfp"); - F->addFnAttrs(FuncAttrs); - } -} - void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) { const Decl *D = GD.getDecl(); if (isa_and_nonnull<NamedDecl>(D)) @@ -2181,16 +2426,19 @@ void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) { if (D && D->hasAttr<UsedAttr>()) addUsedOrCompilerUsedGlobal(GV); - if (CodeGenOpts.KeepStaticConsts && D && isa<VarDecl>(D)) { - const auto *VD = cast<VarDecl>(D); - if (VD->getType().isConstQualified() && - VD->getStorageDuration() == SD_Static) - addUsedOrCompilerUsedGlobal(GV); - } + if (const auto *VD = dyn_cast_if_present<VarDecl>(D); + VD && + ((CodeGenOpts.KeepPersistentStorageVariables && + (VD->getStorageDuration() == SD_Static || + VD->getStorageDuration() == SD_Thread)) || + (CodeGenOpts.KeepStaticConsts && VD->getStorageDuration() == SD_Static && + VD->getType().isConstQualified()))) + addUsedOrCompilerUsedGlobal(GV); } bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, - llvm::AttrBuilder &Attrs) { + llvm::AttrBuilder &Attrs, + bool SetTargetFeatures) { // Add target-cpu and target-features attributes to functions. If // we have a decl for the function and it has a target attribute then // parse that and add it to the feature set. @@ -2233,8 +2481,7 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, if (SD) { // Apply the given CPU name as the 'tune-cpu' so that the optimizer can // favor this processor. - TuneCPU = getTarget().getCPUSpecificTuneName( - SD->getCPUName(GD.getMultiVersionIndex())->getName()); + TuneCPU = SD->getCPUName(GD.getMultiVersionIndex())->getName(); } } else { // Otherwise just add the existing target cpu and target features to the @@ -2250,7 +2497,10 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, Attrs.addAttribute("tune-cpu", TuneCPU); AddedAttr = true; } - if (!Features.empty()) { + if (!Features.empty() && SetTargetFeatures) { + llvm::erase_if(Features, [&](const std::string& F) { + return getTarget().isReadOnlyFeature(F.substr(1)); + }); llvm::sort(Features); Attrs.addAttribute("target-features", llvm::join(Features, ",")); AddedAttr = true; @@ -2353,9 +2603,6 @@ void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD, } void CodeGenModule::setKCFIType(const FunctionDecl *FD, llvm::Function *F) { - if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic()) - return; - llvm::LLVMContext &Ctx = F->getContext(); llvm::MDBuilder MDB(Ctx); F->setMetadata(llvm::LLVMContext::MD_kcfi_type, @@ -3067,12 +3314,14 @@ bool CodeGenModule::MustBeEmitted(const ValueDecl *Global) { if (LangOpts.EmitAllDecls) return true; - if (CodeGenOpts.KeepStaticConsts) { - const auto *VD = dyn_cast<VarDecl>(Global); - if (VD && VD->getType().isConstQualified() && - VD->getStorageDuration() == SD_Static) - return true; - } + const auto *VD = dyn_cast<VarDecl>(Global); + if (VD && + ((CodeGenOpts.KeepPersistentStorageVariables && + (VD->getStorageDuration() == SD_Static || + VD->getStorageDuration() == SD_Thread)) || + (CodeGenOpts.KeepStaticConsts && VD->getStorageDuration() == SD_Static && + VD->getType().isConstQualified()))) + return true; return getContext().DeclMustBeEmitted(Global); } @@ -3115,7 +3364,7 @@ bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) { // codegen for global variables, because they may be marked as threadprivate. if (LangOpts.OpenMP && LangOpts.OpenMPUseTLS && getContext().getTargetInfo().isTLSSupported() && isa<VarDecl>(Global) && - !isTypeConstant(Global->getType(), false) && + !isTypeConstant(Global->getType(), false, false) && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(Global)) return false; @@ -3223,9 +3472,13 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject( return ConstantAddress::invalid(); } - auto *GV = new llvm::GlobalVariable( - getModule(), Init->getType(), - /*isConstant=*/true, llvm::GlobalValue::LinkOnceODRLinkage, Init, Name); + llvm::GlobalValue::LinkageTypes Linkage = + isExternallyVisible(TPO->getLinkageAndVisibility().getLinkage()) + ? llvm::GlobalValue::LinkOnceODRLinkage + : llvm::GlobalValue::InternalLinkage; + auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(), + /*isConstant=*/true, Linkage, Init, Name); + setGVProperties(GV, TPO); if (supportsCOMDAT()) GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); Emitter.finalize(GV); @@ -3318,7 +3571,8 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { if (MustBeEmitted(Global)) EmitOMPDeclareReduction(DRD); return; - } else if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Global)) { + } + if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Global)) { if (MustBeEmitted(Global)) EmitOMPDeclareMapper(DMD); return; @@ -4007,7 +4261,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( // the iFunc instead. Name Mangling will handle the rest of the changes. if (const FunctionDecl *FD = cast_or_null<FunctionDecl>(D)) { // For the device mark the function as one that should be emitted. - if (getLangOpts().OpenMPIsDevice && OpenMPRuntime && + if (getLangOpts().OpenMPIsTargetDevice && OpenMPRuntime && !OpenMPRuntime->markAsGlobalTarget(GD) && FD->isDefined() && !DontDefer && !IsForDefinition) { if (const FunctionDecl *FDDef = FD->getDefinition()) { @@ -4184,13 +4438,10 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( /// GetAddrOfFunction - Return the address of the given function. If Ty is /// non-null, then this function will use the specified type if it has to /// create it (this occurs when we see a definition of the function). -llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD, - llvm::Type *Ty, - bool ForVTable, - bool DontDefer, - ForDefinition_t IsForDefinition) { - assert(!cast<FunctionDecl>(GD.getDecl())->isConsteval() && - "consteval function should never be emitted"); +llvm::Constant * +CodeGenModule::GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty, bool ForVTable, + bool DontDefer, + ForDefinition_t IsForDefinition) { // If there was no specific requested type, just convert it now. if (!Ty) { const auto *FD = cast<FunctionDecl>(GD.getDecl()); @@ -4315,8 +4566,9 @@ CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name, /// /// If ExcludeCtor is true, the duration when the object's constructor runs /// will not be considered. The caller will need to verify that the object is -/// not written to during its construction. -bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor) { +/// not written to during its construction. ExcludeDtor works similarly. +bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor, + bool ExcludeDtor) { if (!Ty.isConstant(Context) && !Ty->isReferenceType()) return false; @@ -4324,7 +4576,7 @@ bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor) { if (const CXXRecordDecl *Record = Context.getBaseElementType(Ty)->getAsCXXRecordDecl()) return ExcludeCtor && !Record->hasMutableFields() && - Record->hasTrivialDestructor(); + (Record->hasTrivialDestructor() || ExcludeDtor); } return true; @@ -4437,7 +4689,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, // FIXME: This code is overly simple and should be merged with other global // handling. - GV->setConstant(isTypeConstant(D->getType(), false)); + GV->setConstant(isTypeConstant(D->getType(), false, false)); GV->setAlignment(getContext().getDeclAlign(D).getAsAlign()); @@ -4514,7 +4766,8 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, } } - if (GV->isDeclaration()) { + if (D && + D->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly) { getTargetCodeGenInfo().setTargetAttributes(D, GV, *this); // External HIP managed variables needed to be recorded for transformation // in both device and host compilations. @@ -4687,16 +4940,17 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) { return LangAS::sycl_global; if (LangOpts.CUDA && LangOpts.CUDAIsDevice) { - if (D && D->hasAttr<CUDAConstantAttr>()) - return LangAS::cuda_constant; - else if (D && D->hasAttr<CUDASharedAttr>()) - return LangAS::cuda_shared; - else if (D && D->hasAttr<CUDADeviceAttr>()) - return LangAS::cuda_device; - else if (D && D->getType().isConstQualified()) - return LangAS::cuda_constant; - else - return LangAS::cuda_device; + if (D) { + if (D->hasAttr<CUDAConstantAttr>()) + return LangAS::cuda_constant; + if (D->hasAttr<CUDASharedAttr>()) + return LangAS::cuda_shared; + if (D->hasAttr<CUDADeviceAttr>()) + return LangAS::cuda_device; + if (D->getType().isConstQualified()) + return LangAS::cuda_constant; + } + return LangAS::cuda_device; } if (LangOpts.OpenMP) { @@ -4807,6 +5061,10 @@ static bool shouldBeInCOMDAT(CodeGenModule &CGM, const Decl &D) { llvm_unreachable("No such linkage"); } +bool CodeGenModule::supportsCOMDAT() const { + return getTriple().supportsCOMDAT(); +} + void CodeGenModule::maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO) { if (!shouldBeInCOMDAT(*this, D)) @@ -4825,7 +5083,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, // If this is OpenMP device, check if it is legal to emit this global // normally. - if (LangOpts.OpenMPIsDevice && OpenMPRuntime && + if (LangOpts.OpenMPIsTargetDevice && OpenMPRuntime && OpenMPRuntime->emitTargetGlobalVariable(D)) return; @@ -4973,7 +5231,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, // Is accessible from all the threads within the grid and from the host // through the runtime library (cudaGetSymbolAddress() / cudaGetSymbolSize() // / cudaMemcpyToSymbol() / cudaMemcpyFromSymbol())." - if (GV && LangOpts.CUDA) { + if (LangOpts.CUDA) { if (LangOpts.CUDAIsDevice) { if (Linkage != llvm::GlobalValue::InternalLinkage && (D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDAConstantAttr>() || @@ -4992,7 +5250,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, // If it is safe to mark the global 'constant', do so now. GV->setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor && - isTypeConstant(D->getType(), true)); + isTypeConstant(D->getType(), true, true)); // If it is in a read-only section, mark it 'constant'. if (const SectionAttr *SA = D->getAttr<SectionAttr>()) { @@ -5396,9 +5654,6 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, maybeSetTrivialComdat(*D, *Fn); - // Set CodeGen attributes that represent floating point environment. - setLLVMFunctionFEnvAttributes(D, Fn); - CodeGenFunction(*this).GenerateCode(GD, Fn, FI); setNonAliasAttributes(GD, Fn); @@ -5845,6 +6100,7 @@ CodeGenModule::GetConstantArrayFromStringLiteral(const StringLiteral *E) { // Resize the string to the right size, which is indicated by its type. const ConstantArrayType *CAT = Context.getAsConstantArrayType(E->getType()); + assert(CAT && "String literal not of constant array type!"); Str.resize(CAT->getSize().getZExtValue()); return llvm::ConstantDataArray::getString(VMContext, Str, false); } @@ -6066,7 +6322,8 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary( emitter.emplace(*this); InitialValue = emitter->emitForInitializer(*Value, AddrSpace, MaterializedType); - Constant = isTypeConstant(MaterializedType, /*ExcludeCtor*/Value); + Constant = isTypeConstant(MaterializedType, /*ExcludeCtor*/ Value, + /*ExcludeDtor*/ false); Type = InitialValue->getType(); } else { // No initializer, the initialization will be provided when we @@ -6228,6 +6485,10 @@ void CodeGenModule::EmitLinkageSpec(const LinkageSpecDecl *LSD) { } void CodeGenModule::EmitTopLevelStmt(const TopLevelStmtDecl *D) { + // Device code should not be at top level. + if (LangOpts.CUDA && LangOpts.CUDAIsDevice) + return; + std::unique_ptr<CodeGenFunction> &CurCGF = GlobalTopLevelStmtBlockInFlight.first; @@ -6283,9 +6544,8 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { return; // Consteval function shouldn't be emitted. - if (auto *FD = dyn_cast<FunctionDecl>(D)) - if (FD->isConsteval()) - return; + if (auto *FD = dyn_cast<FunctionDecl>(D); FD && FD->isImmediateFunction()) + return; switch (D->getKind()) { case Decl::CXXConversion: @@ -6459,7 +6719,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { if (LangOpts.CUDA && LangOpts.CUDAIsDevice) break; // File-scope asm is ignored during device-side OpenMP compilation. - if (LangOpts.OpenMPIsDevice) + if (LangOpts.OpenMPIsTargetDevice) break; // File-scope asm is ignored during device-side SYCL compilation. if (LangOpts.SYCLIsDevice) @@ -6511,16 +6771,14 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { EmitTopLevelDecl(D); // Visit the submodules of this module. - for (clang::Module::submodule_iterator Sub = Mod->submodule_begin(), - SubEnd = Mod->submodule_end(); - Sub != SubEnd; ++Sub) { + for (auto *Submodule : Mod->submodules()) { // Skip explicit children; they need to be explicitly imported to emit // the initializers. - if ((*Sub)->IsExplicit) + if (Submodule->IsExplicit) continue; - if (Visited.insert(*Sub).second) - Stack.push_back(*Sub); + if (Visited.insert(Submodule).second) + Stack.push_back(Submodule); } } break; @@ -6869,10 +7127,6 @@ void CodeGenModule::EmitCommandLineMetadata() { } void CodeGenModule::EmitCoverageFile() { - if (getCodeGenOpts().CoverageDataFile.empty() && - getCodeGenOpts().CoverageNotesFile.empty()) - return; - llvm::NamedMDNode *CUNode = TheModule.getNamedMetadata("llvm.dbg.cu"); if (!CUNode) return; @@ -6895,10 +7149,8 @@ llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty, // 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())) - return llvm::Constant::getNullValue(Int8PtrTy); + if (!shouldEmitRTTI(ForEH)) + return llvm::Constant::getNullValue(GlobalsInt8PtrTy); if (ForEH && Ty->isObjCObjectPointerType() && LangOpts.ObjCRuntime.isGNUFamily()) @@ -6942,7 +7194,12 @@ CodeGenModule::CreateMetadataIdentifierImpl(QualType T, MetadataTypeMap &Map, if (isExternallyVisible(T->getLinkage())) { std::string OutName; llvm::raw_string_ostream Out(OutName); - getCXXABI().getMangleContext().mangleTypeName(T, Out); + getCXXABI().getMangleContext().mangleTypeName( + T, Out, getCodeGenOpts().SanitizeCfiICallNormalizeIntegers); + + if (getCodeGenOpts().SanitizeCfiICallNormalizeIntegers) + Out << ".normalized"; + Out << Suffix; InternalId = llvm::MDString::get(getLLVMContext(), Out.str()); @@ -7202,7 +7459,6 @@ void CodeGenModule::moveLazyEmissionStates(CodeGenModule *NewBuilder) { "Newly created module should not have manglings"); NewBuilder->Manglings = std::move(Manglings); - assert(WeakRefReferences.empty() && "Not all WeakRefRefs have been applied"); NewBuilder->WeakRefReferences = std::move(WeakRefReferences); NewBuilder->TBAA = std::move(TBAA); |