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