blob: 7c57c0592e6647fd3c41ee286c614289ceb99097 [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"
16#include "llvm/Analysis/BlockFrequencyInfo.h"
17#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
18#include "llvm/Analysis/BranchProbabilityInfo.h"
19#include "llvm/Analysis/LoopInfo.h"
20#include "llvm/IR/CallSite.h"
21#include "llvm/IR/Dominators.h"
Teresa Johnsondf5ef872016-04-27 14:19:38 +000022#include "llvm/IR/InstIterator.h"
Teresa Johnson2d5487c2016-04-11 13:58:45 +000023#include "llvm/IR/IntrinsicInst.h"
24#include "llvm/IR/ValueSymbolTable.h"
25#include "llvm/Pass.h"
26using namespace llvm;
27
28#define DEBUG_TYPE "module-summary-analysis"
29
30// Walk through the operands of a given User via worklist iteration and populate
31// the set of GlobalValue references encountered. Invoked either on an
32// Instruction or a GlobalVariable (which walks its initializer).
33static void findRefEdges(const User *CurUser, DenseSet<const Value *> &RefEdges,
34 SmallPtrSet<const User *, 8> &Visited) {
35 SmallVector<const User *, 32> Worklist;
36 Worklist.push_back(CurUser);
37
38 while (!Worklist.empty()) {
39 const User *U = Worklist.pop_back_val();
40
41 if (!Visited.insert(U).second)
42 continue;
43
44 ImmutableCallSite CS(U);
45
46 for (const auto &OI : U->operands()) {
47 const User *Operand = dyn_cast<User>(OI);
48 if (!Operand)
49 continue;
50 if (isa<BlockAddress>(Operand))
51 continue;
52 if (isa<GlobalValue>(Operand)) {
53 // We have a reference to a global value. This should be added to
54 // the reference set unless it is a callee. Callees are handled
55 // specially by WriteFunction and are added to a separate list.
56 if (!(CS && CS.isCallee(&OI)))
57 RefEdges.insert(Operand);
58 continue;
59 }
60 Worklist.push_back(Operand);
61 }
62 }
63}
64
Teresa Johnson28e457b2016-04-24 14:57:11 +000065void ModuleSummaryIndexBuilder::computeFunctionSummary(
66 const Function &F, BlockFrequencyInfo *BFI) {
Teresa Johnson2d5487c2016-04-11 13:58:45 +000067 // Summary not currently supported for anonymous functions, they must
68 // be renamed.
69 if (!F.hasName())
70 return;
71
72 unsigned NumInsts = 0;
73 // Map from callee ValueId to profile count. Used to accumulate profile
74 // counts for all static calls to a given callee.
75 DenseMap<const Value *, CalleeInfo> CallGraphEdges;
76 DenseSet<const Value *> RefEdges;
77
78 SmallPtrSet<const User *, 8> Visited;
79 for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
80 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E;
81 ++I) {
82 if (!isa<DbgInfoIntrinsic>(I))
83 ++NumInsts;
84
85 if (auto CS = ImmutableCallSite(&*I)) {
86 auto *CalledFunction = CS.getCalledFunction();
87 if (CalledFunction && CalledFunction->hasName() &&
88 !CalledFunction->isIntrinsic()) {
89 auto ScaledCount = BFI ? BFI->getBlockProfileCount(&*BB) : None;
90 auto *CalleeId =
91 M->getValueSymbolTable().lookup(CalledFunction->getName());
92 CallGraphEdges[CalleeId] +=
93 (ScaledCount ? ScaledCount.getValue() : 0);
94 }
95 }
96 findRefEdges(&*I, RefEdges, Visited);
97 }
98
Mehdi Aminic3ed48c2016-04-24 03:18:18 +000099 GlobalValueSummary::GVFlags Flags(F);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000100 std::unique_ptr<FunctionSummary> FuncSummary =
Mehdi Aminic3ed48c2016-04-24 03:18:18 +0000101 llvm::make_unique<FunctionSummary>(Flags, NumInsts);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000102 FuncSummary->addCallGraphEdges(CallGraphEdges);
103 FuncSummary->addRefEdges(RefEdges);
Teresa Johnson28e457b2016-04-24 14:57:11 +0000104 Index->addGlobalValueSummary(F.getName(), std::move(FuncSummary));
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000105}
106
Teresa Johnson28e457b2016-04-24 14:57:11 +0000107void ModuleSummaryIndexBuilder::computeVariableSummary(
108 const GlobalVariable &V) {
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000109 DenseSet<const Value *> RefEdges;
110 SmallPtrSet<const User *, 8> Visited;
111 findRefEdges(&V, RefEdges, Visited);
Mehdi Aminic3ed48c2016-04-24 03:18:18 +0000112 GlobalValueSummary::GVFlags Flags(V);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000113 std::unique_ptr<GlobalVarSummary> GVarSummary =
Mehdi Aminic3ed48c2016-04-24 03:18:18 +0000114 llvm::make_unique<GlobalVarSummary>(Flags);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000115 GVarSummary->addRefEdges(RefEdges);
Teresa Johnson28e457b2016-04-24 14:57:11 +0000116 Index->addGlobalValueSummary(V.getName(), std::move(GVarSummary));
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000117}
118
119ModuleSummaryIndexBuilder::ModuleSummaryIndexBuilder(
120 const Module *M,
121 std::function<BlockFrequencyInfo *(const Function &F)> Ftor)
122 : Index(llvm::make_unique<ModuleSummaryIndex>()), M(M) {
Mehdi Amini3b132e32016-05-06 08:25:33 +0000123 // Check if the module can be promoted, otherwise just disable importing from
124 // it by not emitting any summary.
125 // FIXME: we could still import *into* it most of the time.
126 if (!moduleCanBeRenamedForThinLTO(*M))
127 return;
Teresa Johnsonb35cc692016-04-20 14:39:45 +0000128
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000129 // Compute summaries for all functions defined in module, and save in the
130 // index.
131 for (auto &F : *M) {
132 if (F.isDeclaration())
133 continue;
134
135 BlockFrequencyInfo *BFI = nullptr;
136 std::unique_ptr<BlockFrequencyInfo> BFIPtr;
137 if (Ftor)
138 BFI = Ftor(F);
139 else if (F.getEntryCount().hasValue()) {
140 LoopInfo LI{DominatorTree(const_cast<Function &>(F))};
141 BranchProbabilityInfo BPI{F, LI};
142 BFIPtr = llvm::make_unique<BlockFrequencyInfo>(F, BPI, LI);
143 BFI = BFIPtr.get();
144 }
145
Teresa Johnson28e457b2016-04-24 14:57:11 +0000146 computeFunctionSummary(F, BFI);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000147 }
148
149 // Compute summaries for all variables defined in module, and save in the
150 // index.
151 for (const GlobalVariable &G : M->globals()) {
152 if (G.isDeclaration())
153 continue;
Teresa Johnson28e457b2016-04-24 14:57:11 +0000154 computeVariableSummary(G);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000155 }
156}
157
158char ModuleSummaryIndexWrapperPass::ID = 0;
159INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
160 "Module Summary Analysis", false, true)
161INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
162INITIALIZE_PASS_END(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
163 "Module Summary Analysis", false, true)
164
165ModulePass *llvm::createModuleSummaryIndexWrapperPass() {
166 return new ModuleSummaryIndexWrapperPass();
167}
168
169ModuleSummaryIndexWrapperPass::ModuleSummaryIndexWrapperPass()
170 : ModulePass(ID) {
171 initializeModuleSummaryIndexWrapperPassPass(*PassRegistry::getPassRegistry());
172}
173
174bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) {
175 IndexBuilder = llvm::make_unique<ModuleSummaryIndexBuilder>(
176 &M, [this](const Function &F) {
177 return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>(
178 *const_cast<Function *>(&F))
179 .getBFI());
180 });
181 return false;
182}
183
184bool ModuleSummaryIndexWrapperPass::doFinalization(Module &M) {
185 IndexBuilder.reset();
186 return false;
187}
188
189void ModuleSummaryIndexWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
190 AU.setPreservesAll();
191 AU.addRequired<BlockFrequencyInfoWrapperPass>();
192}
Mehdi Amini3b132e32016-05-06 08:25:33 +0000193
194bool llvm::moduleCanBeRenamedForThinLTO(const Module &M) {
195 // We cannot currently promote or rename anything used in inline assembly,
196 // which are not visible to the compiler. Detect a possible case by looking
197 // for a llvm.used local value, in conjunction with an inline assembly call
198 // in the module. Prevent importing of any modules containing these uses by
199 // suppressing generation of the index. This also prevents importing
200 // into this module, which is also necessary to avoid needing to rename
201 // in case of a name clash between a local in this module and an imported
202 // global.
203 // FIXME: If we find we need a finer-grained approach of preventing promotion
204 // and renaming of just the functions using inline assembly we will need to:
205 // - Add flag in the function summaries to identify those with inline asm.
206 // - Prevent importing of any functions with flag set.
207 // - Prevent importing of any global function with the same name as a
208 // function in current module that has the flag set.
209 // - For any llvm.used value that is exported and promoted, add a private
210 // alias to the original name in the current module (even if we don't
211 // export the function using those values in inline asm, another function
212 // with a reference could be exported).
213 SmallPtrSet<GlobalValue *, 8> Used;
214 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
215 bool LocalIsUsed =
216 llvm::any_of(Used, [](GlobalValue *V) { return V->hasLocalLinkage(); });
217 if (!LocalIsUsed)
218 return true;
219
220 // Walk all the instructions in the module and find if one is inline ASM
221 auto HasInlineAsm = llvm::any_of(M, [](const Function &F) {
222 return llvm::any_of(instructions(F), [](const Instruction &I) {
223 const CallInst *CallI = dyn_cast<CallInst>(&I);
224 if (!CallI)
225 return false;
226 return CallI->isInlineAsm();
227 });
228 });
229 return !HasInlineAsm;
230}