blob: 5cf4a895c917dc94aaeaf5c0e4cba92773a6aa26 [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"
Teresa Johnson6955fee2016-11-08 21:53:35 +000016#include "llvm/ADT/Triple.h"
Teresa Johnson2d5487c2016-04-11 13:58:45 +000017#include "llvm/Analysis/BlockFrequencyInfo.h"
18#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
19#include "llvm/Analysis/BranchProbabilityInfo.h"
Teresa Johnsoncd21a642016-07-17 14:47:01 +000020#include "llvm/Analysis/IndirectCallPromotionAnalysis.h"
Teresa Johnson2d5487c2016-04-11 13:58:45 +000021#include "llvm/Analysis/LoopInfo.h"
Piotr Padlewskid9830eb2016-09-26 20:37:32 +000022#include "llvm/Analysis/ProfileSummaryInfo.h"
Teresa Johnson2d5487c2016-04-11 13:58:45 +000023#include "llvm/IR/CallSite.h"
24#include "llvm/IR/Dominators.h"
Teresa Johnsondf5ef872016-04-27 14:19:38 +000025#include "llvm/IR/InstIterator.h"
Teresa Johnson2d5487c2016-04-11 13:58:45 +000026#include "llvm/IR/IntrinsicInst.h"
27#include "llvm/IR/ValueSymbolTable.h"
Teresa Johnson6955fee2016-11-08 21:53:35 +000028#include "llvm/Object/IRObjectFile.h"
Teresa Johnson2d5487c2016-04-11 13:58:45 +000029#include "llvm/Pass.h"
30using namespace llvm;
31
32#define DEBUG_TYPE "module-summary-analysis"
33
34// Walk through the operands of a given User via worklist iteration and populate
35// the set of GlobalValue references encountered. Invoked either on an
36// Instruction or a GlobalVariable (which walks its initializer).
37static void findRefEdges(const User *CurUser, DenseSet<const Value *> &RefEdges,
38 SmallPtrSet<const User *, 8> &Visited) {
39 SmallVector<const User *, 32> Worklist;
40 Worklist.push_back(CurUser);
41
42 while (!Worklist.empty()) {
43 const User *U = Worklist.pop_back_val();
44
45 if (!Visited.insert(U).second)
46 continue;
47
48 ImmutableCallSite CS(U);
49
50 for (const auto &OI : U->operands()) {
51 const User *Operand = dyn_cast<User>(OI);
52 if (!Operand)
53 continue;
54 if (isa<BlockAddress>(Operand))
55 continue;
56 if (isa<GlobalValue>(Operand)) {
57 // We have a reference to a global value. This should be added to
58 // the reference set unless it is a callee. Callees are handled
59 // specially by WriteFunction and are added to a separate list.
60 if (!(CS && CS.isCallee(&OI)))
61 RefEdges.insert(Operand);
62 continue;
63 }
64 Worklist.push_back(Operand);
65 }
66 }
67}
68
Piotr Padlewskid9830eb2016-09-26 20:37:32 +000069static CalleeInfo::HotnessType getHotness(uint64_t ProfileCount,
70 ProfileSummaryInfo *PSI) {
71 if (!PSI)
72 return CalleeInfo::HotnessType::Unknown;
73 if (PSI->isHotCount(ProfileCount))
74 return CalleeInfo::HotnessType::Hot;
75 if (PSI->isColdCount(ProfileCount))
76 return CalleeInfo::HotnessType::Cold;
77 return CalleeInfo::HotnessType::None;
78}
79
Chandler Carruthb7be5b62016-08-19 07:49:19 +000080static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
Piotr Padlewskid9830eb2016-09-26 20:37:32 +000081 const Function &F, BlockFrequencyInfo *BFI,
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +000082 ProfileSummaryInfo *PSI,
83 SmallPtrSetImpl<GlobalValue *> &LocalsUsed) {
Teresa Johnson02563cd2016-10-28 02:39:38 +000084 // Summary not currently supported for anonymous functions, they should
85 // have been named.
86 assert(F.hasName());
Teresa Johnson2d5487c2016-04-11 13:58:45 +000087
88 unsigned NumInsts = 0;
89 // Map from callee ValueId to profile count. Used to accumulate profile
90 // counts for all static calls to a given callee.
91 DenseMap<const Value *, CalleeInfo> CallGraphEdges;
Teresa Johnsoncd21a642016-07-17 14:47:01 +000092 DenseMap<GlobalValue::GUID, CalleeInfo> IndirectCallEdges;
Teresa Johnson2d5487c2016-04-11 13:58:45 +000093 DenseSet<const Value *> RefEdges;
Teresa Johnsoncd21a642016-07-17 14:47:01 +000094 ICallPromotionAnalysis ICallAnalysis;
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +000095 bool HasLocalsInUsed = !LocalsUsed.empty();
Teresa Johnson2d5487c2016-04-11 13:58:45 +000096
97 SmallPtrSet<const User *, 8> Visited;
Benjamin Krameraa209152016-06-26 17:27:42 +000098 for (const BasicBlock &BB : F)
99 for (const Instruction &I : BB) {
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000100 if (isa<DbgInfoIntrinsic>(I))
101 continue;
102 ++NumInsts;
Benjamin Krameraa209152016-06-26 17:27:42 +0000103 findRefEdges(&I, RefEdges, Visited);
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000104 auto CS = ImmutableCallSite(&I);
105 if (!CS)
106 continue;
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000107
108 const auto *CI = dyn_cast<CallInst>(&I);
109 // Since we don't know exactly which local values are referenced in inline
110 // assembly, conservatively reference all of them from this function, to
111 // ensure we don't export a reference (which would require renaming and
112 // promotion).
113 if (HasLocalsInUsed && CI && CI->isInlineAsm())
114 RefEdges.insert(LocalsUsed.begin(), LocalsUsed.end());
115
Teresa Johnson897bab92016-10-08 16:11:42 +0000116 auto *CalledValue = CS.getCalledValue();
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000117 auto *CalledFunction = CS.getCalledFunction();
Teresa Johnson897bab92016-10-08 16:11:42 +0000118 // Check if this is an alias to a function. If so, get the
119 // called aliasee for the checks below.
120 if (auto *GA = dyn_cast<GlobalAlias>(CalledValue)) {
121 assert(!CalledFunction && "Expected null called function in callsite for alias");
122 CalledFunction = dyn_cast<Function>(GA->getBaseObject());
123 }
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000124 // Check if this is a direct call to a known function.
125 if (CalledFunction) {
Teresa Johnson02563cd2016-10-28 02:39:38 +0000126 // Skip intrinsics.
127 if (CalledFunction->isIntrinsic())
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000128 continue;
Teresa Johnson02563cd2016-10-28 02:39:38 +0000129 // We should have named any anonymous globals
130 assert(CalledFunction->hasName());
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000131 auto ScaledCount = BFI ? BFI->getBlockProfileCount(&BB) : None;
Teresa Johnson897bab92016-10-08 16:11:42 +0000132 // Use the original CalledValue, in case it was an alias. We want
133 // to record the call edge to the alias in that case. Eventually
134 // an alias summary will be created to associate the alias and
135 // aliasee.
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000136 auto *CalleeId =
Teresa Johnson897bab92016-10-08 16:11:42 +0000137 M.getValueSymbolTable().lookup(CalledValue->getName());
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000138
139 auto Hotness = ScaledCount ? getHotness(ScaledCount.getValue(), PSI)
140 : CalleeInfo::HotnessType::Unknown;
141 CallGraphEdges[CalleeId].updateHotness(Hotness);
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000142 } else {
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000143 // Skip inline assembly calls.
144 if (CI && CI->isInlineAsm())
145 continue;
146 // Skip direct calls.
147 if (!CS.getCalledValue() || isa<Constant>(CS.getCalledValue()))
148 continue;
149
150 uint32_t NumVals, NumCandidates;
151 uint64_t TotalCount;
152 auto CandidateProfileData =
153 ICallAnalysis.getPromotionCandidatesForInstruction(
154 &I, NumVals, TotalCount, NumCandidates);
155 for (auto &Candidate : CandidateProfileData)
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000156 IndirectCallEdges[Candidate.Value].updateHotness(
157 getHotness(Candidate.Count, PSI));
Piotr Padlewski442d38c2016-08-30 00:46:26 +0000158 }
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000159 }
160
Mehdi Aminic3ed48c2016-04-24 03:18:18 +0000161 GlobalValueSummary::GVFlags Flags(F);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000162 std::unique_ptr<FunctionSummary> FuncSummary =
Mehdi Aminic3ed48c2016-04-24 03:18:18 +0000163 llvm::make_unique<FunctionSummary>(Flags, NumInsts);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000164 FuncSummary->addCallGraphEdges(CallGraphEdges);
Teresa Johnsoncd21a642016-07-17 14:47:01 +0000165 FuncSummary->addCallGraphEdges(IndirectCallEdges);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000166 FuncSummary->addRefEdges(RefEdges);
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000167 Index.addGlobalValueSummary(F.getName(), std::move(FuncSummary));
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000168}
169
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000170static void computeVariableSummary(ModuleSummaryIndex &Index,
171 const GlobalVariable &V) {
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000172 DenseSet<const Value *> RefEdges;
173 SmallPtrSet<const User *, 8> Visited;
174 findRefEdges(&V, RefEdges, Visited);
Mehdi Aminic3ed48c2016-04-24 03:18:18 +0000175 GlobalValueSummary::GVFlags Flags(V);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000176 std::unique_ptr<GlobalVarSummary> GVarSummary =
Mehdi Aminic3ed48c2016-04-24 03:18:18 +0000177 llvm::make_unique<GlobalVarSummary>(Flags);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000178 GVarSummary->addRefEdges(RefEdges);
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000179 Index.addGlobalValueSummary(V.getName(), std::move(GVarSummary));
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000180}
181
Teresa Johnson02563cd2016-10-28 02:39:38 +0000182static void computeAliasSummary(ModuleSummaryIndex &Index,
183 const GlobalAlias &A) {
184 GlobalValueSummary::GVFlags Flags(A);
185 std::unique_ptr<AliasSummary> AS = llvm::make_unique<AliasSummary>(Flags);
186 auto *Aliasee = A.getBaseObject();
187 auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee);
188 assert(AliaseeSummary && "Alias expects aliasee summary to be parsed");
189 AS->setAliasee(AliaseeSummary);
190 Index.addGlobalValueSummary(A.getName(), std::move(AS));
191}
192
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000193ModuleSummaryIndex llvm::buildModuleSummaryIndex(
194 const Module &M,
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000195 std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback,
196 ProfileSummaryInfo *PSI) {
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000197 ModuleSummaryIndex Index;
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000198
Teresa Johnson6955fee2016-11-08 21:53:35 +0000199 // Identify the local values in the llvm.used and llvm.compiler.used sets,
200 // which should not be exported as they would then require renaming and
201 // promotion, but we may have opaque uses e.g. in inline asm. We collect them
202 // here because we use this information to mark functions containing inline
203 // assembly calls as not importable.
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000204 SmallPtrSet<GlobalValue *, 8> LocalsUsed;
Teresa Johnson6955fee2016-11-08 21:53:35 +0000205 SmallPtrSet<GlobalValue *, 8> Used;
206 // First collect those in the llvm.used set.
207 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
208 for (auto *V : Used) {
209 if (V->hasLocalLinkage())
210 LocalsUsed.insert(V);
211 }
212 Used.clear();
213 // Next collect those in the llvm.compiler.used set.
214 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ true);
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000215 for (auto *V : Used) {
216 if (V->hasLocalLinkage())
217 LocalsUsed.insert(V);
218 }
Teresa Johnsonb35cc692016-04-20 14:39:45 +0000219
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000220 // Compute summaries for all functions defined in module, and save in the
221 // index.
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000222 for (auto &F : M) {
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000223 if (F.isDeclaration())
224 continue;
225
226 BlockFrequencyInfo *BFI = nullptr;
227 std::unique_ptr<BlockFrequencyInfo> BFIPtr;
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000228 if (GetBFICallback)
229 BFI = GetBFICallback(F);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000230 else if (F.getEntryCount().hasValue()) {
231 LoopInfo LI{DominatorTree(const_cast<Function &>(F))};
232 BranchProbabilityInfo BPI{F, LI};
233 BFIPtr = llvm::make_unique<BlockFrequencyInfo>(F, BPI, LI);
234 BFI = BFIPtr.get();
235 }
236
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000237 computeFunctionSummary(Index, M, F, BFI, PSI, LocalsUsed);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000238 }
239
240 // Compute summaries for all variables defined in module, and save in the
241 // index.
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000242 for (const GlobalVariable &G : M.globals()) {
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000243 if (G.isDeclaration())
244 continue;
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000245 computeVariableSummary(Index, G);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000246 }
Teresa Johnson02563cd2016-10-28 02:39:38 +0000247
248 // Compute summaries for all aliases defined in module, and save in the
249 // index.
250 for (const GlobalAlias &A : M.aliases())
251 computeAliasSummary(Index, A);
252
Teresa Johnsonbf28c8f2016-10-30 05:40:44 +0000253 for (auto *V : LocalsUsed) {
254 auto *Summary = Index.getGlobalValueSummary(*V);
255 assert(Summary && "Missing summary for global value");
256 Summary->setNoRename();
257 }
258
Teresa Johnson6955fee2016-11-08 21:53:35 +0000259 if (!M.getModuleInlineAsm().empty()) {
260 // Collect the local values defined by module level asm, and set up
261 // summaries for these symbols so that they can be marked as NoRename,
262 // to prevent export of any use of them in regular IR that would require
263 // renaming within the module level asm. Note we don't need to create a
264 // summary for weak or global defs, as they don't need to be flagged as
265 // NoRename, and defs in module level asm can't be imported anyway.
266 // Also, any values used but not defined within module level asm should
267 // be listed on the llvm.used or llvm.compiler.used global and marked as
268 // referenced from there.
269 // FIXME: Rename CollectAsmUndefinedRefs to something more general, as we
270 // are also using it to find the file-scope locals defined in module asm.
271 object::IRObjectFile::CollectAsmUndefinedRefs(
272 Triple(M.getTargetTriple()), M.getModuleInlineAsm(),
273 [&M, &Index](StringRef Name, object::BasicSymbolRef::Flags Flags) {
274 // Symbols not marked as Weak or Global are local definitions.
275 if (Flags & (object::BasicSymbolRef::SF_Weak ||
276 object::BasicSymbolRef::SF_Global))
277 return;
278 GlobalValue *GV = M.getNamedValue(Name);
279 if (!GV)
280 return;
281 assert(GV->isDeclaration() && "Def in module asm already has definition");
282 GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage,
283 /* NoRename */ true,
284 /*IsNotViableToInline */ true);
285 // Create the appropriate summary type.
286 if (isa<Function>(GV)) {
287 std::unique_ptr<FunctionSummary> Summary =
288 llvm::make_unique<FunctionSummary>(GVFlags, 0);
289 Summary->setNoRename();
290 Index.addGlobalValueSummary(Name, std::move(Summary));
291 } else {
292 std::unique_ptr<GlobalVarSummary> Summary =
293 llvm::make_unique<GlobalVarSummary>(GVFlags);
294 Summary->setNoRename();
295 Index.addGlobalValueSummary(Name, std::move(Summary));
296 }
297 });
298 }
299
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000300 return Index;
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000301}
302
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000303char ModuleSummaryIndexAnalysis::PassID;
304
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000305ModuleSummaryIndex
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000306ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000307 ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000308 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000309 return buildModuleSummaryIndex(
310 M,
311 [&FAM](const Function &F) {
312 return &FAM.getResult<BlockFrequencyAnalysis>(
313 *const_cast<Function *>(&F));
314 },
315 &PSI);
Teresa Johnsonf93b2462016-08-12 13:53:02 +0000316}
317
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000318char ModuleSummaryIndexWrapperPass::ID = 0;
319INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
320 "Module Summary Analysis", false, true)
321INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
322INITIALIZE_PASS_END(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
323 "Module Summary Analysis", false, true)
324
325ModulePass *llvm::createModuleSummaryIndexWrapperPass() {
326 return new ModuleSummaryIndexWrapperPass();
327}
328
329ModuleSummaryIndexWrapperPass::ModuleSummaryIndexWrapperPass()
330 : ModulePass(ID) {
331 initializeModuleSummaryIndexWrapperPassPass(*PassRegistry::getPassRegistry());
332}
333
334bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) {
Dehao Chen5461d8b2016-09-28 21:00:58 +0000335 auto &PSI = *getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000336 Index = buildModuleSummaryIndex(
337 M,
338 [this](const Function &F) {
339 return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>(
340 *const_cast<Function *>(&F))
341 .getBFI());
342 },
343 &PSI);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000344 return false;
345}
346
347bool ModuleSummaryIndexWrapperPass::doFinalization(Module &M) {
Chandler Carruthb7be5b62016-08-19 07:49:19 +0000348 Index.reset();
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000349 return false;
350}
351
352void ModuleSummaryIndexWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
353 AU.setPreservesAll();
354 AU.addRequired<BlockFrequencyInfoWrapperPass>();
Piotr Padlewskid9830eb2016-09-26 20:37:32 +0000355 AU.addRequired<ProfileSummaryInfoWrapperPass>();
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000356}