blob: f5ba637e58e20332d465c7562d895a14d56f8014 [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,
193 /* LiveRoot = */ false);
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000194 auto FuncSummary = llvm::make_unique<FunctionSummary>(
Peter Collingbourne1b4137a72016-12-21 23:03:45 +0000195 Flags, NumInsts, RefEdges.takeVector(), CallGraphEdges.takeVector(),
196 TypeTests.takeVector());
Teresa Johnson519465b2017-01-05 14:32:16 +0000197 if (NonRenamableLocal)
198 CantBePromoted.insert(F.getGUID());
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000199 Index.addGlobalValueSummary(F.getName(), std::move(FuncSummary));
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000200}
201
Teresa Johnson519465b2017-01-05 14:32:16 +0000202static void
203computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V,
Teresa Johnsone27b0582017-01-05 14:59:56 +0000204 DenseSet<GlobalValue::GUID> &CantBePromoted) {
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000205 SetVector<ValueInfo> RefEdges;
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000206 SmallPtrSet<const User *, 8> Visited;
207 findRefEdges(&V, RefEdges, Visited);
Teresa Johnson519465b2017-01-05 14:32:16 +0000208 bool NonRenamableLocal = isNonRenamableLocal(V);
Teresa Johnson6c475a72017-01-05 21:34:18 +0000209 GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,
210 /* LiveRoot = */ false);
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000211 auto GVarSummary =
212 llvm::make_unique<GlobalVarSummary>(Flags, RefEdges.takeVector());
Teresa Johnson519465b2017-01-05 14:32:16 +0000213 if (NonRenamableLocal)
214 CantBePromoted.insert(V.getGUID());
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000215 Index.addGlobalValueSummary(V.getName(), std::move(GVarSummary));
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000216}
217
Teresa Johnson519465b2017-01-05 14:32:16 +0000218static void
219computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
Teresa Johnsone27b0582017-01-05 14:59:56 +0000220 DenseSet<GlobalValue::GUID> &CantBePromoted) {
Teresa Johnson519465b2017-01-05 14:32:16 +0000221 bool NonRenamableLocal = isNonRenamableLocal(A);
Teresa Johnson6c475a72017-01-05 21:34:18 +0000222 GlobalValueSummary::GVFlags Flags(A.getLinkage(), NonRenamableLocal,
223 /* LiveRoot = */ false);
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000224 auto AS = llvm::make_unique<AliasSummary>(Flags, ArrayRef<ValueInfo>{});
Teresa Johnson02563cd2016-10-28 02:39:38 +0000225 auto *Aliasee = A.getBaseObject();
226 auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee);
227 assert(AliaseeSummary && "Alias expects aliasee summary to be parsed");
228 AS->setAliasee(AliaseeSummary);
Teresa Johnson519465b2017-01-05 14:32:16 +0000229 if (NonRenamableLocal)
230 CantBePromoted.insert(A.getGUID());
Teresa Johnson02563cd2016-10-28 02:39:38 +0000231 Index.addGlobalValueSummary(A.getName(), std::move(AS));
232}
233
Teresa Johnson6c475a72017-01-05 21:34:18 +0000234// Set LiveRoot flag on entries matching the given value name.
235static void setLiveRoot(ModuleSummaryIndex &Index, StringRef Name) {
236 auto SummaryList =
237 Index.findGlobalValueSummaryList(GlobalValue::getGUID(Name));
238 if (SummaryList == Index.end())
239 return;
240 for (auto &Summary : SummaryList->second)
241 Summary->setLiveRoot();
242}
243
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000244ModuleSummaryIndex llvm::buildModuleSummaryIndex(
245 const Module &M,
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000246 std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback,
247 ProfileSummaryInfo *PSI) {
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000248 ModuleSummaryIndex Index;
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000249
Teresa Johnsona0811452016-11-10 16:57:32 +0000250 // Identify the local values in the llvm.used and llvm.compiler.used sets,
251 // which should not be exported as they would then require renaming and
252 // promotion, but we may have opaque uses e.g. in inline asm. We collect them
253 // here because we use this information to mark functions containing inline
254 // assembly calls as not importable.
Mehdi Aminib6a11a72016-11-09 01:45:13 +0000255 SmallPtrSet<GlobalValue *, 8> LocalsUsed;
Teresa Johnsona0811452016-11-10 16:57:32 +0000256 SmallPtrSet<GlobalValue *, 8> Used;
257 // First collect those in the llvm.used set.
258 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
Teresa Johnsona0811452016-11-10 16:57:32 +0000259 // Next collect those in the llvm.compiler.used set.
260 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ true);
Teresa Johnsone27b0582017-01-05 14:59:56 +0000261 DenseSet<GlobalValue::GUID> CantBePromoted;
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000262 for (auto *V : Used) {
Teresa Johnson519465b2017-01-05 14:32:16 +0000263 if (V->hasLocalLinkage()) {
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000264 LocalsUsed.insert(V);
Teresa Johnson519465b2017-01-05 14:32:16 +0000265 CantBePromoted.insert(V->getGUID());
266 }
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000267 }
Teresa Johnsonb35cc692016-04-20 14:39:45 +0000268
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000269 // Compute summaries for all functions defined in module, and save in the
270 // index.
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000271 for (auto &F : M) {
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000272 if (F.isDeclaration())
273 continue;
274
275 BlockFrequencyInfo *BFI = nullptr;
276 std::unique_ptr<BlockFrequencyInfo> BFIPtr;
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000277 if (GetBFICallback)
278 BFI = GetBFICallback(F);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000279 else if (F.getEntryCount().hasValue()) {
280 LoopInfo LI{DominatorTree(const_cast<Function &>(F))};
281 BranchProbabilityInfo BPI{F, LI};
282 BFIPtr = llvm::make_unique<BlockFrequencyInfo>(F, BPI, LI);
283 BFI = BFIPtr.get();
284 }
285
Teresa Johnson519465b2017-01-05 14:32:16 +0000286 computeFunctionSummary(Index, M, F, BFI, PSI, !LocalsUsed.empty(),
287 CantBePromoted);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000288 }
289
290 // Compute summaries for all variables defined in module, and save in the
291 // index.
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000292 for (const GlobalVariable &G : M.globals()) {
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000293 if (G.isDeclaration())
294 continue;
Teresa Johnson519465b2017-01-05 14:32:16 +0000295 computeVariableSummary(Index, G, CantBePromoted);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000296 }
Teresa Johnson02563cd2016-10-28 02:39:38 +0000297
298 // Compute summaries for all aliases defined in module, and save in the
299 // index.
300 for (const GlobalAlias &A : M.aliases())
Teresa Johnson519465b2017-01-05 14:32:16 +0000301 computeAliasSummary(Index, A, CantBePromoted);
Teresa Johnson02563cd2016-10-28 02:39:38 +0000302
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000303 for (auto *V : LocalsUsed) {
304 auto *Summary = Index.getGlobalValueSummary(*V);
305 assert(Summary && "Missing summary for global value");
Teresa Johnson519465b2017-01-05 14:32:16 +0000306 Summary->setNotEligibleToImport();
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000307 }
308
Teresa Johnson6c475a72017-01-05 21:34:18 +0000309 // The linker doesn't know about these LLVM produced values, so we need
310 // to flag them as live in the index to ensure index-based dead value
311 // analysis treats them as live roots of the analysis.
312 setLiveRoot(Index, "llvm.used");
313 setLiveRoot(Index, "llvm.compiler.used");
314 setLiveRoot(Index, "llvm.global_ctors");
315 setLiveRoot(Index, "llvm.global_dtors");
316 setLiveRoot(Index, "llvm.global.annotations");
317
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000318 if (!M.getModuleInlineAsm().empty()) {
319 // Collect the local values defined by module level asm, and set up
320 // summaries for these symbols so that they can be marked as NoRename,
321 // to prevent export of any use of them in regular IR that would require
322 // renaming within the module level asm. Note we don't need to create a
323 // summary for weak or global defs, as they don't need to be flagged as
324 // NoRename, and defs in module level asm can't be imported anyway.
325 // Also, any values used but not defined within module level asm should
326 // be listed on the llvm.used or llvm.compiler.used global and marked as
327 // referenced from there.
Peter Collingbourne863cbfb2016-12-01 06:51:47 +0000328 ModuleSymbolTable::CollectAsmSymbols(
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000329 Triple(M.getTargetTriple()), M.getModuleInlineAsm(),
Teresa Johnson519465b2017-01-05 14:32:16 +0000330 [&M, &Index, &CantBePromoted](StringRef Name,
331 object::BasicSymbolRef::Flags Flags) {
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000332 // Symbols not marked as Weak or Global are local definitions.
Teresa Johnsone0ee5cf2016-12-27 17:45:09 +0000333 if (Flags & (object::BasicSymbolRef::SF_Weak |
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000334 object::BasicSymbolRef::SF_Global))
335 return;
336 GlobalValue *GV = M.getNamedValue(Name);
337 if (!GV)
338 return;
339 assert(GV->isDeclaration() && "Def in module asm already has definition");
Teresa Johnson519465b2017-01-05 14:32:16 +0000340 GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage,
Teresa Johnson6c475a72017-01-05 21:34:18 +0000341 /* NotEligibleToImport */ true,
342 /* LiveRoot */ true);
Teresa Johnson519465b2017-01-05 14:32:16 +0000343 CantBePromoted.insert(GlobalValue::getGUID(Name));
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000344 // Create the appropriate summary type.
345 if (isa<Function>(GV)) {
346 std::unique_ptr<FunctionSummary> Summary =
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000347 llvm::make_unique<FunctionSummary>(
348 GVFlags, 0, ArrayRef<ValueInfo>{},
Peter Collingbourne1b4137a72016-12-21 23:03:45 +0000349 ArrayRef<FunctionSummary::EdgeTy>{},
350 ArrayRef<GlobalValue::GUID>{});
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000351 Index.addGlobalValueSummary(Name, std::move(Summary));
352 } else {
353 std::unique_ptr<GlobalVarSummary> Summary =
Peter Collingbourne0c30f082016-12-20 21:12:28 +0000354 llvm::make_unique<GlobalVarSummary>(GVFlags,
355 ArrayRef<ValueInfo>{});
Teresa Johnson3624bdf2016-11-14 17:12:32 +0000356 Index.addGlobalValueSummary(Name, std::move(Summary));
357 }
358 });
359 }
360
Teresa Johnson519465b2017-01-05 14:32:16 +0000361 for (auto &GlobalList : Index) {
362 assert(GlobalList.second.size() == 1 &&
363 "Expected module's index to have one summary per GUID");
364 auto &Summary = GlobalList.second[0];
365 bool AllRefsCanBeExternallyReferenced =
366 llvm::all_of(Summary->refs(), [&](const ValueInfo &VI) {
367 return !CantBePromoted.count(VI.getValue()->getGUID());
368 });
369 if (!AllRefsCanBeExternallyReferenced) {
370 Summary->setNotEligibleToImport();
371 continue;
372 }
373
374 if (auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) {
375 bool AllCallsCanBeExternallyReferenced = llvm::all_of(
376 FuncSummary->calls(), [&](const FunctionSummary::EdgeTy &Edge) {
377 auto GUID = Edge.first.isGUID() ? Edge.first.getGUID()
378 : Edge.first.getValue()->getGUID();
379 return !CantBePromoted.count(GUID);
380 });
381 if (!AllCallsCanBeExternallyReferenced)
382 Summary->setNotEligibleToImport();
383 }
384 }
385
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000386 return Index;
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000387}
388
Chandler Carruthdab4eae2016-11-23 17:53:26 +0000389AnalysisKey ModuleSummaryIndexAnalysis::Key;
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000390
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000391ModuleSummaryIndex
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000392ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000393 ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000394 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000395 return buildModuleSummaryIndex(
396 M,
397 [&FAM](const Function &F) {
398 return &FAM.getResult<BlockFrequencyAnalysis>(
399 *const_cast<Function *>(&F));
400 },
401 &PSI);
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000402}
403
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000404char ModuleSummaryIndexWrapperPass::ID = 0;
405INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
406 "Module Summary Analysis", false, true)
407INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
Mehdi Amini89029482017-01-21 06:01:22 +0000408INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000409INITIALIZE_PASS_END(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
410 "Module Summary Analysis", false, true)
411
412ModulePass *llvm::createModuleSummaryIndexWrapperPass() {
413 return new ModuleSummaryIndexWrapperPass();
414}
415
416ModuleSummaryIndexWrapperPass::ModuleSummaryIndexWrapperPass()
417 : ModulePass(ID) {
418 initializeModuleSummaryIndexWrapperPassPass(*PassRegistry::getPassRegistry());
419}
420
421bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) {
Dehao Chen5461d8b2016-09-28 21:00:58 +0000422 auto &PSI = *getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000423 Index = buildModuleSummaryIndex(
424 M,
425 [this](const Function &F) {
426 return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>(
427 *const_cast<Function *>(&F))
428 .getBFI());
429 },
430 &PSI);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000431 return false;
432}
433
434bool ModuleSummaryIndexWrapperPass::doFinalization(Module &M) {
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000435 Index.reset();
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000436 return false;
437}
438
439void ModuleSummaryIndexWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
440 AU.setPreservesAll();
441 AU.addRequired<BlockFrequencyInfoWrapperPass>();
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000442 AU.addRequired<ProfileSummaryInfoWrapperPass>();
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000443}