blob: 058a601c7f3b9427a6e7cc81a06ccc1baa83ebb7 [file] [log] [blame]
Teresa Johnson2d5487c2016-04-11 13:58:45 +00001//===- ModuleSummaryAnalysis.cpp - Module summary index builder -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This pass builds a ModuleSummaryIndex object for the module, to be written
11// to bitcode or LLVM assembly.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/Analysis/ModuleSummaryAnalysis.h"
Peter Collingbourne0c30f082016-12-20 21:12:28 +000016#include "llvm/ADT/MapVector.h"
17#include "llvm/ADT/SetVector.h"
Teresa Johnson3624bdf2016-11-14 17:12:32 +000018#include "llvm/ADT/Triple.h"
Teresa Johnson2d5487c2016-04-11 13:58:45 +000019#include "llvm/Analysis/BlockFrequencyInfo.h"
20#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
21#include "llvm/Analysis/BranchProbabilityInfo.h"
Teresa Johnsoncd21a642016-07-17 14:47:01 +000022#include "llvm/Analysis/IndirectCallPromotionAnalysis.h"
Teresa Johnson2d5487c2016-04-11 13:58:45 +000023#include "llvm/Analysis/LoopInfo.h"
Piotr Padlewskid9830eb2016-09-26 20:37:32 +000024#include "llvm/Analysis/ProfileSummaryInfo.h"
Peter Collingbourne1b4137a72016-12-21 23:03:45 +000025#include "llvm/Analysis/TypeMetadataUtils.h"
Teresa Johnson2d5487c2016-04-11 13:58:45 +000026#include "llvm/IR/CallSite.h"
27#include "llvm/IR/Dominators.h"
Teresa Johnsondf5ef872016-04-27 14:19:38 +000028#include "llvm/IR/InstIterator.h"
Teresa Johnson2d5487c2016-04-11 13:58:45 +000029#include "llvm/IR/IntrinsicInst.h"
30#include "llvm/IR/ValueSymbolTable.h"
Teresa Johnson3624bdf2016-11-14 17:12:32 +000031#include "llvm/Object/IRObjectFile.h"
Teresa Johnson2d5487c2016-04-11 13:58:45 +000032#include "llvm/Pass.h"
33using namespace llvm;
34
35#define DEBUG_TYPE "module-summary-analysis"
36
37// Walk through the operands of a given User via worklist iteration and populate
38// the set of GlobalValue references encountered. Invoked either on an
39// Instruction or a GlobalVariable (which walks its initializer).
Peter Collingbourne0c30f082016-12-20 21:12:28 +000040static void findRefEdges(const User *CurUser, SetVector<ValueInfo> &RefEdges,
Teresa Johnson2d5487c2016-04-11 13:58:45 +000041 SmallPtrSet<const User *, 8> &Visited) {
42 SmallVector<const User *, 32> Worklist;
43 Worklist.push_back(CurUser);
44
45 while (!Worklist.empty()) {
46 const User *U = Worklist.pop_back_val();
47
48 if (!Visited.insert(U).second)
49 continue;
50
51 ImmutableCallSite CS(U);
52
53 for (const auto &OI : U->operands()) {
54 const User *Operand = dyn_cast<User>(OI);
55 if (!Operand)
56 continue;
57 if (isa<BlockAddress>(Operand))
58 continue;
Peter Collingbourne0c30f082016-12-20 21:12:28 +000059 if (auto *GV = dyn_cast<GlobalValue>(Operand)) {
Teresa Johnson2d5487c2016-04-11 13:58:45 +000060 // We have a reference to a global value. This should be added to
61 // the reference set unless it is a callee. Callees are handled
62 // specially by WriteFunction and are added to a separate list.
63 if (!(CS && CS.isCallee(&OI)))
Peter Collingbourne0c30f082016-12-20 21:12:28 +000064 RefEdges.insert(GV);
Teresa Johnson2d5487c2016-04-11 13:58:45 +000065 continue;
66 }
67 Worklist.push_back(Operand);
68 }
69 }
70}
71
Piotr Padlewskid9830eb2016-09-26 20:37:32 +000072static CalleeInfo::HotnessType getHotness(uint64_t ProfileCount,
73 ProfileSummaryInfo *PSI) {
74 if (!PSI)
75 return CalleeInfo::HotnessType::Unknown;
76 if (PSI->isHotCount(ProfileCount))
77 return CalleeInfo::HotnessType::Hot;
78 if (PSI->isColdCount(ProfileCount))
79 return CalleeInfo::HotnessType::Cold;
80 return CalleeInfo::HotnessType::None;
81}
82
Teresa Johnson519465b2017-01-05 14:32:16 +000083static bool isNonRenamableLocal(const GlobalValue &GV) {
84 return GV.hasSection() && GV.hasLocalLinkage();
85}
86
87static void
88computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
89 const Function &F, BlockFrequencyInfo *BFI,
90 ProfileSummaryInfo *PSI, bool HasLocalsInUsed,
Teresa Johnsone27b0582017-01-05 14:59:56 +000091 DenseSet<GlobalValue::GUID> &CantBePromoted) {
Teresa Johnson02563cd2016-10-28 02:39:38 +000092 // Summary not currently supported for anonymous functions, they should
93 // have been named.
94 assert(F.hasName());
Teresa Johnson2d5487c2016-04-11 13:58:45 +000095
96 unsigned NumInsts = 0;
97 // Map from callee ValueId to profile count. Used to accumulate profile
98 // counts for all static calls to a given callee.
Peter Collingbourne0c30f082016-12-20 21:12:28 +000099 MapVector<ValueInfo, CalleeInfo> CallGraphEdges;
100 SetVector<ValueInfo> RefEdges;
Peter Collingbourne1b4137a72016-12-21 23:03:45 +0000101 SetVector<GlobalValue::GUID> TypeTests;
Teresa Johnsoncd21a642016-07-17 14:47:01 +0000102 ICallPromotionAnalysis ICallAnalysis;
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000103
Teresa Johnsond5033a42016-11-14 16:40:19 +0000104 bool HasInlineAsmMaybeReferencingInternal = false;
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000105 SmallPtrSet<const User *, 8> Visited;
Benjamin Krameraa209152016-06-26 17:27:42 +0000106 for (const BasicBlock &BB : F)
107 for (const Instruction &I : BB) {
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000108 if (isa<DbgInfoIntrinsic>(I))
109 continue;
110 ++NumInsts;
Benjamin Krameraa209152016-06-26 17:27:42 +0000111 findRefEdges(&I, RefEdges, Visited);
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000112 auto CS = ImmutableCallSite(&I);
113 if (!CS)
114 continue;
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000115
116 const auto *CI = dyn_cast<CallInst>(&I);
117 // Since we don't know exactly which local values are referenced in inline
Teresa Johnsond5033a42016-11-14 16:40:19 +0000118 // assembly, conservatively mark the function as possibly referencing
119 // a local value from inline assembly to ensure we don't export a
120 // reference (which would require renaming and promotion of the
121 // referenced value).
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000122 if (HasLocalsInUsed && CI && CI->isInlineAsm())
Teresa Johnsond5033a42016-11-14 16:40:19 +0000123 HasInlineAsmMaybeReferencingInternal = true;
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000124
Teresa Johnson897bab92016-10-08 16:11:42 +0000125 auto *CalledValue = CS.getCalledValue();
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000126 auto *CalledFunction = CS.getCalledFunction();
Teresa Johnson897bab92016-10-08 16:11:42 +0000127 // Check if this is an alias to a function. If so, get the
128 // called aliasee for the checks below.
129 if (auto *GA = dyn_cast<GlobalAlias>(CalledValue)) {
130 assert(!CalledFunction && "Expected null called function in callsite for alias");
131 CalledFunction = dyn_cast<Function>(GA->getBaseObject());
132 }
Peter Collingbourne1b4137a72016-12-21 23:03:45 +0000133 // Check if this is a direct call to a known function or a known
134 // intrinsic, or an indirect call with profile data.
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000135 if (CalledFunction) {
Peter Collingbourne1b4137a72016-12-21 23:03:45 +0000136 if (CalledFunction->isIntrinsic()) {
137 if (CalledFunction->getIntrinsicID() != Intrinsic::type_test)
138 continue;
139 // Produce a summary from type.test intrinsics. We only summarize
140 // type.test intrinsics that are used other than by an llvm.assume
141 // intrinsic. Intrinsics that are assumed are relevant only to the
142 // devirtualization pass, not the type test lowering pass.
143 bool HasNonAssumeUses = llvm::any_of(CI->uses(), [](const Use &CIU) {
144 auto *AssumeCI = dyn_cast<CallInst>(CIU.getUser());
145 if (!AssumeCI)
146 return true;
147 Function *F = AssumeCI->getCalledFunction();
148 return !F || F->getIntrinsicID() != Intrinsic::assume;
149 });
150 if (HasNonAssumeUses) {
151 auto *TypeMDVal = cast<MetadataAsValue>(CI->getArgOperand(1));
152 if (auto *TypeId = dyn_cast<MDString>(TypeMDVal->getMetadata()))
153 TypeTests.insert(GlobalValue::getGUID(TypeId->getString()));
154 }
155 }
Teresa Johnson02563cd2016-10-28 02:39:38 +0000156 // We should have named any anonymous globals
157 assert(CalledFunction->hasName());
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000158 auto ScaledCount = BFI ? BFI->getBlockProfileCount(&BB) : None;
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000159 auto Hotness = ScaledCount ? getHotness(ScaledCount.getValue(), PSI)
160 : CalleeInfo::HotnessType::Unknown;
161
Teresa Johnson897bab92016-10-08 16:11:42 +0000162 // Use the original CalledValue, in case it was an alias. We want
163 // to record the call edge to the alias in that case. Eventually
164 // an alias summary will be created to associate the alias and
165 // aliasee.
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000166 CallGraphEdges[cast<GlobalValue>(CalledValue)].updateHotness(Hotness);
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000167 } else {
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000168 // Skip inline assembly calls.
169 if (CI && CI->isInlineAsm())
170 continue;
171 // Skip direct calls.
172 if (!CS.getCalledValue() || isa<Constant>(CS.getCalledValue()))
173 continue;
174
175 uint32_t NumVals, NumCandidates;
176 uint64_t TotalCount;
177 auto CandidateProfileData =
178 ICallAnalysis.getPromotionCandidatesForInstruction(
179 &I, NumVals, TotalCount, NumCandidates);
180 for (auto &Candidate : CandidateProfileData)
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000181 CallGraphEdges[Candidate.Value].updateHotness(
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000182 getHotness(Candidate.Count, PSI));
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000183 }
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000184 }
185
Teresa Johnson519465b2017-01-05 14:32:16 +0000186 bool NonRenamableLocal = isNonRenamableLocal(F);
187 bool NotEligibleForImport =
188 NonRenamableLocal || HasInlineAsmMaybeReferencingInternal ||
189 // Inliner doesn't handle variadic functions.
190 // FIXME: refactor this to use the same code that inliner is using.
191 F.isVarArg();
192 GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport);
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000193 auto FuncSummary = llvm::make_unique<FunctionSummary>(
Peter Collingbourne1b4137a72016-12-21 23:03:45 +0000194 Flags, NumInsts, RefEdges.takeVector(), CallGraphEdges.takeVector(),
195 TypeTests.takeVector());
Teresa Johnson519465b2017-01-05 14:32:16 +0000196 if (NonRenamableLocal)
197 CantBePromoted.insert(F.getGUID());
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000198 Index.addGlobalValueSummary(F.getName(), std::move(FuncSummary));
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000199}
200
Teresa Johnson519465b2017-01-05 14:32:16 +0000201static void
202computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V,
Teresa Johnsone27b0582017-01-05 14:59:56 +0000203 DenseSet<GlobalValue::GUID> &CantBePromoted) {
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000204 SetVector<ValueInfo> RefEdges;
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000205 SmallPtrSet<const User *, 8> Visited;
206 findRefEdges(&V, RefEdges, Visited);
Teresa Johnson519465b2017-01-05 14:32:16 +0000207 bool NonRenamableLocal = isNonRenamableLocal(V);
208 GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal);
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000209 auto GVarSummary =
210 llvm::make_unique<GlobalVarSummary>(Flags, RefEdges.takeVector());
Teresa Johnson519465b2017-01-05 14:32:16 +0000211 if (NonRenamableLocal)
212 CantBePromoted.insert(V.getGUID());
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000213 Index.addGlobalValueSummary(V.getName(), std::move(GVarSummary));
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000214}
215
Teresa Johnson519465b2017-01-05 14:32:16 +0000216static void
217computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
Teresa Johnsone27b0582017-01-05 14:59:56 +0000218 DenseSet<GlobalValue::GUID> &CantBePromoted) {
Teresa Johnson519465b2017-01-05 14:32:16 +0000219 bool NonRenamableLocal = isNonRenamableLocal(A);
220 GlobalValueSummary::GVFlags Flags(A.getLinkage(), NonRenamableLocal);
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000221 auto AS = llvm::make_unique<AliasSummary>(Flags, ArrayRef<ValueInfo>{});
Teresa Johnson02563cd2016-10-28 02:39:38 +0000222 auto *Aliasee = A.getBaseObject();
223 auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee);
224 assert(AliaseeSummary && "Alias expects aliasee summary to be parsed");
225 AS->setAliasee(AliaseeSummary);
Teresa Johnson519465b2017-01-05 14:32:16 +0000226 if (NonRenamableLocal)
227 CantBePromoted.insert(A.getGUID());
Teresa Johnson02563cd2016-10-28 02:39:38 +0000228 Index.addGlobalValueSummary(A.getName(), std::move(AS));
229}
230
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000231ModuleSummaryIndex llvm::buildModuleSummaryIndex(
232 const Module &M,
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000233 std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback,
234 ProfileSummaryInfo *PSI) {
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000235 ModuleSummaryIndex Index;
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000236
Teresa Johnsona0811452016-11-10 16:57:32 +0000237 // Identify the local values in the llvm.used and llvm.compiler.used sets,
238 // which should not be exported as they would then require renaming and
239 // promotion, but we may have opaque uses e.g. in inline asm. We collect them
240 // here because we use this information to mark functions containing inline
241 // assembly calls as not importable.
Mehdi Aminib6a11a72016-11-09 01:45:13 +0000242 SmallPtrSet<GlobalValue *, 8> LocalsUsed;
Teresa Johnsona0811452016-11-10 16:57:32 +0000243 SmallPtrSet<GlobalValue *, 8> Used;
244 // First collect those in the llvm.used set.
245 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
Teresa Johnsona0811452016-11-10 16:57:32 +0000246 // Next collect those in the llvm.compiler.used set.
247 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ true);
Teresa Johnsone27b0582017-01-05 14:59:56 +0000248 DenseSet<GlobalValue::GUID> CantBePromoted;
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000249 for (auto *V : Used) {
Teresa Johnson519465b2017-01-05 14:32:16 +0000250 if (V->hasLocalLinkage()) {
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000251 LocalsUsed.insert(V);
Teresa Johnson519465b2017-01-05 14:32:16 +0000252 CantBePromoted.insert(V->getGUID());
253 }
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000254 }
Teresa Johnsonb35cc692016-04-20 14:39:45 +0000255
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000256 // Compute summaries for all functions defined in module, and save in the
257 // index.
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000258 for (auto &F : M) {
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000259 if (F.isDeclaration())
260 continue;
261
262 BlockFrequencyInfo *BFI = nullptr;
263 std::unique_ptr<BlockFrequencyInfo> BFIPtr;
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000264 if (GetBFICallback)
265 BFI = GetBFICallback(F);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000266 else if (F.getEntryCount().hasValue()) {
267 LoopInfo LI{DominatorTree(const_cast<Function &>(F))};
268 BranchProbabilityInfo BPI{F, LI};
269 BFIPtr = llvm::make_unique<BlockFrequencyInfo>(F, BPI, LI);
270 BFI = BFIPtr.get();
271 }
272
Teresa Johnson519465b2017-01-05 14:32:16 +0000273 computeFunctionSummary(Index, M, F, BFI, PSI, !LocalsUsed.empty(),
274 CantBePromoted);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000275 }
276
277 // Compute summaries for all variables defined in module, and save in the
278 // index.
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000279 for (const GlobalVariable &G : M.globals()) {
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000280 if (G.isDeclaration())
281 continue;
Teresa Johnson519465b2017-01-05 14:32:16 +0000282 computeVariableSummary(Index, G, CantBePromoted);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000283 }
Teresa Johnson02563cd2016-10-28 02:39:38 +0000284
285 // Compute summaries for all aliases defined in module, and save in the
286 // index.
287 for (const GlobalAlias &A : M.aliases())
Teresa Johnson519465b2017-01-05 14:32:16 +0000288 computeAliasSummary(Index, A, CantBePromoted);
Teresa Johnson02563cd2016-10-28 02:39:38 +0000289
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000290 for (auto *V : LocalsUsed) {
291 auto *Summary = Index.getGlobalValueSummary(*V);
292 assert(Summary && "Missing summary for global value");
Teresa Johnson519465b2017-01-05 14:32:16 +0000293 Summary->setNotEligibleToImport();
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000294 }
295
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000296 if (!M.getModuleInlineAsm().empty()) {
297 // Collect the local values defined by module level asm, and set up
298 // summaries for these symbols so that they can be marked as NoRename,
299 // to prevent export of any use of them in regular IR that would require
300 // renaming within the module level asm. Note we don't need to create a
301 // summary for weak or global defs, as they don't need to be flagged as
302 // NoRename, and defs in module level asm can't be imported anyway.
303 // Also, any values used but not defined within module level asm should
304 // be listed on the llvm.used or llvm.compiler.used global and marked as
305 // referenced from there.
Peter Collingbourne863cbfb2016-12-01 06:51:47 +0000306 ModuleSymbolTable::CollectAsmSymbols(
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000307 Triple(M.getTargetTriple()), M.getModuleInlineAsm(),
Teresa Johnson519465b2017-01-05 14:32:16 +0000308 [&M, &Index, &CantBePromoted](StringRef Name,
309 object::BasicSymbolRef::Flags Flags) {
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000310 // Symbols not marked as Weak or Global are local definitions.
Teresa Johnsone0ee5cf2016-12-27 17:45:09 +0000311 if (Flags & (object::BasicSymbolRef::SF_Weak |
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000312 object::BasicSymbolRef::SF_Global))
313 return;
314 GlobalValue *GV = M.getNamedValue(Name);
315 if (!GV)
316 return;
317 assert(GV->isDeclaration() && "Def in module asm already has definition");
Teresa Johnson519465b2017-01-05 14:32:16 +0000318 GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage,
319 /* NotEligibleToImport */ true);
320 CantBePromoted.insert(GlobalValue::getGUID(Name));
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000321 // Create the appropriate summary type.
322 if (isa<Function>(GV)) {
323 std::unique_ptr<FunctionSummary> Summary =
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000324 llvm::make_unique<FunctionSummary>(
325 GVFlags, 0, ArrayRef<ValueInfo>{},
Peter Collingbourne1b4137a72016-12-21 23:03:45 +0000326 ArrayRef<FunctionSummary::EdgeTy>{},
327 ArrayRef<GlobalValue::GUID>{});
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000328 Index.addGlobalValueSummary(Name, std::move(Summary));
329 } else {
330 std::unique_ptr<GlobalVarSummary> Summary =
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000331 llvm::make_unique<GlobalVarSummary>(GVFlags,
332 ArrayRef<ValueInfo>{});
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000333 Index.addGlobalValueSummary(Name, std::move(Summary));
334 }
335 });
336 }
337
Teresa Johnson519465b2017-01-05 14:32:16 +0000338 for (auto &GlobalList : Index) {
339 assert(GlobalList.second.size() == 1 &&
340 "Expected module's index to have one summary per GUID");
341 auto &Summary = GlobalList.second[0];
342 bool AllRefsCanBeExternallyReferenced =
343 llvm::all_of(Summary->refs(), [&](const ValueInfo &VI) {
344 return !CantBePromoted.count(VI.getValue()->getGUID());
345 });
346 if (!AllRefsCanBeExternallyReferenced) {
347 Summary->setNotEligibleToImport();
348 continue;
349 }
350
351 if (auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) {
352 bool AllCallsCanBeExternallyReferenced = llvm::all_of(
353 FuncSummary->calls(), [&](const FunctionSummary::EdgeTy &Edge) {
354 auto GUID = Edge.first.isGUID() ? Edge.first.getGUID()
355 : Edge.first.getValue()->getGUID();
356 return !CantBePromoted.count(GUID);
357 });
358 if (!AllCallsCanBeExternallyReferenced)
359 Summary->setNotEligibleToImport();
360 }
361 }
362
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000363 return Index;
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000364}
365
Chandler Carruthdab4eae2016-11-23 17:53:26 +0000366AnalysisKey ModuleSummaryIndexAnalysis::Key;
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000367
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000368ModuleSummaryIndex
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000369ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000370 ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000371 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000372 return buildModuleSummaryIndex(
373 M,
374 [&FAM](const Function &F) {
375 return &FAM.getResult<BlockFrequencyAnalysis>(
376 *const_cast<Function *>(&F));
377 },
378 &PSI);
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000379}
380
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000381char ModuleSummaryIndexWrapperPass::ID = 0;
382INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
383 "Module Summary Analysis", false, true)
384INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
385INITIALIZE_PASS_END(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
386 "Module Summary Analysis", false, true)
387
388ModulePass *llvm::createModuleSummaryIndexWrapperPass() {
389 return new ModuleSummaryIndexWrapperPass();
390}
391
392ModuleSummaryIndexWrapperPass::ModuleSummaryIndexWrapperPass()
393 : ModulePass(ID) {
394 initializeModuleSummaryIndexWrapperPassPass(*PassRegistry::getPassRegistry());
395}
396
397bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) {
Dehao Chen5461d8b2016-09-28 21:00:58 +0000398 auto &PSI = *getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000399 Index = buildModuleSummaryIndex(
400 M,
401 [this](const Function &F) {
402 return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>(
403 *const_cast<Function *>(&F))
404 .getBFI());
405 },
406 &PSI);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000407 return false;
408}
409
410bool ModuleSummaryIndexWrapperPass::doFinalization(Module &M) {
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000411 Index.reset();
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000412 return false;
413}
414
415void ModuleSummaryIndexWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
416 AU.setPreservesAll();
417 AU.addRequired<BlockFrequencyInfoWrapperPass>();
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000418 AU.addRequired<ProfileSummaryInfoWrapperPass>();
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000419}