diff options
author | Teresa Johnson <tejohnson@google.com> | 2017-01-05 14:32:16 +0000 |
---|---|---|
committer | Teresa Johnson <tejohnson@google.com> | 2017-01-05 14:32:16 +0000 |
commit | 519465b993268b5b07b676a5224d858169507f1b (patch) | |
tree | b9f2413824b261668e8eae7b532765adcdd72fbe /llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | |
parent | 337139830e14dacd3b511cc180475ec277638a09 (diff) | |
download | llvm-519465b993268b5b07b676a5224d858169507f1b.zip llvm-519465b993268b5b07b676a5224d858169507f1b.tar.gz llvm-519465b993268b5b07b676a5224d858169507f1b.tar.bz2 |
[ThinLTO] Subsume all importing checks into a single flag
Summary:
This adds a new summary flag NotEligibleToImport that subsumes
several existing flags (NoRename, HasInlineAsmMaybeReferencingInternal
and IsNotViableToInline). It also subsumes the checking of references
on the summary that was being done during the thin link by
eligibleForImport() for each candidate. It is much more efficient to
do that checking once during the per-module summary build and record
it in the summary.
Reviewers: mehdi_amini
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D28169
llvm-svn: 291108
Diffstat (limited to 'llvm/lib/Analysis/ModuleSummaryAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 97 |
1 files changed, 71 insertions, 26 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp index 1d2ffc1..2854691 100644 --- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -80,10 +80,15 @@ static CalleeInfo::HotnessType getHotness(uint64_t ProfileCount, return CalleeInfo::HotnessType::None; } -static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, - const Function &F, BlockFrequencyInfo *BFI, - ProfileSummaryInfo *PSI, - bool HasLocalsInUsed) { +static bool isNonRenamableLocal(const GlobalValue &GV) { + return GV.hasSection() && GV.hasLocalLinkage(); +} + +static void +computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, + const Function &F, BlockFrequencyInfo *BFI, + ProfileSummaryInfo *PSI, bool HasLocalsInUsed, + SmallPtrSet<GlobalValue::GUID, 8> &CantBePromoted) { // Summary not currently supported for anonymous functions, they should // have been named. assert(F.hasName()); @@ -178,34 +183,48 @@ static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, } } - GlobalValueSummary::GVFlags Flags(F); + bool NonRenamableLocal = isNonRenamableLocal(F); + bool NotEligibleForImport = + NonRenamableLocal || HasInlineAsmMaybeReferencingInternal || + // Inliner doesn't handle variadic functions. + // FIXME: refactor this to use the same code that inliner is using. + F.isVarArg(); + GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport); auto FuncSummary = llvm::make_unique<FunctionSummary>( Flags, NumInsts, RefEdges.takeVector(), CallGraphEdges.takeVector(), TypeTests.takeVector()); - if (HasInlineAsmMaybeReferencingInternal) - FuncSummary->setHasInlineAsmMaybeReferencingInternal(); + if (NonRenamableLocal) + CantBePromoted.insert(F.getGUID()); Index.addGlobalValueSummary(F.getName(), std::move(FuncSummary)); } -static void computeVariableSummary(ModuleSummaryIndex &Index, - const GlobalVariable &V) { +static void +computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V, + SmallPtrSet<GlobalValue::GUID, 8> &CantBePromoted) { SetVector<ValueInfo> RefEdges; SmallPtrSet<const User *, 8> Visited; findRefEdges(&V, RefEdges, Visited); - GlobalValueSummary::GVFlags Flags(V); + bool NonRenamableLocal = isNonRenamableLocal(V); + GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal); auto GVarSummary = llvm::make_unique<GlobalVarSummary>(Flags, RefEdges.takeVector()); + if (NonRenamableLocal) + CantBePromoted.insert(V.getGUID()); Index.addGlobalValueSummary(V.getName(), std::move(GVarSummary)); } -static void computeAliasSummary(ModuleSummaryIndex &Index, - const GlobalAlias &A) { - GlobalValueSummary::GVFlags Flags(A); +static void +computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A, + SmallPtrSet<GlobalValue::GUID, 8> &CantBePromoted) { + bool NonRenamableLocal = isNonRenamableLocal(A); + GlobalValueSummary::GVFlags Flags(A.getLinkage(), NonRenamableLocal); auto AS = llvm::make_unique<AliasSummary>(Flags, ArrayRef<ValueInfo>{}); auto *Aliasee = A.getBaseObject(); auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee); assert(AliaseeSummary && "Alias expects aliasee summary to be parsed"); AS->setAliasee(AliaseeSummary); + if (NonRenamableLocal) + CantBePromoted.insert(A.getGUID()); Index.addGlobalValueSummary(A.getName(), std::move(AS)); } @@ -226,9 +245,12 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); // Next collect those in the llvm.compiler.used set. collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ true); + SmallPtrSet<GlobalValue::GUID, 8> CantBePromoted; for (auto *V : Used) { - if (V->hasLocalLinkage()) + if (V->hasLocalLinkage()) { LocalsUsed.insert(V); + CantBePromoted.insert(V->getGUID()); + } } // Compute summaries for all functions defined in module, and save in the @@ -248,7 +270,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( BFI = BFIPtr.get(); } - computeFunctionSummary(Index, M, F, BFI, PSI, !LocalsUsed.empty()); + computeFunctionSummary(Index, M, F, BFI, PSI, !LocalsUsed.empty(), + CantBePromoted); } // Compute summaries for all variables defined in module, and save in the @@ -256,18 +279,18 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( for (const GlobalVariable &G : M.globals()) { if (G.isDeclaration()) continue; - computeVariableSummary(Index, G); + computeVariableSummary(Index, G, CantBePromoted); } // Compute summaries for all aliases defined in module, and save in the // index. for (const GlobalAlias &A : M.aliases()) - computeAliasSummary(Index, A); + computeAliasSummary(Index, A, CantBePromoted); for (auto *V : LocalsUsed) { auto *Summary = Index.getGlobalValueSummary(*V); assert(Summary && "Missing summary for global value"); - Summary->setNoRename(); + Summary->setNotEligibleToImport(); } if (!M.getModuleInlineAsm().empty()) { @@ -282,7 +305,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( // referenced from there. ModuleSymbolTable::CollectAsmSymbols( Triple(M.getTargetTriple()), M.getModuleInlineAsm(), - [&M, &Index](StringRef Name, object::BasicSymbolRef::Flags Flags) { + [&M, &Index, &CantBePromoted](StringRef Name, + object::BasicSymbolRef::Flags Flags) { // Symbols not marked as Weak or Global are local definitions. if (Flags & (object::BasicSymbolRef::SF_Weak | object::BasicSymbolRef::SF_Global)) @@ -291,11 +315,9 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( if (!GV) return; assert(GV->isDeclaration() && "Def in module asm already has definition"); - GlobalValueSummary::GVFlags GVFlags( - GlobalValue::InternalLinkage, - /* NoRename */ true, - /* HasInlineAsmMaybeReferencingInternal */ false, - /* IsNotViableToInline */ true); + GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage, + /* NotEligibleToImport */ true); + CantBePromoted.insert(GlobalValue::getGUID(Name)); // Create the appropriate summary type. if (isa<Function>(GV)) { std::unique_ptr<FunctionSummary> Summary = @@ -303,18 +325,41 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( GVFlags, 0, ArrayRef<ValueInfo>{}, ArrayRef<FunctionSummary::EdgeTy>{}, ArrayRef<GlobalValue::GUID>{}); - Summary->setNoRename(); Index.addGlobalValueSummary(Name, std::move(Summary)); } else { std::unique_ptr<GlobalVarSummary> Summary = llvm::make_unique<GlobalVarSummary>(GVFlags, ArrayRef<ValueInfo>{}); - Summary->setNoRename(); Index.addGlobalValueSummary(Name, std::move(Summary)); } }); } + for (auto &GlobalList : Index) { + assert(GlobalList.second.size() == 1 && + "Expected module's index to have one summary per GUID"); + auto &Summary = GlobalList.second[0]; + bool AllRefsCanBeExternallyReferenced = + llvm::all_of(Summary->refs(), [&](const ValueInfo &VI) { + return !CantBePromoted.count(VI.getValue()->getGUID()); + }); + if (!AllRefsCanBeExternallyReferenced) { + Summary->setNotEligibleToImport(); + continue; + } + + if (auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) { + bool AllCallsCanBeExternallyReferenced = llvm::all_of( + FuncSummary->calls(), [&](const FunctionSummary::EdgeTy &Edge) { + auto GUID = Edge.first.isGUID() ? Edge.first.getGUID() + : Edge.first.getValue()->getGUID(); + return !CantBePromoted.count(GUID); + }); + if (!AllCallsCanBeExternallyReferenced) + Summary->setNotEligibleToImport(); + } + } + return Index; } |