blob: 0227eab0edeb43fb5a44bfb48589140c3caa34cf [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();
Teresa Johnson6c475a72017-01-05 21:34:18 +0000192 GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport,
Mehdi Aminib0a8ff72017-02-03 00:32:38 +0000193 /* LiveRoot = */ false,
194 /* AutoHide */ false);
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000195 auto FuncSummary = llvm::make_unique<FunctionSummary>(
Peter Collingbourne1b4137a72016-12-21 23:03:45 +0000196 Flags, NumInsts, RefEdges.takeVector(), CallGraphEdges.takeVector(),
197 TypeTests.takeVector());
Teresa Johnson519465b2017-01-05 14:32:16 +0000198 if (NonRenamableLocal)
199 CantBePromoted.insert(F.getGUID());
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000200 Index.addGlobalValueSummary(F.getName(), std::move(FuncSummary));
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000201}
202
Teresa Johnson519465b2017-01-05 14:32:16 +0000203static void
204computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V,
Teresa Johnsone27b0582017-01-05 14:59:56 +0000205 DenseSet<GlobalValue::GUID> &CantBePromoted) {
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000206 SetVector<ValueInfo> RefEdges;
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000207 SmallPtrSet<const User *, 8> Visited;
208 findRefEdges(&V, RefEdges, Visited);
Teresa Johnson519465b2017-01-05 14:32:16 +0000209 bool NonRenamableLocal = isNonRenamableLocal(V);
Teresa Johnson6c475a72017-01-05 21:34:18 +0000210 GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,
Mehdi Aminib0a8ff72017-02-03 00:32:38 +0000211 /* LiveRoot = */ false,
212 /* AutoHide */ false);
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000213 auto GVarSummary =
214 llvm::make_unique<GlobalVarSummary>(Flags, RefEdges.takeVector());
Teresa Johnson519465b2017-01-05 14:32:16 +0000215 if (NonRenamableLocal)
216 CantBePromoted.insert(V.getGUID());
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000217 Index.addGlobalValueSummary(V.getName(), std::move(GVarSummary));
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000218}
219
Teresa Johnson519465b2017-01-05 14:32:16 +0000220static void
221computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
Teresa Johnsone27b0582017-01-05 14:59:56 +0000222 DenseSet<GlobalValue::GUID> &CantBePromoted) {
Teresa Johnson519465b2017-01-05 14:32:16 +0000223 bool NonRenamableLocal = isNonRenamableLocal(A);
Teresa Johnson6c475a72017-01-05 21:34:18 +0000224 GlobalValueSummary::GVFlags Flags(A.getLinkage(), NonRenamableLocal,
Mehdi Aminib0a8ff72017-02-03 00:32:38 +0000225 /* LiveRoot = */ false,
226 /* AutoHide */ false);
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000227 auto AS = llvm::make_unique<AliasSummary>(Flags, ArrayRef<ValueInfo>{});
Teresa Johnson02563cd2016-10-28 02:39:38 +0000228 auto *Aliasee = A.getBaseObject();
229 auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee);
230 assert(AliaseeSummary && "Alias expects aliasee summary to be parsed");
231 AS->setAliasee(AliaseeSummary);
Teresa Johnson519465b2017-01-05 14:32:16 +0000232 if (NonRenamableLocal)
233 CantBePromoted.insert(A.getGUID());
Teresa Johnson02563cd2016-10-28 02:39:38 +0000234 Index.addGlobalValueSummary(A.getName(), std::move(AS));
235}
236
Teresa Johnson6c475a72017-01-05 21:34:18 +0000237// Set LiveRoot flag on entries matching the given value name.
238static void setLiveRoot(ModuleSummaryIndex &Index, StringRef Name) {
239 auto SummaryList =
240 Index.findGlobalValueSummaryList(GlobalValue::getGUID(Name));
241 if (SummaryList == Index.end())
242 return;
243 for (auto &Summary : SummaryList->second)
244 Summary->setLiveRoot();
245}
246
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000247ModuleSummaryIndex llvm::buildModuleSummaryIndex(
248 const Module &M,
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000249 std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback,
250 ProfileSummaryInfo *PSI) {
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000251 ModuleSummaryIndex Index;
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000252
Teresa Johnsona0811452016-11-10 16:57:32 +0000253 // Identify the local values in the llvm.used and llvm.compiler.used sets,
254 // which should not be exported as they would then require renaming and
255 // promotion, but we may have opaque uses e.g. in inline asm. We collect them
256 // here because we use this information to mark functions containing inline
257 // assembly calls as not importable.
Mehdi Aminib6a11a72016-11-09 01:45:13 +0000258 SmallPtrSet<GlobalValue *, 8> LocalsUsed;
Teresa Johnsona0811452016-11-10 16:57:32 +0000259 SmallPtrSet<GlobalValue *, 8> Used;
260 // First collect those in the llvm.used set.
261 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
Teresa Johnsona0811452016-11-10 16:57:32 +0000262 // Next collect those in the llvm.compiler.used set.
263 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ true);
Teresa Johnsone27b0582017-01-05 14:59:56 +0000264 DenseSet<GlobalValue::GUID> CantBePromoted;
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000265 for (auto *V : Used) {
Teresa Johnson519465b2017-01-05 14:32:16 +0000266 if (V->hasLocalLinkage()) {
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000267 LocalsUsed.insert(V);
Teresa Johnson519465b2017-01-05 14:32:16 +0000268 CantBePromoted.insert(V->getGUID());
269 }
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000270 }
Teresa Johnsonb35cc692016-04-20 14:39:45 +0000271
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000272 // Compute summaries for all functions defined in module, and save in the
273 // index.
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000274 for (auto &F : M) {
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000275 if (F.isDeclaration())
276 continue;
277
278 BlockFrequencyInfo *BFI = nullptr;
279 std::unique_ptr<BlockFrequencyInfo> BFIPtr;
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000280 if (GetBFICallback)
281 BFI = GetBFICallback(F);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000282 else if (F.getEntryCount().hasValue()) {
283 LoopInfo LI{DominatorTree(const_cast<Function &>(F))};
284 BranchProbabilityInfo BPI{F, LI};
285 BFIPtr = llvm::make_unique<BlockFrequencyInfo>(F, BPI, LI);
286 BFI = BFIPtr.get();
287 }
288
Teresa Johnson519465b2017-01-05 14:32:16 +0000289 computeFunctionSummary(Index, M, F, BFI, PSI, !LocalsUsed.empty(),
290 CantBePromoted);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000291 }
292
293 // Compute summaries for all variables defined in module, and save in the
294 // index.
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000295 for (const GlobalVariable &G : M.globals()) {
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000296 if (G.isDeclaration())
297 continue;
Teresa Johnson519465b2017-01-05 14:32:16 +0000298 computeVariableSummary(Index, G, CantBePromoted);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000299 }
Teresa Johnson02563cd2016-10-28 02:39:38 +0000300
301 // Compute summaries for all aliases defined in module, and save in the
302 // index.
303 for (const GlobalAlias &A : M.aliases())
Teresa Johnson519465b2017-01-05 14:32:16 +0000304 computeAliasSummary(Index, A, CantBePromoted);
Teresa Johnson02563cd2016-10-28 02:39:38 +0000305
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000306 for (auto *V : LocalsUsed) {
307 auto *Summary = Index.getGlobalValueSummary(*V);
308 assert(Summary && "Missing summary for global value");
Teresa Johnson519465b2017-01-05 14:32:16 +0000309 Summary->setNotEligibleToImport();
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000310 }
311
Teresa Johnson6c475a72017-01-05 21:34:18 +0000312 // The linker doesn't know about these LLVM produced values, so we need
313 // to flag them as live in the index to ensure index-based dead value
314 // analysis treats them as live roots of the analysis.
315 setLiveRoot(Index, "llvm.used");
316 setLiveRoot(Index, "llvm.compiler.used");
317 setLiveRoot(Index, "llvm.global_ctors");
318 setLiveRoot(Index, "llvm.global_dtors");
319 setLiveRoot(Index, "llvm.global.annotations");
320
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000321 if (!M.getModuleInlineAsm().empty()) {
322 // Collect the local values defined by module level asm, and set up
323 // summaries for these symbols so that they can be marked as NoRename,
324 // to prevent export of any use of them in regular IR that would require
325 // renaming within the module level asm. Note we don't need to create a
326 // summary for weak or global defs, as they don't need to be flagged as
327 // NoRename, and defs in module level asm can't be imported anyway.
328 // Also, any values used but not defined within module level asm should
329 // be listed on the llvm.used or llvm.compiler.used global and marked as
330 // referenced from there.
Peter Collingbourne863cbfb2016-12-01 06:51:47 +0000331 ModuleSymbolTable::CollectAsmSymbols(
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000332 Triple(M.getTargetTriple()), M.getModuleInlineAsm(),
Teresa Johnson519465b2017-01-05 14:32:16 +0000333 [&M, &Index, &CantBePromoted](StringRef Name,
334 object::BasicSymbolRef::Flags Flags) {
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000335 // Symbols not marked as Weak or Global are local definitions.
Teresa Johnsone0ee5cf2016-12-27 17:45:09 +0000336 if (Flags & (object::BasicSymbolRef::SF_Weak |
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000337 object::BasicSymbolRef::SF_Global))
338 return;
339 GlobalValue *GV = M.getNamedValue(Name);
340 if (!GV)
341 return;
342 assert(GV->isDeclaration() && "Def in module asm already has definition");
Teresa Johnson519465b2017-01-05 14:32:16 +0000343 GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage,
Teresa Johnson6c475a72017-01-05 21:34:18 +0000344 /* NotEligibleToImport */ true,
Mehdi Aminib0a8ff72017-02-03 00:32:38 +0000345 /* LiveRoot */ true,
346 /* AutoHide */ false);
Teresa Johnson519465b2017-01-05 14:32:16 +0000347 CantBePromoted.insert(GlobalValue::getGUID(Name));
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000348 // Create the appropriate summary type.
349 if (isa<Function>(GV)) {
350 std::unique_ptr<FunctionSummary> Summary =
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000351 llvm::make_unique<FunctionSummary>(
352 GVFlags, 0, ArrayRef<ValueInfo>{},
Peter Collingbourne1b4137a72016-12-21 23:03:45 +0000353 ArrayRef<FunctionSummary::EdgeTy>{},
354 ArrayRef<GlobalValue::GUID>{});
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000355 Index.addGlobalValueSummary(Name, std::move(Summary));
356 } else {
357 std::unique_ptr<GlobalVarSummary> Summary =
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000358 llvm::make_unique<GlobalVarSummary>(GVFlags,
359 ArrayRef<ValueInfo>{});
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000360 Index.addGlobalValueSummary(Name, std::move(Summary));
361 }
362 });
363 }
364
Teresa Johnson519465b2017-01-05 14:32:16 +0000365 for (auto &GlobalList : Index) {
366 assert(GlobalList.second.size() == 1 &&
367 "Expected module's index to have one summary per GUID");
368 auto &Summary = GlobalList.second[0];
369 bool AllRefsCanBeExternallyReferenced =
370 llvm::all_of(Summary->refs(), [&](const ValueInfo &VI) {
371 return !CantBePromoted.count(VI.getValue()->getGUID());
372 });
373 if (!AllRefsCanBeExternallyReferenced) {
374 Summary->setNotEligibleToImport();
375 continue;
376 }
377
378 if (auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) {
379 bool AllCallsCanBeExternallyReferenced = llvm::all_of(
380 FuncSummary->calls(), [&](const FunctionSummary::EdgeTy &Edge) {
381 auto GUID = Edge.first.isGUID() ? Edge.first.getGUID()
382 : Edge.first.getValue()->getGUID();
383 return !CantBePromoted.count(GUID);
384 });
385 if (!AllCallsCanBeExternallyReferenced)
386 Summary->setNotEligibleToImport();
387 }
388 }
389
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000390 return Index;
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000391}
392
Chandler Carruthdab4eae2016-11-23 17:53:26 +0000393AnalysisKey ModuleSummaryIndexAnalysis::Key;
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000394
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000395ModuleSummaryIndex
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000396ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000397 ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000398 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000399 return buildModuleSummaryIndex(
400 M,
401 [&FAM](const Function &F) {
402 return &FAM.getResult<BlockFrequencyAnalysis>(
403 *const_cast<Function *>(&F));
404 },
405 &PSI);
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000406}
407
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000408char ModuleSummaryIndexWrapperPass::ID = 0;
409INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
410 "Module Summary Analysis", false, true)
411INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
Mehdi Amini89029482017-01-21 06:01:22 +0000412INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000413INITIALIZE_PASS_END(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
414 "Module Summary Analysis", false, true)
415
416ModulePass *llvm::createModuleSummaryIndexWrapperPass() {
417 return new ModuleSummaryIndexWrapperPass();
418}
419
420ModuleSummaryIndexWrapperPass::ModuleSummaryIndexWrapperPass()
421 : ModulePass(ID) {
422 initializeModuleSummaryIndexWrapperPassPass(*PassRegistry::getPassRegistry());
423}
424
425bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) {
Dehao Chen5461d8b2016-09-28 21:00:58 +0000426 auto &PSI = *getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000427 Index = buildModuleSummaryIndex(
428 M,
429 [this](const Function &F) {
430 return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>(
431 *const_cast<Function *>(&F))
432 .getBFI());
433 },
434 &PSI);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000435 return false;
436}
437
438bool ModuleSummaryIndexWrapperPass::doFinalization(Module &M) {
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000439 Index.reset();
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000440 return false;
441}
442
443void ModuleSummaryIndexWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
444 AU.setPreservesAll();
445 AU.addRequired<BlockFrequencyInfoWrapperPass>();
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000446 AU.addRequired<ProfileSummaryInfoWrapperPass>();
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000447}