diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-12-08 14:31:58 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-12-08 14:31:58 +0000 |
commit | 52c5eb8567b3104e357ad43927aa605be3246c6f (patch) | |
tree | ec82879cc87188bcca0827988cc7d69143e00ee4 /lib | |
parent | 6ae2bfad8ae4459e286c88b4c5b5584c2577b317 (diff) | |
download | src-52c5eb8567b3104e357ad43927aa605be3246c6f.tar.gz src-52c5eb8567b3104e357ad43927aa605be3246c6f.zip |
Vendor import of clang release_70 branch r348686:vendor/clang/clang-release_70-r348686
Notes
Notes:
svn path=/vendor/clang/dist-release_70/; revision=341730
svn path=/vendor/clang/clang-release_70-r348686/; revision=341731; tag=vendor/clang/clang-release_70-r348686
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 4 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 24 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 80 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 41 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 73 | ||||
-rw-r--r-- | lib/Driver/ToolChains/OpenBSD.cpp | 2 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 7 |
7 files changed, 130 insertions, 101 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index c085f52cae31..648fa9f0fbc6 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -9734,6 +9734,10 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { return true; if (const auto *FD = dyn_cast<FunctionDecl>(D)) { + // Multiversioned functions always have to be emitted, because they are used + // by the resolver. + if (FD->isMultiVersion()) + return true; // Forward declarations aren't required. if (!FD->doesThisDeclarationHaveABody()) return FD->doesDeclarationForceExternallyVisibleDefinition(); diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 8030dd0c2f41..1bf01b901232 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -725,7 +725,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, // If we're paying attention to global visibility, apply // -finline-visibility-hidden if this is an inline method. if (useInlineVisibilityHidden(D)) - LV.mergeVisibility(HiddenVisibility, true); + LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false); } } @@ -915,7 +915,7 @@ LinkageComputer::getLVForClassMember(const NamedDecl *D, // Note that we do this before merging information about // the class visibility. if (!LV.isVisibilityExplicit() && useInlineVisibilityHidden(D)) - LV.mergeVisibility(HiddenVisibility, true); + LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false); } // If this class member has an explicit visibility attribute, the only @@ -1262,7 +1262,27 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D, !isTemplateInstantiation(FD->getTemplateSpecializationKind())) return LinkageInfo::none(); + // If a function is hidden by -fvisibility-inlines-hidden option and + // is not explicitly attributed as a hidden function, + // we should not make static local variables in the function hidden. LV = getLVForDecl(FD, computation); + if (isa<VarDecl>(D) && useInlineVisibilityHidden(FD) && + !LV.isVisibilityExplicit()) { + assert(cast<VarDecl>(D)->isStaticLocal()); + // If this was an implicitly hidden inline method, check again for + // explicit visibility on the parent class, and use that for static locals + // if present. + if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) + LV = getLVForDecl(MD->getParent(), computation); + if (!LV.isVisibilityExplicit()) { + Visibility globalVisibility = + computation.isValueVisibility() + ? Context.getLangOpts().getValueVisibilityMode() + : Context.getLangOpts().getTypeVisibilityMode(); + return LinkageInfo(VisibleNoLinkage, globalVisibility, + /*visibilityExplicit=*/false); + } + } } if (!isExternallyVisible(LV.getLinkage())) return LinkageInfo::none(); diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 3c582688e91e..166d588dd55b 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -2359,91 +2359,53 @@ void CodeGenFunction::EmitSanitizerStatReport(llvm::SanitizerStatKind SSK) { CGM.getSanStats().create(IRB, SSK); } -llvm::Value *CodeGenFunction::FormResolverCondition( - const TargetMultiVersionResolverOption &RO) { - llvm::Value *TrueCondition = nullptr; - if (!RO.ParsedAttribute.Architecture.empty()) - TrueCondition = EmitX86CpuIs(RO.ParsedAttribute.Architecture); - - if (!RO.ParsedAttribute.Features.empty()) { - SmallVector<StringRef, 8> FeatureList; - llvm::for_each(RO.ParsedAttribute.Features, - [&FeatureList](const std::string &Feature) { - FeatureList.push_back(StringRef{Feature}.substr(1)); - }); - llvm::Value *FeatureCmp = EmitX86CpuSupports(FeatureList); - TrueCondition = TrueCondition ? Builder.CreateAnd(TrueCondition, FeatureCmp) - : FeatureCmp; - } - return TrueCondition; -} - -void CodeGenFunction::EmitTargetMultiVersionResolver( - llvm::Function *Resolver, - ArrayRef<TargetMultiVersionResolverOption> Options) { - assert((getContext().getTargetInfo().getTriple().getArch() == - llvm::Triple::x86 || - getContext().getTargetInfo().getTriple().getArch() == - llvm::Triple::x86_64) && - "Only implemented for x86 targets"); - - // Main function's basic block. - llvm::BasicBlock *CurBlock = createBasicBlock("entry", Resolver); - Builder.SetInsertPoint(CurBlock); - EmitX86CpuInit(); +llvm::Value * +CodeGenFunction::FormResolverCondition(const MultiVersionResolverOption &RO) { + llvm::Value *Condition = nullptr; - llvm::Function *DefaultFunc = nullptr; - for (const TargetMultiVersionResolverOption &RO : Options) { - Builder.SetInsertPoint(CurBlock); - llvm::Value *TrueCondition = FormResolverCondition(RO); + if (!RO.Conditions.Architecture.empty()) + Condition = EmitX86CpuIs(RO.Conditions.Architecture); - if (!TrueCondition) { - DefaultFunc = RO.Function; - } else { - llvm::BasicBlock *RetBlock = createBasicBlock("ro_ret", Resolver); - llvm::IRBuilder<> RetBuilder(RetBlock); - RetBuilder.CreateRet(RO.Function); - CurBlock = createBasicBlock("ro_else", Resolver); - Builder.CreateCondBr(TrueCondition, RetBlock, CurBlock); - } + if (!RO.Conditions.Features.empty()) { + llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Conditions.Features); + Condition = + Condition ? Builder.CreateAnd(Condition, FeatureCond) : FeatureCond; } - - assert(DefaultFunc && "No default version?"); - // Emit return from the 'else-ist' block. - Builder.SetInsertPoint(CurBlock); - Builder.CreateRet(DefaultFunc); + return Condition; } -void CodeGenFunction::EmitCPUDispatchMultiVersionResolver( - llvm::Function *Resolver, - ArrayRef<CPUDispatchMultiVersionResolverOption> Options) { +void CodeGenFunction::EmitMultiVersionResolver( + llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) { assert((getContext().getTargetInfo().getTriple().getArch() == llvm::Triple::x86 || getContext().getTargetInfo().getTriple().getArch() == llvm::Triple::x86_64) && "Only implemented for x86 targets"); - // Main function's basic block. llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver); Builder.SetInsertPoint(CurBlock); EmitX86CpuInit(); - for (const CPUDispatchMultiVersionResolverOption &RO : Options) { + for (const MultiVersionResolverOption &RO : Options) { Builder.SetInsertPoint(CurBlock); + llvm::Value *Condition = FormResolverCondition(RO); - // "generic" case should catch-all. - if (RO.FeatureMask == 0) { + // The 'default' or 'generic' case. + if (!Condition) { + assert(&RO == Options.end() - 1 && + "Default or Generic case must be last"); Builder.CreateRet(RO.Function); return; } + llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver); llvm::IRBuilder<> RetBuilder(RetBlock); RetBuilder.CreateRet(RO.Function); CurBlock = createBasicBlock("resolver_else", Resolver); - llvm::Value *TrueCondition = EmitX86CpuSupports(RO.FeatureMask); - Builder.CreateCondBr(TrueCondition, RetBlock, CurBlock); + Builder.CreateCondBr(Condition, RetBlock, CurBlock); } + // If no generic/default, emit an unreachable. Builder.SetInsertPoint(CurBlock); llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); TrapCall->setDoesNotReturn(); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 878923a85bdf..d374f3943661 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -4247,30 +4247,26 @@ public: void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK); - struct TargetMultiVersionResolverOption { + struct MultiVersionResolverOption { llvm::Function *Function; - TargetAttr::ParsedTargetAttr ParsedAttribute; - unsigned Priority; - TargetMultiVersionResolverOption( - const TargetInfo &TargInfo, llvm::Function *F, - const clang::TargetAttr::ParsedTargetAttr &PT) - : Function(F), ParsedAttribute(PT), Priority(0u) { - for (StringRef Feat : PT.Features) - Priority = std::max(Priority, - TargInfo.multiVersionSortPriority(Feat.substr(1))); - - if (!PT.Architecture.empty()) - Priority = std::max(Priority, - TargInfo.multiVersionSortPriority(PT.Architecture)); - } + struct Conds { + StringRef Architecture; + llvm::SmallVector<StringRef, 8> Features; - bool operator>(const TargetMultiVersionResolverOption &Other) const { - return Priority > Other.Priority; - } + Conds(StringRef Arch, ArrayRef<StringRef> Feats) + : Architecture(Arch), Features(Feats.begin(), Feats.end()) {} + } Conditions; + + MultiVersionResolverOption(llvm::Function *F, StringRef Arch, + ArrayRef<StringRef> Feats) + : Function(F), Conditions(Arch, Feats) {} }; - void EmitTargetMultiVersionResolver( - llvm::Function *Resolver, - ArrayRef<TargetMultiVersionResolverOption> Options); + + // Emits the body of a multiversion function's resolver. Assumes that the + // options are already sorted in the proper order, with the 'default' option + // last (if it exists). + void EmitMultiVersionResolver(llvm::Function *Resolver, + ArrayRef<MultiVersionResolverOption> Options); struct CPUDispatchMultiVersionResolverOption { llvm::Function *Function; @@ -4306,8 +4302,7 @@ private: llvm::Value *EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs); llvm::Value *EmitX86CpuSupports(uint32_t Mask); llvm::Value *EmitX86CpuInit(); - llvm::Value * - FormResolverCondition(const TargetMultiVersionResolverOption &RO); + llvm::Value *FormResolverCondition(const MultiVersionResolverOption &RO); }; inline DominatingLLVMValue::saved_type diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 76112e191c71..3e33735c5040 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -2399,9 +2399,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) { @@ -2422,8 +2435,13 @@ 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>( @@ -2431,11 +2449,16 @@ void CodeGenModule::emitMultiVersionFunctions() { if (supportsCOMDAT()) ResolverFunc->setComdat( getModule().getOrInsertComdat(ResolverFunc->getName())); + + const TargetInfo &TI = getTarget(); 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); } } @@ -2444,7 +2467,13 @@ 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( @@ -2455,15 +2484,14 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { GetOrCreateLLVMFunction(ResolverName, ResolverType, GlobalDecl{}, /*ForVTable=*/false)); - SmallVector<CodeGenFunction::CPUDispatchMultiVersionResolverOption, 10> - Options; + SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options; const TargetInfo &Target = getTarget(); 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, + MangledName, DeclTy, GD, /*ForVTable=*/false, /*DontDefer=*/true, /*IsThunk=*/false, llvm::AttributeList(), ForDefinition); llvm::SmallVector<StringRef, 32> Features; Target.getCPUSpecificCPUDispatchFeatures(II->getName(), Features); @@ -2473,15 +2501,34 @@ 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); } llvm::sort( Options.begin(), Options.end(), - std::greater<CodeGenFunction::CPUDispatchMultiVersionResolverOption>()); + [](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 diff --git a/lib/Driver/ToolChains/OpenBSD.cpp b/lib/Driver/ToolChains/OpenBSD.cpp index 7b98cd62bbfc..432f6079e387 100644 --- a/lib/Driver/ToolChains/OpenBSD.cpp +++ b/lib/Driver/ToolChains/OpenBSD.cpp @@ -138,7 +138,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_pie)) CmdArgs.push_back("-pie"); - if (Args.hasArg(options::OPT_nopie)) + if (Args.hasArg(options::OPT_nopie) || Args.hasArg(options::OPT_pg)) CmdArgs.push_back("-nopie"); if (Output.isFilename()) { diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 62c54fc956a9..da9dd3406e14 100644 --- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -475,9 +475,6 @@ static Optional<NonLoc> tryRearrange(ProgramStateRef State, SingleTy = ResultTy; if (LSym->getType() != SingleTy) return None; - // Substracting unsigned integers is a nightmare. - if (!SingleTy->isSignedIntegerOrEnumerationType()) - return None; } else { // Don't rearrange other operations. return None; @@ -485,6 +482,10 @@ static Optional<NonLoc> tryRearrange(ProgramStateRef State, assert(!SingleTy.isNull() && "We should have figured out the type by now!"); + // Rearrange signed symbolic expressions only + if (!SingleTy->isSignedIntegerOrEnumerationType()) + return None; + SymbolRef RSym = Rhs.getAsSymbol(); if (!RSym || RSym->getType() != SingleTy) return None; |