diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
commit | 676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch) | |
tree | 02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /lib/CodeGen/CodeGenModule.cpp | |
parent | c7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff) |
Notes
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 648 |
1 files changed, 455 insertions, 193 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 8c5e0df0969b8..244738042cef0 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -36,14 +36,15 @@ #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" #include "clang/CodeGen/ConstantInitBuilder.h" -#include "clang/Frontend/CodeGenOptions.h" -#include "clang/Sema/SemaDiagnostic.h" +#include "clang/Frontend/FrontendDiagnostic.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/CallSite.h" @@ -53,6 +54,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/ProfileData/InstrProfReader.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MD5.h" @@ -124,7 +126,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO, RuntimeCC = getTargetCodeGenInfo().getABIInfo().getRuntimeCC(); - if (LangOpts.ObjC1) + if (LangOpts.ObjC) createObjCRuntime(); if (LangOpts.OpenCL) createOpenCLRuntime(); @@ -147,12 +149,12 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO, Block.GlobalUniqueCount = 0; - if (C.getLangOpts().ObjC1) + if (C.getLangOpts().ObjC) ObjCData.reset(new ObjCEntrypoints()); if (CodeGenOpts.hasProfileClangUse()) { auto ReaderOrErr = llvm::IndexedInstrProfReader::create( - CodeGenOpts.ProfileInstrumentUsePath); + CodeGenOpts.ProfileInstrumentUsePath, CodeGenOpts.ProfileRemappingFile); if (auto E = ReaderOrErr.takeError()) { unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "Could not read profile %0: %1"); @@ -320,8 +322,6 @@ void CodeGenModule::checkAliases() { assert(FTy); if (!FTy->getReturnType()->isPointerTy()) Diags.Report(Location, diag::err_ifunc_resolver_return); - if (FTy->getNumParams()) - Diags.Report(Location, diag::err_ifunc_resolver_params); } llvm::Constant *Aliasee = Alias->getIndirectSymbol(); @@ -458,9 +458,12 @@ void CodeGenModule::Release() { // Indicate that we want CodeView in the metadata. getModule().addModuleFlag(llvm::Module::Warning, "CodeView", 1); } + if (CodeGenOpts.CodeViewGHash) { + getModule().addModuleFlag(llvm::Module::Warning, "CodeViewGHash", 1); + } if (CodeGenOpts.ControlFlowGuard) { // We want function ID tables for Control Flow Guard. - getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 1); + getModule().addModuleFlag(llvm::Module::Warning, "cfguardtable", 1); } if (CodeGenOpts.OptimizationLevel > 0 && CodeGenOpts.StrictVTablePointers) { // We don't support LTO with 2 with different StrictVTablePointers @@ -556,6 +559,20 @@ void CodeGenModule::Release() { getModule().setPIELevel(static_cast<llvm::PIELevel::Level>(PLevel)); } + if (getCodeGenOpts().CodeModel.size() > 0) { + unsigned CM = llvm::StringSwitch<unsigned>(getCodeGenOpts().CodeModel) + .Case("tiny", llvm::CodeModel::Tiny) + .Case("small", llvm::CodeModel::Small) + .Case("kernel", llvm::CodeModel::Kernel) + .Case("medium", llvm::CodeModel::Medium) + .Case("large", llvm::CodeModel::Large) + .Default(~0u); + if (CM != ~0u) { + llvm::CodeModel::Model codeModel = static_cast<llvm::CodeModel::Model>(CM); + getModule().setCodeModel(codeModel); + } + } + if (CodeGenOpts.NoPLT) getModule().setRtLibUseGOT(); @@ -573,6 +590,9 @@ void CodeGenModule::Release() { if (getCodeGenOpts().EmitVersionIdentMetadata) EmitVersionIdentMetadata(); + if (!getCodeGenOpts().RecordCommandLine.empty()) + EmitCommandLineMetadata(); + EmitTargetMetadata(); } @@ -683,8 +703,8 @@ void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type) { unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, "cannot compile this %0 yet"); std::string Msg = Type; - getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID) - << Msg << S->getSourceRange(); + getDiags().Report(Context.getFullLoc(S->getBeginLoc()), DiagID) + << Msg << S->getSourceRange(); } /// ErrorUnsupported - Print out an error that codegen doesn't support the @@ -730,6 +750,14 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM, return false; const llvm::Triple &TT = CGM.getTriple(); + if (TT.isWindowsGNUEnvironment()) { + // 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. + if (GV->isDeclarationForLinker() && isa<llvm::GlobalVariable>(GV) && + !GV->isThreadLocal()) + return false; + } // Every other GV is local on COFF. // Make an exception for windows OS in the triple: Some firmware builds use // *-win32-macho triples. This (accidentally?) produced windows relocations @@ -869,11 +897,13 @@ static std::string getCPUSpecificMangling(const CodeGenModule &CGM, static void AppendCPUSpecificCPUDispatchMangling(const CodeGenModule &CGM, const CPUSpecificAttr *Attr, + unsigned CPUIndex, raw_ostream &Out) { - // cpu_specific gets the current name, dispatch gets the resolver. + // cpu_specific gets the current name, dispatch gets the resolver if IFunc is + // supported. if (Attr) - Out << getCPUSpecificMangling(CGM, Attr->getCurCPUName()->getName()); - else + Out << getCPUSpecificMangling(CGM, Attr->getCPUName(CPUIndex)->getName()); + else if (CGM.getTarget().supportsIFunc()) Out << ".resolver"; } @@ -939,11 +969,19 @@ static std::string getMangledNameImpl(const CodeGenModule &CGM, GlobalDecl GD, if (const auto *FD = dyn_cast<FunctionDecl>(ND)) if (FD->isMultiVersion() && !OmitMultiVersionMangling) { - if (FD->isCPUDispatchMultiVersion() || FD->isCPUSpecificMultiVersion()) - AppendCPUSpecificCPUDispatchMangling( - CGM, FD->getAttr<CPUSpecificAttr>(), Out); - else + switch (FD->getMultiVersionKind()) { + case MultiVersionKind::CPUDispatch: + case MultiVersionKind::CPUSpecific: + AppendCPUSpecificCPUDispatchMangling(CGM, + FD->getAttr<CPUSpecificAttr>(), + GD.getMultiVersionIndex(), Out); + break; + case MultiVersionKind::Target: AppendTargetMangling(CGM, FD->getAttr<TargetAttr>(), Out); + break; + case MultiVersionKind::None: + llvm_unreachable("None multiversion type isn't valid here"); + } } return Out.str(); @@ -968,8 +1006,10 @@ void CodeGenModule::UpdateMultiVersionNames(GlobalDecl GD, "Other GD should now be a multiversioned function"); // OtherFD is the version of this function that was mangled BEFORE // becoming a MultiVersion function. It potentially needs to be updated. - const FunctionDecl *OtherFD = - OtherGD.getCanonicalDecl().getDecl()->getAsFunction(); + const FunctionDecl *OtherFD = OtherGD.getCanonicalDecl() + .getDecl() + ->getAsFunction() + ->getMostRecentDecl(); std::string OtherName = getMangledNameImpl(*this, OtherGD, OtherFD); // This is so that if the initial version was already the 'default' // version, we don't try to update it. @@ -1001,26 +1041,6 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) { } } - const auto *FD = dyn_cast<FunctionDecl>(GD.getDecl()); - // Since CPUSpecific can require multiple emits per decl, store the manglings - // separately. - if (FD && - (FD->isCPUDispatchMultiVersion() || FD->isCPUSpecificMultiVersion())) { - const auto *SD = FD->getAttr<CPUSpecificAttr>(); - - std::pair<GlobalDecl, unsigned> SpecCanonicalGD{ - CanonicalGD, - SD ? SD->ActiveArgIndex : std::numeric_limits<unsigned>::max()}; - - auto FoundName = CPUSpecificMangledDeclNames.find(SpecCanonicalGD); - if (FoundName != CPUSpecificMangledDeclNames.end()) - return FoundName->second; - - auto Result = CPUSpecificManglings.insert( - std::make_pair(getMangledNameImpl(*this, GD, FD), SpecCanonicalGD)); - return CPUSpecificMangledDeclNames[SpecCanonicalGD] = Result.first->first(); - } - auto FoundName = MangledDeclNames.find(CanonicalGD); if (FoundName != MangledDeclNames.end()) return FoundName->second; @@ -1082,11 +1102,12 @@ void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) { // Ctor function type is void()*. llvm::FunctionType* CtorFTy = llvm::FunctionType::get(VoidTy, false); - llvm::Type *CtorPFTy = llvm::PointerType::getUnqual(CtorFTy); + llvm::Type *CtorPFTy = llvm::PointerType::get(CtorFTy, + TheModule.getDataLayout().getProgramAddressSpace()); // Get the type of a ctor entry, { i32, void ()*, i8* }. llvm::StructType *CtorStructTy = llvm::StructType::get( - Int32Ty, llvm::PointerType::getUnqual(CtorFTy), VoidPtrTy); + Int32Ty, CtorPFTy, VoidPtrTy); // Construct the constructor and destructor arrays. ConstantInitBuilder builder(*this); @@ -1142,12 +1163,12 @@ llvm::ConstantInt *CodeGenModule::CreateCrossDsoCfiTypeId(llvm::Metadata *MD) { return llvm::ConstantInt::get(Int64Ty, llvm::MD5Hash(MDS->getString())); } -void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D, +void CodeGenModule::SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F) { unsigned CallingConv; llvm::AttributeList PAL; - ConstructAttributeList(F->getName(), Info, D, PAL, CallingConv, false); + ConstructAttributeList(F->getName(), Info, GD, PAL, CallingConv, false); F->setAttributes(PAL); F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv)); } @@ -1277,9 +1298,19 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, // Otherwise, propagate the inline hint attribute and potentially use its // absence to mark things as noinline. if (auto *FD = dyn_cast<FunctionDecl>(D)) { - if (any_of(FD->redecls(), [&](const FunctionDecl *Redecl) { - return Redecl->isInlineSpecified(); - })) { + // Search function and template pattern redeclarations for inline. + auto CheckForInline = [](const FunctionDecl *FD) { + auto CheckRedeclForInline = [](const FunctionDecl *Redecl) { + return Redecl->isInlineSpecified(); + }; + if (any_of(FD->redecls(), CheckRedeclForInline)) + return true; + const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern(); + if (!Pattern) + return false; + return any_of(Pattern->redecls(), CheckRedeclForInline); + }; + if (CheckForInline(FD)) { B.addAttribute(llvm::Attribute::InlineHint); } else if (CodeGenOpts.getInlining() == CodeGenOptions::OnlyHintInlining && @@ -1350,23 +1381,30 @@ void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) { if (D && D->hasAttr<UsedAttr>()) addUsedGlobal(GV); + + if (CodeGenOpts.KeepStaticConsts && D && isa<VarDecl>(D)) { + const auto *VD = cast<VarDecl>(D); + if (VD->getType().isConstQualified() && + VD->getStorageDuration() == SD_Static) + addUsedGlobal(GV); + } } -bool CodeGenModule::GetCPUAndFeaturesAttributes(const Decl *D, +bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, llvm::AttrBuilder &Attrs) { // 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. StringRef TargetCPU = getTarget().getTargetOpts().CPU; std::vector<std::string> Features; - const auto *FD = dyn_cast_or_null<FunctionDecl>(D); + const auto *FD = dyn_cast_or_null<FunctionDecl>(GD.getDecl()); FD = FD ? FD->getMostRecentDecl() : FD; const auto *TD = FD ? FD->getAttr<TargetAttr>() : nullptr; const auto *SD = FD ? FD->getAttr<CPUSpecificAttr>() : nullptr; bool AddedAttr = false; if (TD || SD) { llvm::StringMap<bool> FeatureMap; - getFunctionFeatureMap(FeatureMap, FD); + getFunctionFeatureMap(FeatureMap, GD); // Produce the canonical string for this set of features. for (const llvm::StringMap<bool>::value_type &Entry : FeatureMap) @@ -1393,7 +1431,7 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(const Decl *D, AddedAttr = true; } if (!Features.empty()) { - llvm::sort(Features.begin(), Features.end()); + llvm::sort(Features); Attrs.addAttribute("target-features", llvm::join(Features, ",")); AddedAttr = true; } @@ -1422,7 +1460,7 @@ void CodeGenModule::setNonAliasAttributes(GlobalDecl GD, F->addFnAttr("implicit-section-name", SA->getName()); llvm::AttrBuilder Attrs; - if (GetCPUAndFeaturesAttributes(D, Attrs)) { + if (GetCPUAndFeaturesAttributes(GD, Attrs)) { // 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. @@ -1445,7 +1483,7 @@ void CodeGenModule::SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI) { const Decl *D = GD.getDecl(); - SetLLVMFunctionAttributes(D, FI, F); + SetLLVMFunctionAttributes(GD, FI, F); SetLLVMFunctionAttributesForDefinition(D, F); F->setLinkage(llvm::Function::InternalLinkage); @@ -1507,7 +1545,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, const auto *FD = cast<FunctionDecl>(GD.getDecl()); if (!IsIncompleteFunction) { - SetLLVMFunctionAttributes(FD, getTypes().arrangeGlobalDeclaration(GD), F); + SetLLVMFunctionAttributes(GD, getTypes().arrangeGlobalDeclaration(GD), F); // Setup target-specific attributes. if (F->isDeclaration()) getTargetCodeGenInfo().setTargetAttributes(FD, F, *this); @@ -1654,6 +1692,8 @@ static void addLinkOptionsPostorder(CodeGenModule &CGM, Module *Mod, // Add linker options to link against the libraries/frameworks // described by this module. llvm::LLVMContext &Context = CGM.getLLVMContext(); + bool IsELF = CGM.getTarget().getTriple().isOSBinFormatELF(); + bool IsPS4 = CGM.getTarget().getTriple().isPS4(); // For modules that use export_as for linking, use that module // name instead. @@ -1673,11 +1713,19 @@ static void addLinkOptionsPostorder(CodeGenModule &CGM, Module *Mod, } // Link against a library. - llvm::SmallString<24> Opt; - CGM.getTargetCodeGenInfo().getDependentLibraryOption( - Mod->LinkLibraries[I-1].Library, Opt); - auto *OptString = llvm::MDString::get(Context, Opt); - Metadata.push_back(llvm::MDNode::get(Context, OptString)); + if (IsELF && !IsPS4) { + llvm::Metadata *Args[2] = { + llvm::MDString::get(Context, "lib"), + llvm::MDString::get(Context, Mod->LinkLibraries[I - 1].Library), + }; + Metadata.push_back(llvm::MDNode::get(Context, Args)); + } else { + llvm::SmallString<24> Opt; + CGM.getTargetCodeGenInfo().getDependentLibraryOption( + Mod->LinkLibraries[I - 1].Library, Opt); + auto *OptString = llvm::MDString::get(Context, Opt); + Metadata.push_back(llvm::MDNode::get(Context, OptString)); + } } } @@ -1708,16 +1756,14 @@ void CodeGenModule::EmitModuleLinkOptions() { bool AnyChildren = false; // Visit the submodules of this module. - for (clang::Module::submodule_iterator Sub = Mod->submodule_begin(), - SubEnd = Mod->submodule_end(); - Sub != SubEnd; ++Sub) { + for (const auto &SM : Mod->submodules()) { // Skip explicit children; they need to be explicitly imported to be // linked against. - if ((*Sub)->IsExplicit) + if (SM->IsExplicit) continue; - if (Visited.insert(*Sub).second) { - Stack.push_back(*Sub); + if (Visited.insert(SM).second) { + Stack.push_back(SM); AnyChildren = true; } } @@ -1747,6 +1793,10 @@ void CodeGenModule::EmitModuleLinkOptions() { } void CodeGenModule::EmitDeferred() { + // Emit deferred declare target declarations. + if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd) + getOpenMPRuntime().emitDeferredTargetDecls(); + // Emit code for any potentially referenced deferred decls. Since a // previously unused static decl may become used during the generation of code // for a static function, iterate until no changes are made. @@ -1949,9 +1999,6 @@ bool CodeGenModule::isInSanitizerBlacklist(llvm::GlobalVariable *GV, bool CodeGenModule::imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc, StringRef Category) const { - if (!LangOpts.XRayInstrument) - return false; - const auto &XRayFilter = getContext().getXRayFilter(); using ImbueAttr = XRayFunctionFilter::ImbueAttribute; auto Attr = ImbueAttr::NONE; @@ -1981,6 +2028,13 @@ 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; + } + return getContext().DeclMustBeEmitted(Global); } @@ -2000,7 +2054,8 @@ 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) && + !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(Global)) return false; return true; @@ -2141,16 +2196,22 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { } else { const auto *VD = cast<VarDecl>(Global); assert(VD->isFileVarDecl() && "Cannot emit local var decl as global."); - // We need to emit device-side global CUDA variables even if a - // variable does not have a definition -- we still need to define - // host-side shadow for it. - bool MustEmitForCuda = LangOpts.CUDA && !LangOpts.CUDAIsDevice && - !VD->hasDefinition() && - (VD->hasAttr<CUDAConstantAttr>() || - VD->hasAttr<CUDADeviceAttr>()); - if (!MustEmitForCuda && - VD->isThisDeclarationADefinition() != VarDecl::Definition && + if (VD->isThisDeclarationADefinition() != VarDecl::Definition && !Context.isMSStaticDataMemberInlineDefinition(VD)) { + if (LangOpts.OpenMP) { + // Emit declaration of the must-be-emitted declare target variable. + if (llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { + if (*Res == OMPDeclareTargetDeclAttr::MT_To) { + (void)GetAddrOfGlobalVar(VD); + } else { + assert(*Res == OMPDeclareTargetDeclAttr::MT_Link && + "link claue expected."); + (void)getOpenMPRuntime().getAddrOfDeclareTargetLink(VD); + } + return; + } + } // If this declaration may have caused an inline variable definition to // change linkage, make sure that it's emitted. if (Context.getInlineVariableDefinitionKind(VD) == @@ -2360,6 +2421,19 @@ bool CodeGenModule::shouldOpportunisticallyEmitVTables() { return CodeGenOpts.OptimizationLevel > 0; } +void CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD, + llvm::GlobalValue *GV) { + const auto *FD = cast<FunctionDecl>(GD.getDecl()); + + if (FD->isCPUSpecificMultiVersion()) { + auto *Spec = FD->getAttr<CPUSpecificAttr>(); + for (unsigned I = 0; I < Spec->cpus_size(); ++I) + EmitGlobalFunctionDefinition(GD.getWithMultiVersionIndex(I), nullptr); + // Requires multiple emits. + } else + EmitGlobalFunctionDefinition(GD, GV); +} + void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { const auto *D = cast<ValueDecl>(GD.getDecl()); @@ -2367,7 +2441,7 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { Context.getSourceManager(), "Generating code for declaration"); - if (isa<FunctionDecl>(D)) { + if (const auto *FD = dyn_cast<FunctionDecl>(D)) { // At -O0, don't generate IR for functions with available_externally // linkage. if (!shouldEmitFunction(GD)) @@ -2380,6 +2454,8 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { ABI->emitCXXStructor(CD, getFromCtorType(GD.getCtorType())); else if (const auto *DD = dyn_cast<CXXDestructorDecl>(Method)) ABI->emitCXXStructor(DD, getFromDtorType(GD.getDtorType())); + else if (FD->isMultiVersion()) + EmitMultiVersionFunctionDefinition(GD, GV); else EmitGlobalFunctionDefinition(GD, GV); @@ -2389,6 +2465,8 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { return; } + if (FD->isMultiVersion()) + return EmitMultiVersionFunctionDefinition(GD, GV); return EmitGlobalFunctionDefinition(GD, GV); } @@ -2401,9 +2479,22 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, llvm::Function *NewFn); +static unsigned +TargetMVPriority(const TargetInfo &TI, + const CodeGenFunction::MultiVersionResolverOption &RO) { + unsigned Priority = 0; + for (StringRef Feat : RO.Conditions.Features) + Priority = std::max(Priority, TI.multiVersionSortPriority(Feat)); + + if (!RO.Conditions.Architecture.empty()) + Priority = std::max( + Priority, TI.multiVersionSortPriority(RO.Conditions.Architecture)); + return Priority; +} + void CodeGenModule::emitMultiVersionFunctions() { for (GlobalDecl GD : MultiVersionFuncs) { - SmallVector<CodeGenFunction::TargetMultiVersionResolverOption, 10> Options; + SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options; const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); getContext().forEachMultiversionedFunctionVersion( FD, [this, &GD, &Options](const FunctionDecl *CurFD) { @@ -2424,20 +2515,36 @@ void CodeGenModule::emitMultiVersionFunctions() { } assert(Func && "This should have just been created"); } - Options.emplace_back(getTarget(), cast<llvm::Function>(Func), - CurFD->getAttr<TargetAttr>()->parse()); + + const auto *TA = CurFD->getAttr<TargetAttr>(); + llvm::SmallVector<StringRef, 8> Feats; + TA->getAddedFeatures(Feats); + + Options.emplace_back(cast<llvm::Function>(Func), + TA->getArchitecture(), Feats); }); - llvm::Function *ResolverFunc = cast<llvm::Function>( - GetGlobalValue((getMangledName(GD) + ".resolver").str())); + llvm::Function *ResolverFunc; + const TargetInfo &TI = getTarget(); + + if (TI.supportsIFunc() || FD->isTargetMultiVersion()) + ResolverFunc = cast<llvm::Function>( + GetGlobalValue((getMangledName(GD) + ".resolver").str())); + else + ResolverFunc = cast<llvm::Function>(GetGlobalValue(getMangledName(GD))); + if (supportsCOMDAT()) ResolverFunc->setComdat( getModule().getOrInsertComdat(ResolverFunc->getName())); + std::stable_sort( Options.begin(), Options.end(), - std::greater<CodeGenFunction::TargetMultiVersionResolverOption>()); + [&TI](const CodeGenFunction::MultiVersionResolverOption &LHS, + const CodeGenFunction::MultiVersionResolverOption &RHS) { + return TargetMVPriority(TI, LHS) > TargetMVPriority(TI, RHS); + }); CodeGenFunction CGF(*this); - CGF.EmitTargetMultiVersionResolver(ResolverFunc, Options); + CGF.EmitMultiVersionResolver(ResolverFunc, Options); } } @@ -2446,27 +2553,58 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { assert(FD && "Not a FunctionDecl?"); const auto *DD = FD->getAttr<CPUDispatchAttr>(); assert(DD && "Not a cpu_dispatch Function?"); - llvm::Type *DeclTy = getTypes().ConvertTypeForMem(FD->getType()); + QualType CanonTy = Context.getCanonicalType(FD->getType()); + llvm::Type *DeclTy = getTypes().ConvertFunctionType(CanonTy, FD); + + if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { + const CGFunctionInfo &FInfo = getTypes().arrangeCXXMethodDeclaration(CXXFD); + DeclTy = getTypes().GetFunctionType(FInfo); + } StringRef ResolverName = getMangledName(GD); - llvm::Type *ResolverType = llvm::FunctionType::get( - llvm::PointerType::get(DeclTy, - Context.getTargetAddressSpace(FD->getType())), - false); - auto *ResolverFunc = cast<llvm::Function>( - GetOrCreateLLVMFunction(ResolverName, ResolverType, GlobalDecl{}, - /*ForVTable=*/false)); - - SmallVector<CodeGenFunction::CPUDispatchMultiVersionResolverOption, 10> - Options; + + llvm::Type *ResolverType; + GlobalDecl ResolverGD; + if (getTarget().supportsIFunc()) + ResolverType = llvm::FunctionType::get( + llvm::PointerType::get(DeclTy, + Context.getTargetAddressSpace(FD->getType())), + false); + else { + ResolverType = DeclTy; + ResolverGD = GD; + } + + auto *ResolverFunc = cast<llvm::Function>(GetOrCreateLLVMFunction( + ResolverName, ResolverType, ResolverGD, /*ForVTable=*/false)); + + SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options; const TargetInfo &Target = getTarget(); + unsigned Index = 0; for (const IdentifierInfo *II : DD->cpus()) { // Get the name of the target function so we can look it up/create it. std::string MangledName = getMangledNameImpl(*this, GD, FD, true) + getCPUSpecificMangling(*this, II->getName()); - llvm::Constant *Func = GetOrCreateLLVMFunction( - MangledName, DeclTy, GD, /*ForVTable=*/false, /*DontDefer=*/false, - /*IsThunk=*/false, llvm::AttributeList(), ForDefinition); + + llvm::Constant *Func = GetGlobalValue(MangledName); + + if (!Func) { + GlobalDecl ExistingDecl = Manglings.lookup(MangledName); + if (ExistingDecl.getDecl() && + ExistingDecl.getDecl()->getAsFunction()->isDefined()) { + EmitGlobalFunctionDefinition(ExistingDecl, nullptr); + Func = GetGlobalValue(MangledName); + } else { + if (!ExistingDecl.getDecl()) + ExistingDecl = GD.getWithMultiVersionIndex(Index); + + Func = GetOrCreateLLVMFunction( + MangledName, DeclTy, ExistingDecl, + /*ForVTable=*/false, /*DontDefer=*/true, + /*IsThunk=*/false, llvm::AttributeList(), ForDefinition); + } + } + llvm::SmallVector<StringRef, 32> Features; Target.getCPUSpecificCPUDispatchFeatures(II->getName(), Features); llvm::transform(Features, Features.begin(), @@ -2475,27 +2613,54 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { Features.begin(), Features.end(), [&Target](StringRef Feat) { return !Target.validateCpuSupports(Feat); }), Features.end()); - Options.emplace_back(cast<llvm::Function>(Func), - CodeGenFunction::GetX86CpuSupportsMask(Features)); + Options.emplace_back(cast<llvm::Function>(Func), StringRef{}, Features); + ++Index; } llvm::sort( - Options.begin(), Options.end(), - std::greater<CodeGenFunction::CPUDispatchMultiVersionResolverOption>()); + Options, [](const CodeGenFunction::MultiVersionResolverOption &LHS, + const CodeGenFunction::MultiVersionResolverOption &RHS) { + return CodeGenFunction::GetX86CpuSupportsMask(LHS.Conditions.Features) > + CodeGenFunction::GetX86CpuSupportsMask(RHS.Conditions.Features); + }); + + // If the list contains multiple 'default' versions, such as when it contains + // 'pentium' and 'generic', don't emit the call to the generic one (since we + // always run on at least a 'pentium'). We do this by deleting the 'least + // advanced' (read, lowest mangling letter). + while (Options.size() > 1 && + CodeGenFunction::GetX86CpuSupportsMask( + (Options.end() - 2)->Conditions.Features) == 0) { + StringRef LHSName = (Options.end() - 2)->Function->getName(); + StringRef RHSName = (Options.end() - 1)->Function->getName(); + if (LHSName.compare(RHSName) < 0) + Options.erase(Options.end() - 2); + else + Options.erase(Options.end() - 1); + } + CodeGenFunction CGF(*this); - CGF.EmitCPUDispatchMultiVersionResolver(ResolverFunc, Options); + CGF.EmitMultiVersionResolver(ResolverFunc, Options); } -/// If an ifunc for the specified mangled name is not in the module, create and -/// return an llvm IFunc Function with the specified type. -llvm::Constant * -CodeGenModule::GetOrCreateMultiVersionIFunc(GlobalDecl GD, llvm::Type *DeclTy, - const FunctionDecl *FD) { +/// If a dispatcher for the specified mangled name is not in the module, create +/// and return an llvm Function with the specified type. +llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver( + GlobalDecl GD, llvm::Type *DeclTy, const FunctionDecl *FD) { std::string MangledName = getMangledNameImpl(*this, GD, FD, /*OmitMultiVersionMangling=*/true); - std::string IFuncName = MangledName + ".ifunc"; - if (llvm::GlobalValue *IFuncGV = GetGlobalValue(IFuncName)) - return IFuncGV; + + // Holds the name of the resolver, in ifunc mode this is the ifunc (which has + // a separate resolver). + std::string ResolverName = MangledName; + if (getTarget().supportsIFunc()) + ResolverName += ".ifunc"; + else if (FD->isTargetMultiVersion()) + ResolverName += ".resolver"; + + // If this already exists, just return that one. + if (llvm::GlobalValue *ResolverGV = GetGlobalValue(ResolverName)) + return ResolverGV; // Since this is the first time we've created this IFunc, make sure // that we put this multiversioned function into the list to be @@ -2503,20 +2668,28 @@ CodeGenModule::GetOrCreateMultiVersionIFunc(GlobalDecl GD, llvm::Type *DeclTy, if (!FD->isCPUDispatchMultiVersion() && !FD->isCPUSpecificMultiVersion()) MultiVersionFuncs.push_back(GD); - std::string ResolverName = MangledName + ".resolver"; - llvm::Type *ResolverType = llvm::FunctionType::get( - llvm::PointerType::get(DeclTy, - Context.getTargetAddressSpace(FD->getType())), - false); - llvm::Constant *Resolver = - GetOrCreateLLVMFunction(ResolverName, ResolverType, GlobalDecl{}, - /*ForVTable=*/false); - llvm::GlobalIFunc *GIF = llvm::GlobalIFunc::create( - DeclTy, 0, llvm::Function::ExternalLinkage, "", Resolver, &getModule()); - GIF->setName(IFuncName); - SetCommonAttributes(FD, GIF); + if (getTarget().supportsIFunc()) { + llvm::Type *ResolverType = llvm::FunctionType::get( + llvm::PointerType::get( + DeclTy, getContext().getTargetAddressSpace(FD->getType())), + false); + llvm::Constant *Resolver = GetOrCreateLLVMFunction( + MangledName + ".resolver", ResolverType, GlobalDecl{}, + /*ForVTable=*/false); + llvm::GlobalIFunc *GIF = llvm::GlobalIFunc::create( + DeclTy, 0, llvm::Function::ExternalLinkage, "", Resolver, &getModule()); + GIF->setName(ResolverName); + SetCommonAttributes(FD, GIF); - return GIF; + return GIF; + } + + llvm::Constant *Resolver = GetOrCreateLLVMFunction( + ResolverName, DeclTy, GlobalDecl{}, /*ForVTable=*/false); + assert(isa<llvm::GlobalValue>(Resolver) && + "Resolver should be created for the first time"); + SetCommonAttributes(FD, cast<llvm::GlobalValue>(Resolver)); + return Resolver; } /// GetOrCreateLLVMFunction - If the specified mangled name is not in the @@ -2539,15 +2712,16 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( if (getLangOpts().OpenMPIsDevice && OpenMPRuntime && !OpenMPRuntime->markAsGlobalTarget(GD) && FD->isDefined() && !DontDefer && !IsForDefinition) { - const FunctionDecl *FDDef = FD->getDefinition(); - GlobalDecl GDDef; - if (const auto *CD = dyn_cast<CXXConstructorDecl>(FDDef)) - GDDef = GlobalDecl(CD, GD.getCtorType()); - else if (const auto *DD = dyn_cast<CXXDestructorDecl>(FDDef)) - GDDef = GlobalDecl(DD, GD.getDtorType()); - else - GDDef = GlobalDecl(FDDef); - addDeferredDeclToEmit(GDDef); + if (const FunctionDecl *FDDef = FD->getDefinition()) { + GlobalDecl GDDef; + if (const auto *CD = dyn_cast<CXXConstructorDecl>(FDDef)) + GDDef = GlobalDecl(CD, GD.getCtorType()); + else if (const auto *DD = dyn_cast<CXXDestructorDecl>(FDDef)) + GDDef = GlobalDecl(DD, GD.getDtorType()); + else + GDDef = GlobalDecl(FDDef); + EmitGlobal(GDDef); + } } if (FD->isMultiVersion()) { @@ -2555,7 +2729,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( if (TA && TA->isDefaultVersion()) UpdateMultiVersionNames(GD, FD); if (!IsForDefinition) - return GetOrCreateMultiVersionIFunc(GD, Ty, FD); + return GetOrCreateMultiVersionResolver(GD, Ty, FD); } } @@ -3058,10 +3232,9 @@ CodeGenModule::GetAddrOfGlobal(GlobalDecl GD, IsForDefinition); } -llvm::GlobalVariable * -CodeGenModule::CreateOrReplaceCXXRuntimeVariable(StringRef Name, - llvm::Type *Ty, - llvm::GlobalValue::LinkageTypes Linkage) { +llvm::GlobalVariable *CodeGenModule::CreateOrReplaceCXXRuntimeVariable( + StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage, + unsigned Alignment) { llvm::GlobalVariable *GV = getModule().getNamedGlobal(Name); llvm::GlobalVariable *OldGV = nullptr; @@ -3097,6 +3270,8 @@ CodeGenModule::CreateOrReplaceCXXRuntimeVariable(StringRef Name, !GV->hasAvailableExternallyLinkage()) GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); + GV->setAlignment(Alignment); + return GV; } @@ -3313,8 +3488,15 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, // CUDA E.2.4.1 "__shared__ variables cannot have an initialization // as part of their declaration." Sema has already checked for // error cases, so we just need to set Init to UndefValue. - if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice && - D->hasAttr<CUDASharedAttr>()) + bool IsCUDASharedVar = + getLangOpts().CUDAIsDevice && D->hasAttr<CUDASharedAttr>(); + // Shadows of initialized device-side global variables are also left + // undefined. + bool IsCUDAShadowVar = + !getLangOpts().CUDAIsDevice && + (D->hasAttr<CUDAConstantAttr>() || D->hasAttr<CUDADeviceAttr>() || + D->hasAttr<CUDASharedAttr>()); + if (getLangOpts().CUDA && (IsCUDASharedVar || IsCUDAShadowVar)) Init = llvm::UndefValue::get(getTypes().ConvertType(ASTTy)); else if (!InitExpr) { // This is a tentative definition; tentative definitions are @@ -3434,7 +3616,10 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, Flags |= CGCUDARuntime::ExternDeviceVar; if (D->hasAttr<CUDAConstantAttr>()) Flags |= CGCUDARuntime::ConstantDeviceVar; - getCUDARuntime().registerDeviceVar(*GV, Flags); + // Extern global variables will be registered in the TU where they are + // defined. + if (!D->hasExternalStorage()) + getCUDARuntime().registerDeviceVar(*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 @@ -3577,6 +3762,15 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context, } } + // Microsoft's link.exe doesn't support alignments greater than 32 for common + // symbols, so symbols with greater alignment requirements cannot be common. + // Other COFF linkers (ld.bfd and LLD) support arbitrary power-of-two + // alignments for common symbols via the aligncomm directive, so this + // restriction only applies to MSVC environments. + if (Context.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() && + Context.getTypeAlignIfKnown(D->getType()) > 32) + return true; + return false; } @@ -3592,6 +3786,10 @@ llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator( return llvm::GlobalVariable::WeakAnyLinkage; } + if (const auto *FD = D->getAsFunction()) + if (FD->isMultiVersion() && Linkage == GVA_AvailableExternally) + return llvm::GlobalVariable::LinkOnceAnyLinkage; + // We are guaranteed to have a strong definition somewhere else, // so we can use available_externally linkage. if (Linkage == GVA_AvailableExternally) @@ -3828,15 +4026,6 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, AddGlobalDtor(Fn, DA->getPriority()); if (D->hasAttr<AnnotateAttr>()) AddGlobalAnnotations(D, Fn); - - if (D->isCPUSpecificMultiVersion()) { - auto *Spec = D->getAttr<CPUSpecificAttr>(); - // If there is another specific version we need to emit, do so here. - if (Spec->ActiveArgIndex + 1 < Spec->cpus_size()) { - ++Spec->ActiveArgIndex; - EmitGlobalFunctionDefinition(GD, nullptr); - } - } } void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { @@ -4030,39 +4219,81 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { llvm::Constant *Zero = llvm::Constant::getNullValue(Int32Ty); llvm::Constant *Zeros[] = { Zero, Zero }; + const ASTContext &Context = getContext(); + const llvm::Triple &Triple = getTriple(); + + const auto CFRuntime = getLangOpts().CFRuntime; + const bool IsSwiftABI = + static_cast<unsigned>(CFRuntime) >= + static_cast<unsigned>(LangOptions::CoreFoundationABI::Swift); + const bool IsSwift4_1 = CFRuntime == LangOptions::CoreFoundationABI::Swift4_1; + // If we don't already have it, get __CFConstantStringClassReference. if (!CFConstantStringClassRef) { + const char *CFConstantStringClassName = "__CFConstantStringClassReference"; llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); Ty = llvm::ArrayType::get(Ty, 0); - llvm::GlobalValue *GV = cast<llvm::GlobalValue>( - CreateRuntimeVariable(Ty, "__CFConstantStringClassReference")); - - if (getTriple().isOSBinFormatCOFF()) { - IdentifierInfo &II = getContext().Idents.get(GV->getName()); - TranslationUnitDecl *TUDecl = getContext().getTranslationUnitDecl(); - DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); - - const VarDecl *VD = nullptr; - for (const auto &Result : DC->lookup(&II)) - if ((VD = dyn_cast<VarDecl>(Result))) - break; - - if (!VD || !VD->hasAttr<DLLExportAttr>()) { - GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); - GV->setLinkage(llvm::GlobalValue::ExternalLinkage); - } else { - GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); - GV->setLinkage(llvm::GlobalValue::ExternalLinkage); + + switch (CFRuntime) { + default: break; + case LangOptions::CoreFoundationABI::Swift: LLVM_FALLTHROUGH; + case LangOptions::CoreFoundationABI::Swift5_0: + CFConstantStringClassName = + Triple.isOSDarwin() ? "$s15SwiftFoundation19_NSCFConstantStringCN" + : "$s10Foundation19_NSCFConstantStringCN"; + Ty = IntPtrTy; + break; + case LangOptions::CoreFoundationABI::Swift4_2: + CFConstantStringClassName = + Triple.isOSDarwin() ? "$S15SwiftFoundation19_NSCFConstantStringCN" + : "$S10Foundation19_NSCFConstantStringCN"; + Ty = IntPtrTy; + break; + case LangOptions::CoreFoundationABI::Swift4_1: + CFConstantStringClassName = + Triple.isOSDarwin() ? "__T015SwiftFoundation19_NSCFConstantStringCN" + : "__T010Foundation19_NSCFConstantStringCN"; + Ty = IntPtrTy; + break; + } + + llvm::Constant *C = CreateRuntimeVariable(Ty, CFConstantStringClassName); + + if (Triple.isOSBinFormatELF() || Triple.isOSBinFormatCOFF()) { + llvm::GlobalValue *GV = nullptr; + + if ((GV = dyn_cast<llvm::GlobalValue>(C))) { + IdentifierInfo &II = Context.Idents.get(GV->getName()); + TranslationUnitDecl *TUDecl = Context.getTranslationUnitDecl(); + DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); + + const VarDecl *VD = nullptr; + for (const auto &Result : DC->lookup(&II)) + if ((VD = dyn_cast<VarDecl>(Result))) + break; + + if (Triple.isOSBinFormatELF()) { + if (!VD) + GV->setLinkage(llvm::GlobalValue::ExternalLinkage); + } else { + GV->setLinkage(llvm::GlobalValue::ExternalLinkage); + if (!VD || !VD->hasAttr<DLLExportAttr>()) + GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + else + GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + } + + setDSOLocal(GV); } } - setDSOLocal(GV); // Decay array -> ptr CFConstantStringClassRef = - llvm::ConstantExpr::getGetElementPtr(Ty, GV, Zeros); + IsSwiftABI ? llvm::ConstantExpr::getPtrToInt(C, Ty) + : llvm::ConstantExpr::getGetElementPtr(Ty, C, Zeros); } - QualType CFTy = getContext().getCFConstantStringType(); + QualType CFTy = Context.getCFConstantStringType(); auto *STy = cast<llvm::StructType>(getTypes().ConvertType(CFTy)); @@ -4073,7 +4304,12 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { Fields.add(cast<llvm::ConstantExpr>(CFConstantStringClassRef)); // Flags. - Fields.addInt(IntTy, isUTF16 ? 0x07d0 : 0x07C8); + if (IsSwiftABI) { + Fields.addInt(IntPtrTy, IsSwift4_1 ? 0x05 : 0x01); + Fields.addInt(Int64Ty, isUTF16 ? 0x07d0 : 0x07c8); + } else { + Fields.addInt(IntTy, isUTF16 ? 0x07d0 : 0x07C8); + } // String pointer. llvm::Constant *C = nullptr; @@ -4094,17 +4330,20 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); // Don't enforce the target's minimum global alignment, since the only use // of the string is via this class initializer. - CharUnits Align = isUTF16 - ? getContext().getTypeAlignInChars(getContext().ShortTy) - : getContext().getTypeAlignInChars(getContext().CharTy); + CharUnits Align = isUTF16 ? Context.getTypeAlignInChars(Context.ShortTy) + : Context.getTypeAlignInChars(Context.CharTy); GV->setAlignment(Align.getQuantity()); // FIXME: We set the section explicitly to avoid a bug in ld64 224.1. // Without it LLVM can merge the string with a non unnamed_addr one during // LTO. Doing that changes the section it ends in, which surprises ld64. - if (getTriple().isOSBinFormatMachO()) + if (Triple.isOSBinFormatMachO()) GV->setSection(isUTF16 ? "__TEXT,__ustring" : "__TEXT,__cstring,cstring_literals"); + // Make sure the literal ends up in .rodata to allow for safe ICF and for + // the static linker to adjust permissions to read-only later on. + else if (Triple.isOSBinFormatELF()) + GV->setSection(".rodata"); // String. llvm::Constant *Str = @@ -4116,8 +4355,17 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { Fields.add(Str); // String length. - auto Ty = getTypes().ConvertType(getContext().LongTy); - Fields.addInt(cast<llvm::IntegerType>(Ty), StringLength); + llvm::IntegerType *LengthTy = + llvm::IntegerType::get(getModule().getContext(), + Context.getTargetInfo().getLongWidth()); + if (IsSwiftABI) { + if (CFRuntime == LangOptions::CoreFoundationABI::Swift4_1 || + CFRuntime == LangOptions::CoreFoundationABI::Swift4_2) + LengthTy = Int32Ty; + else + LengthTy = IntPtrTy; + } + Fields.addInt(LengthTy, StringLength); CharUnits Alignment = getPointerAlign(); @@ -4125,7 +4373,7 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { GV = Fields.finishAndCreateGlobal("_unnamed_cfstring_", Alignment, /*isConstant=*/false, llvm::GlobalVariable::PrivateLinkage); - switch (getTriple().getObjectFormat()) { + switch (Triple.getObjectFormat()) { case llvm::Triple::UnknownObjectFormat: llvm_unreachable("unknown file format"); case llvm::Triple::COFF: @@ -4264,15 +4512,13 @@ CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S, StringRef GlobalVariableName; llvm::GlobalValue::LinkageTypes LT; - // Mangle the string literal if the ABI allows for it. However, we cannot - // do this if we are compiling with ASan or -fwritable-strings because they - // rely on strings having normal linkage. - if (!LangOpts.WritableStrings && - !LangOpts.Sanitize.has(SanitizerKind::Address) && - getCXXABI().getMangleContext().shouldMangleStringLiteral(S)) { + // Mangle the string literal if that's how the ABI merges duplicate strings. + // Don't do it if they are writable, since we don't want writes in one TU to + // affect strings in another. + if (getCXXABI().getMangleContext().shouldMangleStringLiteral(S) && + !LangOpts.WritableStrings) { llvm::raw_svector_ostream Out(MangledNameBuffer); getCXXABI().getMangleContext().mangleStringLiteral(S, Out); - LT = llvm::GlobalValue::LinkOnceODRLinkage; GlobalVariableName = MangledNameBuffer; } else { @@ -4620,6 +4866,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::TypeAliasTemplate: case Decl::Block: case Decl::Empty: + case Decl::Binding: break; case Decl::Using: // using X; [C++] if (CGDebugInfo *DI = getModuleDebugInfo()) @@ -4787,6 +5034,10 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { EmitOMPDeclareReduction(cast<OMPDeclareReductionDecl>(D)); break; + case Decl::OMPRequires: + EmitOMPRequiresDecl(cast<OMPRequiresDecl>(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 @@ -4810,7 +5061,7 @@ void CodeGenModule::AddDeferredUnusedCoverageMapping(Decl *D) { if (!cast<FunctionDecl>(D)->doesThisDeclarationHaveABody()) return; SourceManager &SM = getContext().getSourceManager(); - if (LimitedCoverage && SM.getMainFileID() != SM.getFileID(D->getLocStart())) + if (LimitedCoverage && SM.getMainFileID() != SM.getFileID(D->getBeginLoc())) return; auto I = DeferredEmptyCoverageMappingDecls.find(D); if (I == DeferredEmptyCoverageMappingDecls.end()) @@ -4981,6 +5232,16 @@ void CodeGenModule::EmitVersionIdentMetadata() { IdentMetadata->addOperand(llvm::MDNode::get(Ctx, IdentNode)); } +void CodeGenModule::EmitCommandLineMetadata() { + llvm::NamedMDNode *CommandLineMetadata = + TheModule.getOrInsertNamedMetadata("llvm.commandline"); + std::string CommandLine = getCodeGenOpts().RecordCommandLine; + llvm::LLVMContext &Ctx = TheModule.getContext(); + + llvm::Metadata *CommandLineNode[] = {llvm::MDString::get(Ctx, CommandLine)}; + 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 @@ -5073,7 +5334,7 @@ void CodeGenModule::EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) { Address Addr(GetAddrOfGlobalVar(VD), getContext().getDeclAlign(VD)); if (auto InitFunction = getOpenMPRuntime().emitThreadPrivateVarDefinition( - VD, Addr, RefExpr->getLocStart(), PerformInit)) + VD, Addr, RefExpr->getBeginLoc(), PerformInit)) CXXGlobalInits.push_back(InitFunction); } } @@ -5196,8 +5457,9 @@ TargetAttr::ParsedTargetAttr CodeGenModule::filterFunctionTargetAttrs(const Targ // Fills in the supplied string map with the set of target features for the // passed in function. void CodeGenModule::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap, - const FunctionDecl *FD) { + GlobalDecl GD) { StringRef TargetCPU = Target.getTargetOpts().CPU; + const FunctionDecl *FD = GD.getDecl()->getAsFunction(); if (const auto *TD = FD->getAttr<TargetAttr>()) { TargetAttr::ParsedTargetAttr ParsedAttr = filterFunctionTargetAttrs(TD); @@ -5219,8 +5481,8 @@ void CodeGenModule::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap, ParsedAttr.Features); } else if (const auto *SD = FD->getAttr<CPUSpecificAttr>()) { llvm::SmallVector<StringRef, 32> FeaturesTmp; - Target.getCPUSpecificCPUDispatchFeatures(SD->getCurCPUName()->getName(), - FeaturesTmp); + Target.getCPUSpecificCPUDispatchFeatures( + SD->getCPUName(GD.getMultiVersionIndex())->getName(), FeaturesTmp); std::vector<std::string> Features(FeaturesTmp.begin(), FeaturesTmp.end()); Target.initFeatureMap(FeatureMap, getDiags(), TargetCPU, Features); } else { |