blob: 258b77c8addb199afa54d125c1e7328d0be3a799 [file] [log] [blame]
Rong Xuf430ae42015-12-09 18:08:16 +00001//===-- PGOInstrumentation.cpp - MST-based PGO Instrumentation ------------===//
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 file implements PGO instrumentation using a minimum spanning tree based
11// on the following paper:
12// [1] Donald E. Knuth, Francis R. Stevenson. Optimal measurement of points
13// for program frequency counts. BIT Numerical Mathematics 1973, Volume 13,
14// Issue 3, pp 313-322
15// The idea of the algorithm based on the fact that for each node (except for
16// the entry and exit), the sum of incoming edge counts equals the sum of
17// outgoing edge counts. The count of edge on spanning tree can be derived from
18// those edges not on the spanning tree. Knuth proves this method instruments
19// the minimum number of edges.
20//
21// The minimal spanning tree here is actually a maximum weight tree -- on-tree
22// edges have higher frequencies (more likely to execute). The idea is to
23// instrument those less frequently executed edges to reduce the runtime
24// overhead of instrumented binaries.
25//
26// This file contains two passes:
27// (1) Pass PGOInstrumentationGen which instruments the IR to generate edge
Rong Xu13b01dc2016-02-10 18:24:45 +000028// count profile, and generates the instrumentation for indirect call
29// profiling.
Rong Xuf430ae42015-12-09 18:08:16 +000030// (2) Pass PGOInstrumentationUse which reads the edge count profile and
Rong Xu13b01dc2016-02-10 18:24:45 +000031// annotates the branch weights. It also reads the indirect call value
32// profiling records and annotate the indirect call instructions.
33//
Rong Xuf430ae42015-12-09 18:08:16 +000034// To get the precise counter information, These two passes need to invoke at
35// the same compilation point (so they see the same IR). For pass
36// PGOInstrumentationGen, the real work is done in instrumentOneFunc(). For
37// pass PGOInstrumentationUse, the real work in done in class PGOUseFunc and
38// the profile is opened in module level and passed to each PGOUseFunc instance.
39// The shared code for PGOInstrumentationGen and PGOInstrumentationUse is put
40// in class FuncPGOInstrumentation.
41//
42// Class PGOEdge represents a CFG edge and some auxiliary information. Class
43// BBInfo contains auxiliary information for each BB. These two classes are used
44// in pass PGOInstrumentationGen. Class PGOUseEdge and UseBBInfo are the derived
45// class of PGOEdge and BBInfo, respectively. They contains extra data structure
46// used in populating profile counters.
47// The MST implementation is in Class CFGMST (CFGMST.h).
48//
49//===----------------------------------------------------------------------===//
50
Xinliang David Li8aebf442016-05-06 05:49:19 +000051#include "llvm/Transforms/PGOInstrumentation.h"
Rong Xuf430ae42015-12-09 18:08:16 +000052#include "CFGMST.h"
Rong Xuf430ae42015-12-09 18:08:16 +000053#include "llvm/ADT/STLExtras.h"
Rong Xu705f7772016-07-25 18:45:37 +000054#include "llvm/ADT/SmallVector.h"
Rong Xuf430ae42015-12-09 18:08:16 +000055#include "llvm/ADT/Statistic.h"
Rong Xu33c76c02016-02-10 17:18:30 +000056#include "llvm/ADT/Triple.h"
Rong Xuf430ae42015-12-09 18:08:16 +000057#include "llvm/Analysis/BlockFrequencyInfo.h"
58#include "llvm/Analysis/BranchProbabilityInfo.h"
59#include "llvm/Analysis/CFG.h"
Teresa Johnson1e44b5d2016-07-12 21:13:44 +000060#include "llvm/Analysis/IndirectCallSiteVisitor.h"
Xinliang David Licb253ce2017-01-23 18:58:24 +000061#include "llvm/Analysis/LoopInfo.h"
Rong Xued9fec72016-01-21 18:11:44 +000062#include "llvm/IR/CallSite.h"
Rong Xuf430ae42015-12-09 18:08:16 +000063#include "llvm/IR/DiagnosticInfo.h"
Xinliang David Lid289e452017-01-27 19:06:25 +000064#include "llvm/IR/Dominators.h"
Rong Xu705f7772016-07-25 18:45:37 +000065#include "llvm/IR/GlobalValue.h"
Rong Xuf430ae42015-12-09 18:08:16 +000066#include "llvm/IR/IRBuilder.h"
67#include "llvm/IR/InstIterator.h"
68#include "llvm/IR/Instructions.h"
69#include "llvm/IR/IntrinsicInst.h"
70#include "llvm/IR/MDBuilder.h"
71#include "llvm/IR/Module.h"
72#include "llvm/Pass.h"
73#include "llvm/ProfileData/InstrProfReader.h"
Easwaran Raman5fe04a12016-05-26 22:57:11 +000074#include "llvm/ProfileData/ProfileCommon.h"
Rong Xuf430ae42015-12-09 18:08:16 +000075#include "llvm/Support/BranchProbability.h"
Xinliang David Lid289e452017-01-27 19:06:25 +000076#include "llvm/Support/DOTGraphTraits.h"
Rong Xuf430ae42015-12-09 18:08:16 +000077#include "llvm/Support/Debug.h"
Xinliang David Lid289e452017-01-27 19:06:25 +000078#include "llvm/Support/GraphWriter.h"
Rong Xuf430ae42015-12-09 18:08:16 +000079#include "llvm/Support/JamCRC.h"
Rong Xued9fec72016-01-21 18:11:44 +000080#include "llvm/Transforms/Instrumentation.h"
Rong Xuf430ae42015-12-09 18:08:16 +000081#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Xinliang David Li8aebf442016-05-06 05:49:19 +000082#include <algorithm>
Rong Xuf430ae42015-12-09 18:08:16 +000083#include <string>
Rong Xu705f7772016-07-25 18:45:37 +000084#include <unordered_map>
Rong Xuf430ae42015-12-09 18:08:16 +000085#include <utility>
86#include <vector>
87
88using namespace llvm;
89
90#define DEBUG_TYPE "pgo-instrumentation"
91
92STATISTIC(NumOfPGOInstrument, "Number of edges instrumented.");
Xinliang David Li4ca17332016-09-18 18:34:07 +000093STATISTIC(NumOfPGOSelectInsts, "Number of select instruction instrumented.");
Rong Xu4ed52792017-03-15 21:47:27 +000094STATISTIC(NumOfPGOMemIntrinsics, "Number of mem intrinsics instrumented.");
Rong Xuf430ae42015-12-09 18:08:16 +000095STATISTIC(NumOfPGOEdge, "Number of edges.");
96STATISTIC(NumOfPGOBB, "Number of basic-blocks.");
97STATISTIC(NumOfPGOSplit, "Number of critical edge splits.");
98STATISTIC(NumOfPGOFunc, "Number of functions having valid profile counts.");
99STATISTIC(NumOfPGOMismatch, "Number of functions having mismatch profile.");
100STATISTIC(NumOfPGOMissing, "Number of functions without profile.");
Rong Xu13b01dc2016-02-10 18:24:45 +0000101STATISTIC(NumOfPGOICall, "Number of indirect call value instrumentations.");
Rong Xuf430ae42015-12-09 18:08:16 +0000102
103// Command line option to specify the file to read profile from. This is
104// mainly used for testing.
105static cl::opt<std::string>
106 PGOTestProfileFile("pgo-test-profile-file", cl::init(""), cl::Hidden,
107 cl::value_desc("filename"),
108 cl::desc("Specify the path of profile data file. This is"
109 "mainly for test purpose."));
110
Rong Xuecdc98f2016-03-04 22:08:44 +0000111// Command line option to disable value profiling. The default is false:
Rong Xu13b01dc2016-02-10 18:24:45 +0000112// i.e. value profiling is enabled by default. This is for debug purpose.
Rong Xu9e926e82016-02-29 19:16:04 +0000113static cl::opt<bool> DisableValueProfiling("disable-vp", cl::init(false),
114 cl::Hidden,
115 cl::desc("Disable Value Profiling"));
Rong Xued9fec72016-01-21 18:11:44 +0000116
Rong Xuecdc98f2016-03-04 22:08:44 +0000117// Command line option to set the maximum number of VP annotations to write to
Rong Xu08afb052016-04-28 17:31:22 +0000118// the metadata for a single indirect call callsite.
119static cl::opt<unsigned> MaxNumAnnotations(
120 "icp-max-annotations", cl::init(3), cl::Hidden, cl::ZeroOrMore,
121 cl::desc("Max number of annotations for a single indirect "
122 "call callsite"));
Rong Xuecdc98f2016-03-04 22:08:44 +0000123
Rong Xu705f7772016-07-25 18:45:37 +0000124// Command line option to control appending FunctionHash to the name of a COMDAT
125// function. This is to avoid the hash mismatch caused by the preinliner.
126static cl::opt<bool> DoComdatRenaming(
Rong Xu20f5df12017-01-11 20:19:41 +0000127 "do-comdat-renaming", cl::init(false), cl::Hidden,
Rong Xu705f7772016-07-25 18:45:37 +0000128 cl::desc("Append function hash to the name of COMDAT function to avoid "
129 "function hash mismatch due to the preinliner"));
130
Rong Xu0698de92016-05-13 17:26:06 +0000131// Command line option to enable/disable the warning about missing profile
132// information.
Xinliang David Li58fcc9b2017-02-02 21:29:17 +0000133static cl::opt<bool>
134 PGOWarnMissing("pgo-warn-missing-function", cl::init(false), cl::Hidden,
135 cl::desc("Use this option to turn on/off "
136 "warnings about missing profile data for "
137 "functions."));
Rong Xu0698de92016-05-13 17:26:06 +0000138
139// Command line option to enable/disable the warning about a hash mismatch in
140// the profile data.
Xinliang David Li58fcc9b2017-02-02 21:29:17 +0000141static cl::opt<bool>
142 NoPGOWarnMismatch("no-pgo-warn-mismatch", cl::init(false), cl::Hidden,
143 cl::desc("Use this option to turn off/on "
144 "warnings about profile cfg mismatch."));
Rong Xu0698de92016-05-13 17:26:06 +0000145
Rong Xu20f5df12017-01-11 20:19:41 +0000146// Command line option to enable/disable the warning about a hash mismatch in
147// the profile data for Comdat functions, which often turns out to be false
148// positive due to the pre-instrumentation inline.
Xinliang David Li58fcc9b2017-02-02 21:29:17 +0000149static cl::opt<bool>
150 NoPGOWarnMismatchComdat("no-pgo-warn-mismatch-comdat", cl::init(true),
151 cl::Hidden,
152 cl::desc("The option is used to turn on/off "
153 "warnings about hash mismatch for comdat "
154 "functions."));
Rong Xu20f5df12017-01-11 20:19:41 +0000155
Xinliang David Li4ca17332016-09-18 18:34:07 +0000156// Command line option to enable/disable select instruction instrumentation.
Xinliang David Li58fcc9b2017-02-02 21:29:17 +0000157static cl::opt<bool>
158 PGOInstrSelect("pgo-instr-select", cl::init(true), cl::Hidden,
159 cl::desc("Use this option to turn on/off SELECT "
160 "instruction instrumentation. "));
Xinliang David Licb253ce2017-01-23 18:58:24 +0000161
Xinliang David Lid289e452017-01-27 19:06:25 +0000162// Command line option to turn on CFG dot dump of raw profile counts
Xinliang David Li58fcc9b2017-02-02 21:29:17 +0000163static cl::opt<bool>
164 PGOViewRawCounts("pgo-view-raw-counts", cl::init(false), cl::Hidden,
165 cl::desc("A boolean option to show CFG dag "
166 "with raw profile counts from "
167 "profile data. See also option "
168 "-pgo-view-counts. To limit graph "
169 "display to only one function, use "
170 "filtering option -view-bfi-func-name."));
Xinliang David Lid289e452017-01-27 19:06:25 +0000171
Rong Xu4ed52792017-03-15 21:47:27 +0000172// Command line option to enable/disable memop intrinsic calls..
173static cl::opt<bool> PGOInstrMemOP("pgo-instr-memop", cl::init(true),
174 cl::Hidden);
175
Xinliang David Licb253ce2017-01-23 18:58:24 +0000176// Command line option to turn on CFG dot dump after profile annotation.
Xinliang David Li58fcc9b2017-02-02 21:29:17 +0000177// Defined in Analysis/BlockFrequencyInfo.cpp: -pgo-view-counts
Xinliang David Licb253ce2017-01-23 18:58:24 +0000178extern cl::opt<bool> PGOViewCounts;
179
Xinliang David Li58fcc9b2017-02-02 21:29:17 +0000180// Command line option to specify the name of the function for CFG dump
181// Defined in Analysis/BlockFrequencyInfo.cpp: -view-bfi-func-name=
182extern cl::opt<std::string> ViewBlockFreqFuncName;
183
Rong Xuf430ae42015-12-09 18:08:16 +0000184namespace {
Xinliang David Li4ca17332016-09-18 18:34:07 +0000185
186/// The select instruction visitor plays three roles specified
187/// by the mode. In \c VM_counting mode, it simply counts the number of
188/// select instructions. In \c VM_instrument mode, it inserts code to count
189/// the number times TrueValue of select is taken. In \c VM_annotate mode,
190/// it reads the profile data and annotate the select instruction with metadata.
191enum VisitMode { VM_counting, VM_instrument, VM_annotate };
192class PGOUseFunc;
193
194/// Instruction Visitor class to visit select instructions.
195struct SelectInstVisitor : public InstVisitor<SelectInstVisitor> {
196 Function &F;
197 unsigned NSIs = 0; // Number of select instructions instrumented.
198 VisitMode Mode = VM_counting; // Visiting mode.
199 unsigned *CurCtrIdx = nullptr; // Pointer to current counter index.
200 unsigned TotalNumCtrs = 0; // Total number of counters
201 GlobalVariable *FuncNameVar = nullptr;
202 uint64_t FuncHash = 0;
203 PGOUseFunc *UseFunc = nullptr;
204
205 SelectInstVisitor(Function &Func) : F(Func) {}
206
207 void countSelects(Function &Func) {
208 Mode = VM_counting;
209 visit(Func);
210 }
211 // Visit the IR stream and instrument all select instructions. \p
212 // Ind is a pointer to the counter index variable; \p TotalNC
213 // is the total number of counters; \p FNV is the pointer to the
214 // PGO function name var; \p FHash is the function hash.
215 void instrumentSelects(Function &Func, unsigned *Ind, unsigned TotalNC,
216 GlobalVariable *FNV, uint64_t FHash) {
217 Mode = VM_instrument;
218 CurCtrIdx = Ind;
219 TotalNumCtrs = TotalNC;
220 FuncHash = FHash;
221 FuncNameVar = FNV;
222 visit(Func);
223 }
224
225 // Visit the IR stream and annotate all select instructions.
226 void annotateSelects(Function &Func, PGOUseFunc *UF, unsigned *Ind) {
227 Mode = VM_annotate;
228 UseFunc = UF;
229 CurCtrIdx = Ind;
230 visit(Func);
231 }
232
233 void instrumentOneSelectInst(SelectInst &SI);
234 void annotateOneSelectInst(SelectInst &SI);
235 // Visit \p SI instruction and perform tasks according to visit mode.
236 void visitSelectInst(SelectInst &SI);
237 unsigned getNumOfSelectInsts() const { return NSIs; }
238};
239
Rong Xu4ed52792017-03-15 21:47:27 +0000240/// Instruction Visitor class to visit memory intrinsic calls.
241struct MemIntrinsicVisitor : public InstVisitor<MemIntrinsicVisitor> {
242 Function &F;
243 unsigned NMemIs = 0; // Number of memIntrinsics instrumented.
244 VisitMode Mode = VM_counting; // Visiting mode.
245 unsigned CurCtrId = 0; // Current counter index.
246 unsigned TotalNumCtrs = 0; // Total number of counters
247 GlobalVariable *FuncNameVar = nullptr;
248 uint64_t FuncHash = 0;
249 PGOUseFunc *UseFunc = nullptr;
250
251 MemIntrinsicVisitor(Function &Func) : F(Func) {}
252
253 void countMemIntrinsics(Function &Func) {
254 NMemIs = 0;
255 Mode = VM_counting;
256 visit(Func);
257 }
258 void instrumentMemIntrinsics(Function &Func, unsigned TotalNC,
259 GlobalVariable *FNV, uint64_t FHash) {
260 Mode = VM_instrument;
261 TotalNumCtrs = TotalNC;
262 FuncHash = FHash;
263 FuncNameVar = FNV;
264 visit(Func);
265 }
266
267 // Visit the IR stream and annotate all mem intrinsic call instructions.
268 void instrumentOneMemIntrinsic(MemIntrinsic &MI);
269 // Visit \p MI instruction and perform tasks according to visit mode.
270 void visitMemIntrinsic(MemIntrinsic &SI);
271 unsigned getNumOfMemIntrinsics() const { return NMemIs; }
272};
273
Xinliang David Li8aebf442016-05-06 05:49:19 +0000274class PGOInstrumentationGenLegacyPass : public ModulePass {
Rong Xuf430ae42015-12-09 18:08:16 +0000275public:
276 static char ID;
277
Xinliang David Lidfa21c32016-05-09 21:37:12 +0000278 PGOInstrumentationGenLegacyPass() : ModulePass(ID) {
Xinliang David Li8aebf442016-05-06 05:49:19 +0000279 initializePGOInstrumentationGenLegacyPassPass(
280 *PassRegistry::getPassRegistry());
Rong Xuf430ae42015-12-09 18:08:16 +0000281 }
282
Mehdi Amini117296c2016-10-01 02:56:57 +0000283 StringRef getPassName() const override { return "PGOInstrumentationGenPass"; }
Rong Xuf430ae42015-12-09 18:08:16 +0000284
285private:
286 bool runOnModule(Module &M) override;
287
288 void getAnalysisUsage(AnalysisUsage &AU) const override {
289 AU.addRequired<BlockFrequencyInfoWrapperPass>();
290 }
291};
292
Xinliang David Lid55827f2016-05-07 05:39:12 +0000293class PGOInstrumentationUseLegacyPass : public ModulePass {
Rong Xuf430ae42015-12-09 18:08:16 +0000294public:
295 static char ID;
296
297 // Provide the profile filename as the parameter.
Xinliang David Lid55827f2016-05-07 05:39:12 +0000298 PGOInstrumentationUseLegacyPass(std::string Filename = "")
Benjamin Kramer82de7d32016-05-27 14:27:24 +0000299 : ModulePass(ID), ProfileFileName(std::move(Filename)) {
Rong Xuf430ae42015-12-09 18:08:16 +0000300 if (!PGOTestProfileFile.empty())
301 ProfileFileName = PGOTestProfileFile;
Xinliang David Lid55827f2016-05-07 05:39:12 +0000302 initializePGOInstrumentationUseLegacyPassPass(
303 *PassRegistry::getPassRegistry());
Rong Xuf430ae42015-12-09 18:08:16 +0000304 }
305
Mehdi Amini117296c2016-10-01 02:56:57 +0000306 StringRef getPassName() const override { return "PGOInstrumentationUsePass"; }
Rong Xuf430ae42015-12-09 18:08:16 +0000307
308private:
309 std::string ProfileFileName;
Rong Xuf430ae42015-12-09 18:08:16 +0000310
Xinliang David Lida195582016-05-10 21:59:52 +0000311 bool runOnModule(Module &M) override;
Rong Xuf430ae42015-12-09 18:08:16 +0000312 void getAnalysisUsage(AnalysisUsage &AU) const override {
313 AU.addRequired<BlockFrequencyInfoWrapperPass>();
314 }
315};
Xinliang David Li4ca17332016-09-18 18:34:07 +0000316
Rong Xuf430ae42015-12-09 18:08:16 +0000317} // end anonymous namespace
318
Xinliang David Li8aebf442016-05-06 05:49:19 +0000319char PGOInstrumentationGenLegacyPass::ID = 0;
320INITIALIZE_PASS_BEGIN(PGOInstrumentationGenLegacyPass, "pgo-instr-gen",
Rong Xuf430ae42015-12-09 18:08:16 +0000321 "PGO instrumentation.", false, false)
322INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
323INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
Xinliang David Li8aebf442016-05-06 05:49:19 +0000324INITIALIZE_PASS_END(PGOInstrumentationGenLegacyPass, "pgo-instr-gen",
Rong Xuf430ae42015-12-09 18:08:16 +0000325 "PGO instrumentation.", false, false)
326
Xinliang David Li8aebf442016-05-06 05:49:19 +0000327ModulePass *llvm::createPGOInstrumentationGenLegacyPass() {
328 return new PGOInstrumentationGenLegacyPass();
Rong Xuf430ae42015-12-09 18:08:16 +0000329}
330
Xinliang David Lid55827f2016-05-07 05:39:12 +0000331char PGOInstrumentationUseLegacyPass::ID = 0;
332INITIALIZE_PASS_BEGIN(PGOInstrumentationUseLegacyPass, "pgo-instr-use",
Rong Xuf430ae42015-12-09 18:08:16 +0000333 "Read PGO instrumentation profile.", false, false)
334INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
335INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
Xinliang David Lid55827f2016-05-07 05:39:12 +0000336INITIALIZE_PASS_END(PGOInstrumentationUseLegacyPass, "pgo-instr-use",
Rong Xuf430ae42015-12-09 18:08:16 +0000337 "Read PGO instrumentation profile.", false, false)
338
Xinliang David Lid55827f2016-05-07 05:39:12 +0000339ModulePass *llvm::createPGOInstrumentationUseLegacyPass(StringRef Filename) {
340 return new PGOInstrumentationUseLegacyPass(Filename.str());
Rong Xuf430ae42015-12-09 18:08:16 +0000341}
342
343namespace {
344/// \brief An MST based instrumentation for PGO
345///
346/// Implements a Minimum Spanning Tree (MST) based instrumentation for PGO
347/// in the function level.
348struct PGOEdge {
349 // This class implements the CFG edges. Note the CFG can be a multi-graph.
350 // So there might be multiple edges with same SrcBB and DestBB.
351 const BasicBlock *SrcBB;
352 const BasicBlock *DestBB;
353 uint64_t Weight;
354 bool InMST;
355 bool Removed;
356 bool IsCritical;
357 PGOEdge(const BasicBlock *Src, const BasicBlock *Dest, unsigned W = 1)
358 : SrcBB(Src), DestBB(Dest), Weight(W), InMST(false), Removed(false),
359 IsCritical(false) {}
360 // Return the information string of an edge.
361 const std::string infoString() const {
362 return (Twine(Removed ? "-" : " ") + (InMST ? " " : "*") +
363 (IsCritical ? "c" : " ") + " W=" + Twine(Weight)).str();
364 }
365};
366
367// This class stores the auxiliary information for each BB.
368struct BBInfo {
369 BBInfo *Group;
370 uint32_t Index;
371 uint32_t Rank;
372
373 BBInfo(unsigned IX) : Group(this), Index(IX), Rank(0) {}
374
375 // Return the information string of this object.
376 const std::string infoString() const {
377 return (Twine("Index=") + Twine(Index)).str();
378 }
379};
380
381// This class implements the CFG edges. Note the CFG can be a multi-graph.
382template <class Edge, class BBInfo> class FuncPGOInstrumentation {
383private:
384 Function &F;
385 void computeCFGHash();
Rong Xu705f7772016-07-25 18:45:37 +0000386 void renameComdatFunction();
387 // A map that stores the Comdat group in function F.
388 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
Rong Xuf430ae42015-12-09 18:08:16 +0000389
390public:
Rong Xua3bbf962017-03-15 18:23:39 +0000391 std::vector<std::vector<Instruction *>> ValueSites;
Xinliang David Li4ca17332016-09-18 18:34:07 +0000392 SelectInstVisitor SIVisitor;
Rong Xu4ed52792017-03-15 21:47:27 +0000393 MemIntrinsicVisitor MIVisitor;
Rong Xuf430ae42015-12-09 18:08:16 +0000394 std::string FuncName;
395 GlobalVariable *FuncNameVar;
396 // CFG hash value for this function.
397 uint64_t FunctionHash;
398
399 // The Minimum Spanning Tree of function CFG.
400 CFGMST<Edge, BBInfo> MST;
401
402 // Give an edge, find the BB that will be instrumented.
403 // Return nullptr if there is no BB to be instrumented.
404 BasicBlock *getInstrBB(Edge *E);
405
406 // Return the auxiliary BB information.
407 BBInfo &getBBInfo(const BasicBlock *BB) const { return MST.getBBInfo(BB); }
408
Rong Xua5b57452016-12-02 19:10:29 +0000409 // Return the auxiliary BB information if available.
410 BBInfo *findBBInfo(const BasicBlock *BB) const { return MST.findBBInfo(BB); }
411
Rong Xuf430ae42015-12-09 18:08:16 +0000412 // Dump edges and BB information.
413 void dumpInfo(std::string Str = "") const {
414 MST.dumpEdges(dbgs(), Twine("Dump Function ") + FuncName + " Hash: " +
Rong Xued9fec72016-01-21 18:11:44 +0000415 Twine(FunctionHash) + "\t" + Str);
Rong Xuf430ae42015-12-09 18:08:16 +0000416 }
417
Rong Xu705f7772016-07-25 18:45:37 +0000418 FuncPGOInstrumentation(
419 Function &Func,
420 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
421 bool CreateGlobalVar = false, BranchProbabilityInfo *BPI = nullptr,
422 BlockFrequencyInfo *BFI = nullptr)
Rong Xua3bbf962017-03-15 18:23:39 +0000423 : F(Func), ComdatMembers(ComdatMembers), ValueSites(IPVK_Last + 1),
Rong Xu4ed52792017-03-15 21:47:27 +0000424 SIVisitor(Func), MIVisitor(Func), FunctionHash(0), MST(F, BPI, BFI) {
Xinliang David Li4ca17332016-09-18 18:34:07 +0000425
426 // This should be done before CFG hash computation.
427 SIVisitor.countSelects(Func);
Rong Xu4ed52792017-03-15 21:47:27 +0000428 MIVisitor.countMemIntrinsics(Func);
Xinliang David Li4ca17332016-09-18 18:34:07 +0000429 NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
Rong Xu4ed52792017-03-15 21:47:27 +0000430 NumOfPGOMemIntrinsics += MIVisitor.getNumOfMemIntrinsics();
Rong Xua3bbf962017-03-15 18:23:39 +0000431 ValueSites[IPVK_IndirectCallTarget] = findIndirectCallSites(Func);
Xinliang David Li4ca17332016-09-18 18:34:07 +0000432
Rong Xuf430ae42015-12-09 18:08:16 +0000433 FuncName = getPGOFuncName(F);
434 computeCFGHash();
Rong Xu705f7772016-07-25 18:45:37 +0000435 if (ComdatMembers.size())
436 renameComdatFunction();
Rong Xuf430ae42015-12-09 18:08:16 +0000437 DEBUG(dumpInfo("after CFGMST"));
438
439 NumOfPGOBB += MST.BBInfos.size();
440 for (auto &E : MST.AllEdges) {
441 if (E->Removed)
442 continue;
443 NumOfPGOEdge++;
444 if (!E->InMST)
445 NumOfPGOInstrument++;
446 }
447
448 if (CreateGlobalVar)
449 FuncNameVar = createPGOFuncNameVar(F, FuncName);
Eugene Zelenko6ac3f732016-01-26 18:48:36 +0000450 }
Xinliang David Lid1197612016-08-01 20:25:06 +0000451
452 // Return the number of profile counters needed for the function.
453 unsigned getNumCounters() {
454 unsigned NumCounters = 0;
455 for (auto &E : this->MST.AllEdges) {
456 if (!E->InMST && !E->Removed)
457 NumCounters++;
458 }
Xinliang David Li4ca17332016-09-18 18:34:07 +0000459 return NumCounters + SIVisitor.getNumOfSelectInsts();
Xinliang David Lid1197612016-08-01 20:25:06 +0000460 }
Rong Xuf430ae42015-12-09 18:08:16 +0000461};
462
463// Compute Hash value for the CFG: the lower 32 bits are CRC32 of the index
464// value of each BB in the CFG. The higher 32 bits record the number of edges.
465template <class Edge, class BBInfo>
466void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
467 std::vector<char> Indexes;
468 JamCRC JC;
469 for (auto &BB : F) {
470 const TerminatorInst *TI = BB.getTerminator();
471 for (unsigned I = 0, E = TI->getNumSuccessors(); I != E; ++I) {
472 BasicBlock *Succ = TI->getSuccessor(I);
Rong Xua5b57452016-12-02 19:10:29 +0000473 auto BI = findBBInfo(Succ);
474 if (BI == nullptr)
475 continue;
476 uint32_t Index = BI->Index;
Rong Xuf430ae42015-12-09 18:08:16 +0000477 for (int J = 0; J < 4; J++)
478 Indexes.push_back((char)(Index >> (J * 8)));
479 }
480 }
481 JC.update(Indexes);
Xinliang David Li4ca17332016-09-18 18:34:07 +0000482 FunctionHash = (uint64_t)SIVisitor.getNumOfSelectInsts() << 56 |
Rong Xua3bbf962017-03-15 18:23:39 +0000483 (uint64_t)ValueSites[IPVK_IndirectCallTarget].size() << 48 |
Rong Xu705f7772016-07-25 18:45:37 +0000484 (uint64_t)MST.AllEdges.size() << 32 | JC.getCRC();
485}
486
487// Check if we can safely rename this Comdat function.
488static bool canRenameComdat(
489 Function &F,
490 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
Rong Xu20f5df12017-01-11 20:19:41 +0000491 if (!DoComdatRenaming || !canRenameComdatFunc(F, true))
Rong Xu705f7772016-07-25 18:45:37 +0000492 return false;
Rong Xu705f7772016-07-25 18:45:37 +0000493
494 // FIXME: Current only handle those Comdat groups that only containing one
495 // function and function aliases.
496 // (1) For a Comdat group containing multiple functions, we need to have a
497 // unique postfix based on the hashes for each function. There is a
498 // non-trivial code refactoring to do this efficiently.
499 // (2) Variables can not be renamed, so we can not rename Comdat function in a
500 // group including global vars.
501 Comdat *C = F.getComdat();
502 for (auto &&CM : make_range(ComdatMembers.equal_range(C))) {
503 if (dyn_cast<GlobalAlias>(CM.second))
504 continue;
505 Function *FM = dyn_cast<Function>(CM.second);
506 if (FM != &F)
507 return false;
508 }
509 return true;
510}
511
512// Append the CFGHash to the Comdat function name.
513template <class Edge, class BBInfo>
514void FuncPGOInstrumentation<Edge, BBInfo>::renameComdatFunction() {
515 if (!canRenameComdat(F, ComdatMembers))
516 return;
Rong Xu0e79f7d2016-10-06 20:38:13 +0000517 std::string OrigName = F.getName().str();
Rong Xu705f7772016-07-25 18:45:37 +0000518 std::string NewFuncName =
519 Twine(F.getName() + "." + Twine(FunctionHash)).str();
520 F.setName(Twine(NewFuncName));
Rong Xu0e79f7d2016-10-06 20:38:13 +0000521 GlobalAlias::create(GlobalValue::WeakAnyLinkage, OrigName, &F);
Rong Xu705f7772016-07-25 18:45:37 +0000522 FuncName = Twine(FuncName + "." + Twine(FunctionHash)).str();
523 Comdat *NewComdat;
524 Module *M = F.getParent();
525 // For AvailableExternallyLinkage functions, change the linkage to
526 // LinkOnceODR and put them into comdat. This is because after renaming, there
527 // is no backup external copy available for the function.
528 if (!F.hasComdat()) {
529 assert(F.getLinkage() == GlobalValue::AvailableExternallyLinkage);
530 NewComdat = M->getOrInsertComdat(StringRef(NewFuncName));
531 F.setLinkage(GlobalValue::LinkOnceODRLinkage);
532 F.setComdat(NewComdat);
533 return;
534 }
535
536 // This function belongs to a single function Comdat group.
537 Comdat *OrigComdat = F.getComdat();
538 std::string NewComdatName =
539 Twine(OrigComdat->getName() + "." + Twine(FunctionHash)).str();
540 NewComdat = M->getOrInsertComdat(StringRef(NewComdatName));
541 NewComdat->setSelectionKind(OrigComdat->getSelectionKind());
542
543 for (auto &&CM : make_range(ComdatMembers.equal_range(OrigComdat))) {
544 if (GlobalAlias *GA = dyn_cast<GlobalAlias>(CM.second)) {
545 // For aliases, change the name directly.
546 assert(dyn_cast<Function>(GA->getAliasee()->stripPointerCasts()) == &F);
Rong Xu0e79f7d2016-10-06 20:38:13 +0000547 std::string OrigGAName = GA->getName().str();
Rong Xu705f7772016-07-25 18:45:37 +0000548 GA->setName(Twine(GA->getName() + "." + Twine(FunctionHash)));
Rong Xu0e79f7d2016-10-06 20:38:13 +0000549 GlobalAlias::create(GlobalValue::WeakAnyLinkage, OrigGAName, GA);
Rong Xu705f7772016-07-25 18:45:37 +0000550 continue;
551 }
552 // Must be a function.
553 Function *CF = dyn_cast<Function>(CM.second);
554 assert(CF);
555 CF->setComdat(NewComdat);
556 }
Rong Xuf430ae42015-12-09 18:08:16 +0000557}
558
559// Given a CFG E to be instrumented, find which BB to place the instrumented
560// code. The function will split the critical edge if necessary.
561template <class Edge, class BBInfo>
562BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *E) {
563 if (E->InMST || E->Removed)
564 return nullptr;
565
566 BasicBlock *SrcBB = const_cast<BasicBlock *>(E->SrcBB);
567 BasicBlock *DestBB = const_cast<BasicBlock *>(E->DestBB);
568 // For a fake edge, instrument the real BB.
569 if (SrcBB == nullptr)
570 return DestBB;
571 if (DestBB == nullptr)
572 return SrcBB;
573
574 // Instrument the SrcBB if it has a single successor,
575 // otherwise, the DestBB if this is not a critical edge.
576 TerminatorInst *TI = SrcBB->getTerminator();
577 if (TI->getNumSuccessors() <= 1)
578 return SrcBB;
579 if (!E->IsCritical)
580 return DestBB;
581
582 // For a critical edge, we have to split. Instrument the newly
583 // created BB.
584 NumOfPGOSplit++;
585 DEBUG(dbgs() << "Split critical edge: " << getBBInfo(SrcBB).Index << " --> "
586 << getBBInfo(DestBB).Index << "\n");
587 unsigned SuccNum = GetSuccessorNumber(SrcBB, DestBB);
588 BasicBlock *InstrBB = SplitCriticalEdge(TI, SuccNum);
589 assert(InstrBB && "Critical edge is not split");
590
591 E->Removed = true;
592 return InstrBB;
593}
594
Rong Xued9fec72016-01-21 18:11:44 +0000595// Visit all edge and instrument the edges not in MST, and do value profiling.
Rong Xuf430ae42015-12-09 18:08:16 +0000596// Critical edges will be split.
Rong Xu705f7772016-07-25 18:45:37 +0000597static void instrumentOneFunc(
598 Function &F, Module *M, BranchProbabilityInfo *BPI, BlockFrequencyInfo *BFI,
599 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
Rong Xu705f7772016-07-25 18:45:37 +0000600 FuncPGOInstrumentation<PGOEdge, BBInfo> FuncInfo(F, ComdatMembers, true, BPI,
601 BFI);
Xinliang David Lid1197612016-08-01 20:25:06 +0000602 unsigned NumCounters = FuncInfo.getNumCounters();
603
Rong Xuf430ae42015-12-09 18:08:16 +0000604 uint32_t I = 0;
Rong Xued9fec72016-01-21 18:11:44 +0000605 Type *I8PtrTy = Type::getInt8PtrTy(M->getContext());
Rong Xuf430ae42015-12-09 18:08:16 +0000606 for (auto &E : FuncInfo.MST.AllEdges) {
607 BasicBlock *InstrBB = FuncInfo.getInstrBB(E.get());
608 if (!InstrBB)
609 continue;
610
611 IRBuilder<> Builder(InstrBB, InstrBB->getFirstInsertionPt());
612 assert(Builder.GetInsertPoint() != InstrBB->end() &&
613 "Cannot get the Instrumentation point");
Rong Xuf430ae42015-12-09 18:08:16 +0000614 Builder.CreateCall(
615 Intrinsic::getDeclaration(M, Intrinsic::instrprof_increment),
616 {llvm::ConstantExpr::getBitCast(FuncInfo.FuncNameVar, I8PtrTy),
617 Builder.getInt64(FuncInfo.FunctionHash), Builder.getInt32(NumCounters),
618 Builder.getInt32(I++)});
619 }
Xinliang David Li4ca17332016-09-18 18:34:07 +0000620
621 // Now instrument select instructions:
622 FuncInfo.SIVisitor.instrumentSelects(F, &I, NumCounters, FuncInfo.FuncNameVar,
623 FuncInfo.FunctionHash);
Xinliang David Lid1197612016-08-01 20:25:06 +0000624 assert(I == NumCounters);
Rong Xued9fec72016-01-21 18:11:44 +0000625
626 if (DisableValueProfiling)
627 return;
628
629 unsigned NumIndirectCallSites = 0;
Rong Xua3bbf962017-03-15 18:23:39 +0000630 for (auto &I : FuncInfo.ValueSites[IPVK_IndirectCallTarget]) {
Rong Xued9fec72016-01-21 18:11:44 +0000631 CallSite CS(I);
632 Value *Callee = CS.getCalledValue();
633 DEBUG(dbgs() << "Instrument one indirect call: CallSite Index = "
634 << NumIndirectCallSites << "\n");
635 IRBuilder<> Builder(I);
636 assert(Builder.GetInsertPoint() != I->getParent()->end() &&
637 "Cannot get the Instrumentation point");
638 Builder.CreateCall(
639 Intrinsic::getDeclaration(M, Intrinsic::instrprof_value_profile),
640 {llvm::ConstantExpr::getBitCast(FuncInfo.FuncNameVar, I8PtrTy),
641 Builder.getInt64(FuncInfo.FunctionHash),
642 Builder.CreatePtrToInt(Callee, Builder.getInt64Ty()),
Rong Xua3bbf962017-03-15 18:23:39 +0000643 Builder.getInt32(IPVK_IndirectCallTarget),
Rong Xued9fec72016-01-21 18:11:44 +0000644 Builder.getInt32(NumIndirectCallSites++)});
645 }
646 NumOfPGOICall += NumIndirectCallSites;
Rong Xu4ed52792017-03-15 21:47:27 +0000647
648 // Now instrument memop intrinsic calls.
649 FuncInfo.MIVisitor.instrumentMemIntrinsics(
650 F, NumCounters, FuncInfo.FuncNameVar, FuncInfo.FunctionHash);
Rong Xuf430ae42015-12-09 18:08:16 +0000651}
652
653// This class represents a CFG edge in profile use compilation.
654struct PGOUseEdge : public PGOEdge {
655 bool CountValid;
656 uint64_t CountValue;
657 PGOUseEdge(const BasicBlock *Src, const BasicBlock *Dest, unsigned W = 1)
658 : PGOEdge(Src, Dest, W), CountValid(false), CountValue(0) {}
659
660 // Set edge count value
661 void setEdgeCount(uint64_t Value) {
662 CountValue = Value;
663 CountValid = true;
664 }
665
666 // Return the information string for this object.
667 const std::string infoString() const {
668 if (!CountValid)
669 return PGOEdge::infoString();
Rong Xu9e926e82016-02-29 19:16:04 +0000670 return (Twine(PGOEdge::infoString()) + " Count=" + Twine(CountValue))
671 .str();
Rong Xuf430ae42015-12-09 18:08:16 +0000672 }
673};
674
675typedef SmallVector<PGOUseEdge *, 2> DirectEdges;
676
677// This class stores the auxiliary information for each BB.
678struct UseBBInfo : public BBInfo {
679 uint64_t CountValue;
680 bool CountValid;
681 int32_t UnknownCountInEdge;
682 int32_t UnknownCountOutEdge;
683 DirectEdges InEdges;
684 DirectEdges OutEdges;
685 UseBBInfo(unsigned IX)
686 : BBInfo(IX), CountValue(0), CountValid(false), UnknownCountInEdge(0),
687 UnknownCountOutEdge(0) {}
688 UseBBInfo(unsigned IX, uint64_t C)
689 : BBInfo(IX), CountValue(C), CountValid(true), UnknownCountInEdge(0),
690 UnknownCountOutEdge(0) {}
691
692 // Set the profile count value for this BB.
693 void setBBInfoCount(uint64_t Value) {
694 CountValue = Value;
695 CountValid = true;
696 }
697
698 // Return the information string of this object.
699 const std::string infoString() const {
700 if (!CountValid)
701 return BBInfo::infoString();
702 return (Twine(BBInfo::infoString()) + " Count=" + Twine(CountValue)).str();
703 }
704};
705
706// Sum up the count values for all the edges.
707static uint64_t sumEdgeCount(const ArrayRef<PGOUseEdge *> Edges) {
708 uint64_t Total = 0;
709 for (auto &E : Edges) {
710 if (E->Removed)
711 continue;
712 Total += E->CountValue;
713 }
714 return Total;
715}
716
717class PGOUseFunc {
Rong Xu6090afd2016-03-28 17:08:56 +0000718public:
Rong Xu705f7772016-07-25 18:45:37 +0000719 PGOUseFunc(Function &Func, Module *Modu,
720 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
721 BranchProbabilityInfo *BPI = nullptr,
Rong Xu6090afd2016-03-28 17:08:56 +0000722 BlockFrequencyInfo *BFI = nullptr)
Rong Xu705f7772016-07-25 18:45:37 +0000723 : F(Func), M(Modu), FuncInfo(Func, ComdatMembers, false, BPI, BFI),
Rong Xu33308f92016-10-25 21:47:24 +0000724 CountPosition(0), ProfileCountSize(0), FreqAttr(FFA_Normal) {}
Rong Xu6090afd2016-03-28 17:08:56 +0000725
726 // Read counts for the instrumented BB from profile.
727 bool readCounters(IndexedInstrProfReader *PGOReader);
728
729 // Populate the counts for all BBs.
730 void populateCounters();
731
732 // Set the branch weights based on the count values.
733 void setBranchWeights();
734
Rong Xua3bbf962017-03-15 18:23:39 +0000735 // Annotate the value profile call sites all all value kind.
736 void annotateValueSites();
737
738 // Annotate the value profile call sites for one value kind.
739 void annotateValueSites(uint32_t Kind);
Rong Xu6090afd2016-03-28 17:08:56 +0000740
Sean Silva9dd4b5c2016-05-28 03:56:25 +0000741 // The hotness of the function from the profile count.
742 enum FuncFreqAttr { FFA_Normal, FFA_Cold, FFA_Hot };
743
744 // Return the function hotness from the profile.
745 FuncFreqAttr getFuncFreqAttr() const { return FreqAttr; }
746
Rong Xu705f7772016-07-25 18:45:37 +0000747 // Return the function hash.
748 uint64_t getFuncHash() const { return FuncInfo.FunctionHash; }
Easwaran Raman5fe04a12016-05-26 22:57:11 +0000749 // Return the profile record for this function;
750 InstrProfRecord &getProfileRecord() { return ProfileRecord; }
751
Xinliang David Li4ca17332016-09-18 18:34:07 +0000752 // Return the auxiliary BB information.
753 UseBBInfo &getBBInfo(const BasicBlock *BB) const {
754 return FuncInfo.getBBInfo(BB);
755 }
756
Rong Xua5b57452016-12-02 19:10:29 +0000757 // Return the auxiliary BB information if available.
758 UseBBInfo *findBBInfo(const BasicBlock *BB) const {
759 return FuncInfo.findBBInfo(BB);
760 }
761
Xinliang David Lid289e452017-01-27 19:06:25 +0000762 Function &getFunc() const { return F; }
763
Rong Xuf430ae42015-12-09 18:08:16 +0000764private:
765 Function &F;
766 Module *M;
767 // This member stores the shared information with class PGOGenFunc.
768 FuncPGOInstrumentation<PGOUseEdge, UseBBInfo> FuncInfo;
769
Sean Silva9dd4b5c2016-05-28 03:56:25 +0000770 // The maximum count value in the profile. This is only used in PGO use
771 // compilation.
772 uint64_t ProgramMaxCount;
773
Rong Xu33308f92016-10-25 21:47:24 +0000774 // Position of counter that remains to be read.
775 uint32_t CountPosition;
776
777 // Total size of the profile count for this function.
778 uint32_t ProfileCountSize;
779
Rong Xu13b01dc2016-02-10 18:24:45 +0000780 // ProfileRecord for this function.
781 InstrProfRecord ProfileRecord;
782
Sean Silva9dd4b5c2016-05-28 03:56:25 +0000783 // Function hotness info derived from profile.
784 FuncFreqAttr FreqAttr;
785
Rong Xuf430ae42015-12-09 18:08:16 +0000786 // Find the Instrumented BB and set the value.
787 void setInstrumentedCounts(const std::vector<uint64_t> &CountFromProfile);
788
789 // Set the edge counter value for the unknown edge -- there should be only
790 // one unknown edge.
791 void setEdgeCount(DirectEdges &Edges, uint64_t Value);
792
793 // Return FuncName string;
794 const std::string getFuncName() const { return FuncInfo.FuncName; }
Sean Silva9dd4b5c2016-05-28 03:56:25 +0000795
796 // Set the hot/cold inline hints based on the count values.
797 // FIXME: This function should be removed once the functionality in
798 // the inliner is implemented.
799 void markFunctionAttributes(uint64_t EntryCount, uint64_t MaxCount) {
800 if (ProgramMaxCount == 0)
801 return;
802 // Threshold of the hot functions.
803 const BranchProbability HotFunctionThreshold(1, 100);
804 // Threshold of the cold functions.
805 const BranchProbability ColdFunctionThreshold(2, 10000);
806 if (EntryCount >= HotFunctionThreshold.scale(ProgramMaxCount))
807 FreqAttr = FFA_Hot;
808 else if (MaxCount <= ColdFunctionThreshold.scale(ProgramMaxCount))
809 FreqAttr = FFA_Cold;
810 }
Rong Xuf430ae42015-12-09 18:08:16 +0000811};
812
813// Visit all the edges and assign the count value for the instrumented
814// edges and the BB.
815void PGOUseFunc::setInstrumentedCounts(
816 const std::vector<uint64_t> &CountFromProfile) {
817
Xinliang David Lid1197612016-08-01 20:25:06 +0000818 assert(FuncInfo.getNumCounters() == CountFromProfile.size());
Rong Xuf430ae42015-12-09 18:08:16 +0000819 // Use a worklist as we will update the vector during the iteration.
820 std::vector<PGOUseEdge *> WorkList;
821 for (auto &E : FuncInfo.MST.AllEdges)
822 WorkList.push_back(E.get());
823
824 uint32_t I = 0;
825 for (auto &E : WorkList) {
826 BasicBlock *InstrBB = FuncInfo.getInstrBB(E);
827 if (!InstrBB)
828 continue;
829 uint64_t CountValue = CountFromProfile[I++];
830 if (!E->Removed) {
831 getBBInfo(InstrBB).setBBInfoCount(CountValue);
832 E->setEdgeCount(CountValue);
833 continue;
834 }
835
836 // Need to add two new edges.
837 BasicBlock *SrcBB = const_cast<BasicBlock *>(E->SrcBB);
838 BasicBlock *DestBB = const_cast<BasicBlock *>(E->DestBB);
839 // Add new edge of SrcBB->InstrBB.
840 PGOUseEdge &NewEdge = FuncInfo.MST.addEdge(SrcBB, InstrBB, 0);
841 NewEdge.setEdgeCount(CountValue);
842 // Add new edge of InstrBB->DestBB.
843 PGOUseEdge &NewEdge1 = FuncInfo.MST.addEdge(InstrBB, DestBB, 0);
844 NewEdge1.setEdgeCount(CountValue);
845 NewEdge1.InMST = true;
846 getBBInfo(InstrBB).setBBInfoCount(CountValue);
847 }
Rong Xu0a2a1312017-03-09 19:08:55 +0000848 ProfileCountSize = CountFromProfile.size();
Rong Xu33308f92016-10-25 21:47:24 +0000849 CountPosition = I;
Rong Xuf430ae42015-12-09 18:08:16 +0000850}
851
852// Set the count value for the unknown edge. There should be one and only one
853// unknown edge in Edges vector.
854void PGOUseFunc::setEdgeCount(DirectEdges &Edges, uint64_t Value) {
855 for (auto &E : Edges) {
856 if (E->CountValid)
857 continue;
858 E->setEdgeCount(Value);
859
860 getBBInfo(E->SrcBB).UnknownCountOutEdge--;
861 getBBInfo(E->DestBB).UnknownCountInEdge--;
862 return;
863 }
864 llvm_unreachable("Cannot find the unknown count edge");
865}
866
867// Read the profile from ProfileFileName and assign the value to the
868// instrumented BB and the edges. This function also updates ProgramMaxCount.
869// Return true if the profile are successfully read, and false on errors.
870bool PGOUseFunc::readCounters(IndexedInstrProfReader *PGOReader) {
871 auto &Ctx = M->getContext();
Vedant Kumar9152fd12016-05-19 03:54:45 +0000872 Expected<InstrProfRecord> Result =
Rong Xuf430ae42015-12-09 18:08:16 +0000873 PGOReader->getInstrProfRecord(FuncInfo.FuncName, FuncInfo.FunctionHash);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000874 if (Error E = Result.takeError()) {
875 handleAllErrors(std::move(E), [&](const InstrProfError &IPE) {
876 auto Err = IPE.get();
877 bool SkipWarning = false;
878 if (Err == instrprof_error::unknown_function) {
879 NumOfPGOMissing++;
Xinliang David Li76a01082016-08-11 05:09:30 +0000880 SkipWarning = !PGOWarnMissing;
Vedant Kumar9152fd12016-05-19 03:54:45 +0000881 } else if (Err == instrprof_error::hash_mismatch ||
882 Err == instrprof_error::malformed) {
883 NumOfPGOMismatch++;
Rong Xu20f5df12017-01-11 20:19:41 +0000884 SkipWarning =
885 NoPGOWarnMismatch ||
886 (NoPGOWarnMismatchComdat &&
887 (F.hasComdat() ||
888 F.getLinkage() == GlobalValue::AvailableExternallyLinkage));
Vedant Kumar9152fd12016-05-19 03:54:45 +0000889 }
Rong Xuf430ae42015-12-09 18:08:16 +0000890
Vedant Kumar9152fd12016-05-19 03:54:45 +0000891 if (SkipWarning)
892 return;
893
894 std::string Msg = IPE.message() + std::string(" ") + F.getName().str();
895 Ctx.diagnose(
896 DiagnosticInfoPGOProfile(M->getName().data(), Msg, DS_Warning));
897 });
Rong Xuf430ae42015-12-09 18:08:16 +0000898 return false;
899 }
Rong Xu13b01dc2016-02-10 18:24:45 +0000900 ProfileRecord = std::move(Result.get());
901 std::vector<uint64_t> &CountFromProfile = ProfileRecord.Counts;
Rong Xuf430ae42015-12-09 18:08:16 +0000902
903 NumOfPGOFunc++;
904 DEBUG(dbgs() << CountFromProfile.size() << " counts\n");
905 uint64_t ValueSum = 0;
906 for (unsigned I = 0, S = CountFromProfile.size(); I < S; I++) {
907 DEBUG(dbgs() << " " << I << ": " << CountFromProfile[I] << "\n");
908 ValueSum += CountFromProfile[I];
909 }
910
911 DEBUG(dbgs() << "SUM = " << ValueSum << "\n");
912
913 getBBInfo(nullptr).UnknownCountOutEdge = 2;
914 getBBInfo(nullptr).UnknownCountInEdge = 2;
915
916 setInstrumentedCounts(CountFromProfile);
Sean Silva9dd4b5c2016-05-28 03:56:25 +0000917 ProgramMaxCount = PGOReader->getMaximumFunctionCount();
Rong Xuf430ae42015-12-09 18:08:16 +0000918 return true;
919}
920
921// Populate the counters from instrumented BBs to all BBs.
922// In the end of this operation, all BBs should have a valid count value.
923void PGOUseFunc::populateCounters() {
924 // First set up Count variable for all BBs.
925 for (auto &E : FuncInfo.MST.AllEdges) {
926 if (E->Removed)
927 continue;
928
929 const BasicBlock *SrcBB = E->SrcBB;
930 const BasicBlock *DestBB = E->DestBB;
931 UseBBInfo &SrcInfo = getBBInfo(SrcBB);
932 UseBBInfo &DestInfo = getBBInfo(DestBB);
933 SrcInfo.OutEdges.push_back(E.get());
934 DestInfo.InEdges.push_back(E.get());
935 SrcInfo.UnknownCountOutEdge++;
936 DestInfo.UnknownCountInEdge++;
937
938 if (!E->CountValid)
939 continue;
940 DestInfo.UnknownCountInEdge--;
941 SrcInfo.UnknownCountOutEdge--;
942 }
943
944 bool Changes = true;
945 unsigned NumPasses = 0;
946 while (Changes) {
947 NumPasses++;
948 Changes = false;
949
950 // For efficient traversal, it's better to start from the end as most
951 // of the instrumented edges are at the end.
952 for (auto &BB : reverse(F)) {
Rong Xua5b57452016-12-02 19:10:29 +0000953 UseBBInfo *Count = findBBInfo(&BB);
954 if (Count == nullptr)
955 continue;
956 if (!Count->CountValid) {
957 if (Count->UnknownCountOutEdge == 0) {
958 Count->CountValue = sumEdgeCount(Count->OutEdges);
959 Count->CountValid = true;
Rong Xuf430ae42015-12-09 18:08:16 +0000960 Changes = true;
Rong Xua5b57452016-12-02 19:10:29 +0000961 } else if (Count->UnknownCountInEdge == 0) {
962 Count->CountValue = sumEdgeCount(Count->InEdges);
963 Count->CountValid = true;
Rong Xuf430ae42015-12-09 18:08:16 +0000964 Changes = true;
965 }
966 }
Rong Xua5b57452016-12-02 19:10:29 +0000967 if (Count->CountValid) {
968 if (Count->UnknownCountOutEdge == 1) {
Rong Xu51a1e3c2016-12-13 06:41:14 +0000969 uint64_t Total = 0;
970 uint64_t OutSum = sumEdgeCount(Count->OutEdges);
971 // If the one of the successor block can early terminate (no-return),
972 // we can end up with situation where out edge sum count is larger as
973 // the source BB's count is collected by a post-dominated block.
974 if (Count->CountValue > OutSum)
975 Total = Count->CountValue - OutSum;
Rong Xua5b57452016-12-02 19:10:29 +0000976 setEdgeCount(Count->OutEdges, Total);
Rong Xuf430ae42015-12-09 18:08:16 +0000977 Changes = true;
978 }
Rong Xua5b57452016-12-02 19:10:29 +0000979 if (Count->UnknownCountInEdge == 1) {
Rong Xu51a1e3c2016-12-13 06:41:14 +0000980 uint64_t Total = 0;
981 uint64_t InSum = sumEdgeCount(Count->InEdges);
982 if (Count->CountValue > InSum)
983 Total = Count->CountValue - InSum;
Rong Xua5b57452016-12-02 19:10:29 +0000984 setEdgeCount(Count->InEdges, Total);
Rong Xuf430ae42015-12-09 18:08:16 +0000985 Changes = true;
986 }
987 }
988 }
989 }
990
991 DEBUG(dbgs() << "Populate counts in " << NumPasses << " passes.\n");
Sean Silva8c7e1212016-05-28 04:19:45 +0000992#ifndef NDEBUG
Sean Silva9dd4b5c2016-05-28 03:56:25 +0000993 // Assert every BB has a valid counter.
Rong Xua5b57452016-12-02 19:10:29 +0000994 for (auto &BB : F) {
995 auto BI = findBBInfo(&BB);
996 if (BI == nullptr)
997 continue;
998 assert(BI->CountValid && "BB count is not valid");
999 }
Sean Silva8c7e1212016-05-28 04:19:45 +00001000#endif
Sean Silva9dd4b5c2016-05-28 03:56:25 +00001001 uint64_t FuncEntryCount = getBBInfo(&*F.begin()).CountValue;
Sean Silva02b9d892016-05-28 04:05:36 +00001002 F.setEntryCount(FuncEntryCount);
Sean Silva9dd4b5c2016-05-28 03:56:25 +00001003 uint64_t FuncMaxCount = FuncEntryCount;
Rong Xua5b57452016-12-02 19:10:29 +00001004 for (auto &BB : F) {
1005 auto BI = findBBInfo(&BB);
1006 if (BI == nullptr)
1007 continue;
1008 FuncMaxCount = std::max(FuncMaxCount, BI->CountValue);
1009 }
Sean Silva9dd4b5c2016-05-28 03:56:25 +00001010 markFunctionAttributes(FuncEntryCount, FuncMaxCount);
Rong Xuf430ae42015-12-09 18:08:16 +00001011
Rong Xu33308f92016-10-25 21:47:24 +00001012 // Now annotate select instructions
1013 FuncInfo.SIVisitor.annotateSelects(F, this, &CountPosition);
1014 assert(CountPosition == ProfileCountSize);
1015
Rong Xuf430ae42015-12-09 18:08:16 +00001016 DEBUG(FuncInfo.dumpInfo("after reading profile."));
1017}
1018
Xinliang David Li4ca17332016-09-18 18:34:07 +00001019static void setProfMetadata(Module *M, Instruction *TI,
Xinliang David Li63248ab2016-08-19 06:31:45 +00001020 ArrayRef<uint64_t> EdgeCounts, uint64_t MaxCount) {
Xinliang David Li2c933682016-08-19 05:31:33 +00001021 MDBuilder MDB(M->getContext());
1022 assert(MaxCount > 0 && "Bad max count");
1023 uint64_t Scale = calculateCountScale(MaxCount);
1024 SmallVector<unsigned, 4> Weights;
1025 for (const auto &ECI : EdgeCounts)
1026 Weights.push_back(scaleBranchCount(ECI, Scale));
1027
1028 DEBUG(dbgs() << "Weight is: ";
Rong Xu0a2a1312017-03-09 19:08:55 +00001029 for (const auto &W : Weights) { dbgs() << W << " "; }
Xinliang David Li2c933682016-08-19 05:31:33 +00001030 dbgs() << "\n";);
1031 TI->setMetadata(llvm::LLVMContext::MD_prof, MDB.createBranchWeights(Weights));
1032}
1033
Rong Xuf430ae42015-12-09 18:08:16 +00001034// Assign the scaled count values to the BB with multiple out edges.
1035void PGOUseFunc::setBranchWeights() {
1036 // Generate MD_prof metadata for every branch instruction.
1037 DEBUG(dbgs() << "\nSetting branch weights.\n");
Rong Xuf430ae42015-12-09 18:08:16 +00001038 for (auto &BB : F) {
1039 TerminatorInst *TI = BB.getTerminator();
1040 if (TI->getNumSuccessors() < 2)
1041 continue;
1042 if (!isa<BranchInst>(TI) && !isa<SwitchInst>(TI))
1043 continue;
1044 if (getBBInfo(&BB).CountValue == 0)
1045 continue;
1046
1047 // We have a non-zero Branch BB.
1048 const UseBBInfo &BBCountInfo = getBBInfo(&BB);
1049 unsigned Size = BBCountInfo.OutEdges.size();
Xinliang David Li63248ab2016-08-19 06:31:45 +00001050 SmallVector<uint64_t, 2> EdgeCounts(Size, 0);
Rong Xuf430ae42015-12-09 18:08:16 +00001051 uint64_t MaxCount = 0;
1052 for (unsigned s = 0; s < Size; s++) {
1053 const PGOUseEdge *E = BBCountInfo.OutEdges[s];
1054 const BasicBlock *SrcBB = E->SrcBB;
1055 const BasicBlock *DestBB = E->DestBB;
Eugene Zelenko6ac3f732016-01-26 18:48:36 +00001056 if (DestBB == nullptr)
Rong Xuf430ae42015-12-09 18:08:16 +00001057 continue;
1058 unsigned SuccNum = GetSuccessorNumber(SrcBB, DestBB);
1059 uint64_t EdgeCount = E->CountValue;
1060 if (EdgeCount > MaxCount)
1061 MaxCount = EdgeCount;
1062 EdgeCounts[SuccNum] = EdgeCount;
1063 }
Xinliang David Li2c933682016-08-19 05:31:33 +00001064 setProfMetadata(M, TI, EdgeCounts, MaxCount);
Rong Xuf430ae42015-12-09 18:08:16 +00001065 }
1066}
Rong Xu13b01dc2016-02-10 18:24:45 +00001067
Xinliang David Li4ca17332016-09-18 18:34:07 +00001068void SelectInstVisitor::instrumentOneSelectInst(SelectInst &SI) {
1069 Module *M = F.getParent();
1070 IRBuilder<> Builder(&SI);
1071 Type *Int64Ty = Builder.getInt64Ty();
1072 Type *I8PtrTy = Builder.getInt8PtrTy();
1073 auto *Step = Builder.CreateZExt(SI.getCondition(), Int64Ty);
1074 Builder.CreateCall(
1075 Intrinsic::getDeclaration(M, Intrinsic::instrprof_increment_step),
1076 {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
Rong Xu0a2a1312017-03-09 19:08:55 +00001077 Builder.getInt64(FuncHash), Builder.getInt32(TotalNumCtrs),
1078 Builder.getInt32(*CurCtrIdx), Step});
Xinliang David Li4ca17332016-09-18 18:34:07 +00001079 ++(*CurCtrIdx);
1080}
1081
1082void SelectInstVisitor::annotateOneSelectInst(SelectInst &SI) {
1083 std::vector<uint64_t> &CountFromProfile = UseFunc->getProfileRecord().Counts;
1084 assert(*CurCtrIdx < CountFromProfile.size() &&
1085 "Out of bound access of counters");
1086 uint64_t SCounts[2];
1087 SCounts[0] = CountFromProfile[*CurCtrIdx]; // True count
1088 ++(*CurCtrIdx);
Rong Xua5b57452016-12-02 19:10:29 +00001089 uint64_t TotalCount = 0;
1090 auto BI = UseFunc->findBBInfo(SI.getParent());
1091 if (BI != nullptr)
1092 TotalCount = BI->CountValue;
Xinliang David Li4ca17332016-09-18 18:34:07 +00001093 // False Count
1094 SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0);
1095 uint64_t MaxCount = std::max(SCounts[0], SCounts[1]);
Xinliang David Lic7368282016-09-20 20:20:01 +00001096 if (MaxCount)
1097 setProfMetadata(F.getParent(), &SI, SCounts, MaxCount);
Xinliang David Li4ca17332016-09-18 18:34:07 +00001098}
1099
1100void SelectInstVisitor::visitSelectInst(SelectInst &SI) {
1101 if (!PGOInstrSelect)
1102 return;
1103 // FIXME: do not handle this yet.
1104 if (SI.getCondition()->getType()->isVectorTy())
1105 return;
1106
Vitaly Bukade85ad82017-03-15 23:06:22 +00001107 NSIs++;
Xinliang David Li4ca17332016-09-18 18:34:07 +00001108 switch (Mode) {
1109 case VM_counting:
1110 return;
1111 case VM_instrument:
1112 instrumentOneSelectInst(SI);
Simon Pilgrimf33a6b72016-09-18 21:08:35 +00001113 return;
Xinliang David Li4ca17332016-09-18 18:34:07 +00001114 case VM_annotate:
1115 annotateOneSelectInst(SI);
Simon Pilgrimf33a6b72016-09-18 21:08:35 +00001116 return;
Xinliang David Li4ca17332016-09-18 18:34:07 +00001117 }
Simon Pilgrimf33a6b72016-09-18 21:08:35 +00001118
1119 llvm_unreachable("Unknown visiting mode");
Xinliang David Li4ca17332016-09-18 18:34:07 +00001120}
1121
Rong Xu4ed52792017-03-15 21:47:27 +00001122void MemIntrinsicVisitor::instrumentOneMemIntrinsic(MemIntrinsic &MI) {
1123 Module *M = F.getParent();
1124 IRBuilder<> Builder(&MI);
1125 Type *Int64Ty = Builder.getInt64Ty();
1126 Type *I8PtrTy = Builder.getInt8PtrTy();
1127 Value *Length = MI.getLength();
1128 assert(!dyn_cast<ConstantInt>(Length));
1129 Builder.CreateCall(
1130 Intrinsic::getDeclaration(M, Intrinsic::instrprof_value_profile),
1131 {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
1132 Builder.getInt64(FuncHash), Builder.CreatePtrToInt(Length, Int64Ty),
1133 Builder.getInt32(IPVK_MemOPSize), Builder.getInt32(CurCtrId)});
1134 ++CurCtrId;
1135}
1136
1137void MemIntrinsicVisitor::visitMemIntrinsic(MemIntrinsic &MI) {
1138 if (!PGOInstrMemOP)
1139 return;
1140 Value *Length = MI.getLength();
1141 // Not instrument constant length calls.
1142 if (dyn_cast<ConstantInt>(Length))
1143 return;
1144
1145 NMemIs++;
1146 switch (Mode) {
1147 case VM_counting:
1148 return;
1149 case VM_instrument:
1150 instrumentOneMemIntrinsic(MI);
1151 return;
1152 case VM_annotate:
1153 break;
1154 }
1155 llvm_unreachable("Unknown visiting mode");
1156}
1157
Rong Xua3bbf962017-03-15 18:23:39 +00001158// Traverse all valuesites and annotate the instructions for all value kind.
1159void PGOUseFunc::annotateValueSites() {
Rong Xu13b01dc2016-02-10 18:24:45 +00001160 if (DisableValueProfiling)
1161 return;
1162
Rong Xu8e8fe852016-04-01 16:43:30 +00001163 // Create the PGOFuncName meta data.
Rong Xuf8f051c2016-04-22 21:00:17 +00001164 createPGOFuncNameMetadata(F, FuncInfo.FuncName);
Rong Xub5341662016-03-30 18:37:52 +00001165
Rong Xua3bbf962017-03-15 18:23:39 +00001166 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
1167 annotateValueSites(Kind);
1168}
1169
1170// Annotate the instructions for a specific value kind.
1171void PGOUseFunc::annotateValueSites(uint32_t Kind) {
1172 unsigned ValueSiteIndex = 0;
1173 auto &ValueSites = FuncInfo.ValueSites[Kind];
1174 unsigned NumValueSites = ProfileRecord.getNumValueSites(Kind);
1175 if (NumValueSites != ValueSites.size()) {
Rong Xu13b01dc2016-02-10 18:24:45 +00001176 auto &Ctx = M->getContext();
Rong Xua3bbf962017-03-15 18:23:39 +00001177 Ctx.diagnose(DiagnosticInfoPGOProfile(
1178 M->getName().data(),
1179 Twine("Inconsistent number of value sites for kind = ") + Twine(Kind) +
1180 " in " + F.getName().str(),
1181 DS_Warning));
Rong Xu13b01dc2016-02-10 18:24:45 +00001182 return;
1183 }
1184
Rong Xua3bbf962017-03-15 18:23:39 +00001185 for (auto &I : ValueSites) {
1186 DEBUG(dbgs() << "Read one value site profile (kind = " << Kind
1187 << "): Index = " << ValueSiteIndex << " out of "
1188 << NumValueSites << "\n");
1189 annotateValueSite(*M, *I, ProfileRecord,
1190 static_cast<InstrProfValueKind>(Kind), ValueSiteIndex,
1191 MaxNumAnnotations);
1192 ValueSiteIndex++;
Rong Xu13b01dc2016-02-10 18:24:45 +00001193 }
1194}
Rong Xuf430ae42015-12-09 18:08:16 +00001195} // end anonymous namespace
1196
Xinliang David Lid382e9d2016-07-22 04:46:56 +00001197// Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime
Rong Xu33c76c02016-02-10 17:18:30 +00001198// aware this is an ir_level profile so it can set the version flag.
1199static void createIRLevelProfileFlagVariable(Module &M) {
1200 Type *IntTy64 = Type::getInt64Ty(M.getContext());
1201 uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF);
Rong Xu9e926e82016-02-29 19:16:04 +00001202 auto IRLevelVersionVariable = new GlobalVariable(
1203 M, IntTy64, true, GlobalVariable::ExternalLinkage,
1204 Constant::getIntegerValue(IntTy64, APInt(64, ProfileVersion)),
Xinliang David Lid382e9d2016-07-22 04:46:56 +00001205 INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
Rong Xu33c76c02016-02-10 17:18:30 +00001206 IRLevelVersionVariable->setVisibility(GlobalValue::DefaultVisibility);
1207 Triple TT(M.getTargetTriple());
Xinliang David Li11c849c2016-05-27 16:22:03 +00001208 if (!TT.supportsCOMDAT())
Rong Xuca28a0a2016-05-11 00:31:59 +00001209 IRLevelVersionVariable->setLinkage(GlobalValue::WeakAnyLinkage);
Rong Xu33c76c02016-02-10 17:18:30 +00001210 else
Rong Xu9e926e82016-02-29 19:16:04 +00001211 IRLevelVersionVariable->setComdat(M.getOrInsertComdat(
Xinliang David Lid382e9d2016-07-22 04:46:56 +00001212 StringRef(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR))));
Rong Xu33c76c02016-02-10 17:18:30 +00001213}
1214
Rong Xu705f7772016-07-25 18:45:37 +00001215// Collect the set of members for each Comdat in module M and store
1216// in ComdatMembers.
1217static void collectComdatMembers(
1218 Module &M,
1219 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
1220 if (!DoComdatRenaming)
1221 return;
1222 for (Function &F : M)
1223 if (Comdat *C = F.getComdat())
1224 ComdatMembers.insert(std::make_pair(C, &F));
1225 for (GlobalVariable &GV : M.globals())
1226 if (Comdat *C = GV.getComdat())
1227 ComdatMembers.insert(std::make_pair(C, &GV));
1228 for (GlobalAlias &GA : M.aliases())
1229 if (Comdat *C = GA.getComdat())
1230 ComdatMembers.insert(std::make_pair(C, &GA));
1231}
1232
Xinliang David Li5ad7c822016-05-02 20:33:59 +00001233static bool InstrumentAllFunctions(
Xinliang David Lidfa21c32016-05-09 21:37:12 +00001234 Module &M, function_ref<BranchProbabilityInfo *(Function &)> LookupBPI,
1235 function_ref<BlockFrequencyInfo *(Function &)> LookupBFI) {
Rong Xu33c76c02016-02-10 17:18:30 +00001236 createIRLevelProfileFlagVariable(M);
Rong Xu705f7772016-07-25 18:45:37 +00001237 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
1238 collectComdatMembers(M, ComdatMembers);
1239
Rong Xuf430ae42015-12-09 18:08:16 +00001240 for (auto &F : M) {
1241 if (F.isDeclaration())
1242 continue;
Xinliang David Lidfa21c32016-05-09 21:37:12 +00001243 auto *BPI = LookupBPI(F);
1244 auto *BFI = LookupBFI(F);
Rong Xu705f7772016-07-25 18:45:37 +00001245 instrumentOneFunc(F, &M, BPI, BFI, ComdatMembers);
Rong Xuf430ae42015-12-09 18:08:16 +00001246 }
1247 return true;
1248}
1249
Xinliang David Li8aebf442016-05-06 05:49:19 +00001250bool PGOInstrumentationGenLegacyPass::runOnModule(Module &M) {
Xinliang David Li5ad7c822016-05-02 20:33:59 +00001251 if (skipModule(M))
1252 return false;
1253
Xinliang David Lidfa21c32016-05-09 21:37:12 +00001254 auto LookupBPI = [this](Function &F) {
1255 return &this->getAnalysis<BranchProbabilityInfoWrapperPass>(F).getBPI();
Xinliang David Li5ad7c822016-05-02 20:33:59 +00001256 };
Xinliang David Lidfa21c32016-05-09 21:37:12 +00001257 auto LookupBFI = [this](Function &F) {
1258 return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI();
Xinliang David Li5ad7c822016-05-02 20:33:59 +00001259 };
1260 return InstrumentAllFunctions(M, LookupBPI, LookupBFI);
1261}
1262
Xinliang David Li8aebf442016-05-06 05:49:19 +00001263PreservedAnalyses PGOInstrumentationGen::run(Module &M,
Sean Silvafd03ac62016-08-09 00:28:38 +00001264 ModuleAnalysisManager &AM) {
Xinliang David Li8aebf442016-05-06 05:49:19 +00001265
1266 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
Xinliang David Lidfa21c32016-05-09 21:37:12 +00001267 auto LookupBPI = [&FAM](Function &F) {
1268 return &FAM.getResult<BranchProbabilityAnalysis>(F);
Xinliang David Li8aebf442016-05-06 05:49:19 +00001269 };
1270
Xinliang David Lidfa21c32016-05-09 21:37:12 +00001271 auto LookupBFI = [&FAM](Function &F) {
1272 return &FAM.getResult<BlockFrequencyAnalysis>(F);
Xinliang David Li8aebf442016-05-06 05:49:19 +00001273 };
1274
1275 if (!InstrumentAllFunctions(M, LookupBPI, LookupBFI))
1276 return PreservedAnalyses::all();
1277
1278 return PreservedAnalyses::none();
1279}
1280
Xinliang David Lida195582016-05-10 21:59:52 +00001281static bool annotateAllFunctions(
1282 Module &M, StringRef ProfileFileName,
1283 function_ref<BranchProbabilityInfo *(Function &)> LookupBPI,
Xinliang David Lidfa21c32016-05-09 21:37:12 +00001284 function_ref<BlockFrequencyInfo *(Function &)> LookupBFI) {
Rong Xuf430ae42015-12-09 18:08:16 +00001285 DEBUG(dbgs() << "Read in profile counters: ");
1286 auto &Ctx = M.getContext();
1287 // Read the counter array from file.
1288 auto ReaderOrErr = IndexedInstrProfReader::create(ProfileFileName);
Vedant Kumar9152fd12016-05-19 03:54:45 +00001289 if (Error E = ReaderOrErr.takeError()) {
1290 handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
1291 Ctx.diagnose(
1292 DiagnosticInfoPGOProfile(ProfileFileName.data(), EI.message()));
1293 });
Rong Xuf430ae42015-12-09 18:08:16 +00001294 return false;
1295 }
1296
Xinliang David Lida195582016-05-10 21:59:52 +00001297 std::unique_ptr<IndexedInstrProfReader> PGOReader =
1298 std::move(ReaderOrErr.get());
Rong Xuf430ae42015-12-09 18:08:16 +00001299 if (!PGOReader) {
1300 Ctx.diagnose(DiagnosticInfoPGOProfile(ProfileFileName.data(),
Xinliang David Lida195582016-05-10 21:59:52 +00001301 StringRef("Cannot get PGOReader")));
Rong Xuf430ae42015-12-09 18:08:16 +00001302 return false;
1303 }
Rong Xu33c76c02016-02-10 17:18:30 +00001304 // TODO: might need to change the warning once the clang option is finalized.
1305 if (!PGOReader->isIRLevelProfile()) {
1306 Ctx.diagnose(DiagnosticInfoPGOProfile(
1307 ProfileFileName.data(), "Not an IR level instrumentation profile"));
1308 return false;
1309 }
1310
Rong Xu705f7772016-07-25 18:45:37 +00001311 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
1312 collectComdatMembers(M, ComdatMembers);
Rong Xu6090afd2016-03-28 17:08:56 +00001313 std::vector<Function *> HotFunctions;
1314 std::vector<Function *> ColdFunctions;
Rong Xuf430ae42015-12-09 18:08:16 +00001315 for (auto &F : M) {
1316 if (F.isDeclaration())
1317 continue;
Xinliang David Lidfa21c32016-05-09 21:37:12 +00001318 auto *BPI = LookupBPI(F);
1319 auto *BFI = LookupBFI(F);
Rong Xu705f7772016-07-25 18:45:37 +00001320 PGOUseFunc Func(F, &M, ComdatMembers, BPI, BFI);
Sean Silva2e8f0952016-05-28 04:19:40 +00001321 if (!Func.readCounters(PGOReader.get()))
1322 continue;
1323 Func.populateCounters();
1324 Func.setBranchWeights();
Rong Xua3bbf962017-03-15 18:23:39 +00001325 Func.annotateValueSites();
Sean Silva9dd4b5c2016-05-28 03:56:25 +00001326 PGOUseFunc::FuncFreqAttr FreqAttr = Func.getFuncFreqAttr();
1327 if (FreqAttr == PGOUseFunc::FFA_Cold)
Sean Silva2a730192016-05-28 03:02:50 +00001328 ColdFunctions.push_back(&F);
Sean Silva9dd4b5c2016-05-28 03:56:25 +00001329 else if (FreqAttr == PGOUseFunc::FFA_Hot)
1330 HotFunctions.push_back(&F);
Xinliang David Li58fcc9b2017-02-02 21:29:17 +00001331 if (PGOViewCounts && (ViewBlockFreqFuncName.empty() ||
1332 F.getName().equals(ViewBlockFreqFuncName))) {
Xinliang David Licb253ce2017-01-23 18:58:24 +00001333 LoopInfo LI{DominatorTree(F)};
1334 std::unique_ptr<BranchProbabilityInfo> NewBPI =
1335 llvm::make_unique<BranchProbabilityInfo>(F, LI);
1336 std::unique_ptr<BlockFrequencyInfo> NewBFI =
1337 llvm::make_unique<BlockFrequencyInfo>(F, *NewBPI, LI);
1338
1339 NewBFI->view();
1340 }
Xinliang David Li58fcc9b2017-02-02 21:29:17 +00001341 if (PGOViewRawCounts && (ViewBlockFreqFuncName.empty() ||
1342 F.getName().equals(ViewBlockFreqFuncName))) {
1343 if (ViewBlockFreqFuncName.empty())
Xinliang David Lid289e452017-01-27 19:06:25 +00001344 WriteGraph(&Func, Twine("PGORawCounts_") + Func.getFunc().getName());
1345 else
1346 ViewGraph(&Func, Twine("PGORawCounts_") + Func.getFunc().getName());
1347 }
Rong Xuf430ae42015-12-09 18:08:16 +00001348 }
Easwaran Raman8bceb9d2016-06-21 19:29:49 +00001349 M.setProfileSummary(PGOReader->getSummary().getMD(M.getContext()));
Rong Xu6090afd2016-03-28 17:08:56 +00001350 // Set function hotness attribute from the profile.
Sean Silva42cc3422016-05-28 04:24:39 +00001351 // We have to apply these attributes at the end because their presence
1352 // can affect the BranchProbabilityInfo of any callers, resulting in an
1353 // inconsistent MST between prof-gen and prof-use.
Rong Xu6090afd2016-03-28 17:08:56 +00001354 for (auto &F : HotFunctions) {
1355 F->addFnAttr(llvm::Attribute::InlineHint);
1356 DEBUG(dbgs() << "Set inline attribute to function: " << F->getName()
1357 << "\n");
1358 }
1359 for (auto &F : ColdFunctions) {
1360 F->addFnAttr(llvm::Attribute::Cold);
1361 DEBUG(dbgs() << "Set cold attribute to function: " << F->getName() << "\n");
1362 }
Rong Xuf430ae42015-12-09 18:08:16 +00001363 return true;
1364}
Xinliang David Lid55827f2016-05-07 05:39:12 +00001365
Xinliang David Lida195582016-05-10 21:59:52 +00001366PGOInstrumentationUse::PGOInstrumentationUse(std::string Filename)
Benjamin Kramer82de7d32016-05-27 14:27:24 +00001367 : ProfileFileName(std::move(Filename)) {
Xinliang David Lida195582016-05-10 21:59:52 +00001368 if (!PGOTestProfileFile.empty())
1369 ProfileFileName = PGOTestProfileFile;
1370}
1371
1372PreservedAnalyses PGOInstrumentationUse::run(Module &M,
Sean Silvafd03ac62016-08-09 00:28:38 +00001373 ModuleAnalysisManager &AM) {
Xinliang David Lida195582016-05-10 21:59:52 +00001374
1375 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
1376 auto LookupBPI = [&FAM](Function &F) {
1377 return &FAM.getResult<BranchProbabilityAnalysis>(F);
1378 };
1379
1380 auto LookupBFI = [&FAM](Function &F) {
1381 return &FAM.getResult<BlockFrequencyAnalysis>(F);
1382 };
1383
1384 if (!annotateAllFunctions(M, ProfileFileName, LookupBPI, LookupBFI))
1385 return PreservedAnalyses::all();
1386
1387 return PreservedAnalyses::none();
1388}
1389
Xinliang David Lid55827f2016-05-07 05:39:12 +00001390bool PGOInstrumentationUseLegacyPass::runOnModule(Module &M) {
1391 if (skipModule(M))
1392 return false;
1393
Xinliang David Lidfa21c32016-05-09 21:37:12 +00001394 auto LookupBPI = [this](Function &F) {
1395 return &this->getAnalysis<BranchProbabilityInfoWrapperPass>(F).getBPI();
Xinliang David Lid55827f2016-05-07 05:39:12 +00001396 };
Xinliang David Lidfa21c32016-05-09 21:37:12 +00001397 auto LookupBFI = [this](Function &F) {
1398 return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI();
Xinliang David Lid55827f2016-05-07 05:39:12 +00001399 };
1400
Xinliang David Lida195582016-05-10 21:59:52 +00001401 return annotateAllFunctions(M, ProfileFileName, LookupBPI, LookupBFI);
Xinliang David Lid55827f2016-05-07 05:39:12 +00001402}
Xinliang David Lid289e452017-01-27 19:06:25 +00001403
1404namespace llvm {
1405template <> struct GraphTraits<PGOUseFunc *> {
1406 typedef const BasicBlock *NodeRef;
1407 typedef succ_const_iterator ChildIteratorType;
1408 typedef pointer_iterator<Function::const_iterator> nodes_iterator;
1409
1410 static NodeRef getEntryNode(const PGOUseFunc *G) {
1411 return &G->getFunc().front();
1412 }
1413 static ChildIteratorType child_begin(const NodeRef N) {
1414 return succ_begin(N);
1415 }
1416 static ChildIteratorType child_end(const NodeRef N) { return succ_end(N); }
1417 static nodes_iterator nodes_begin(const PGOUseFunc *G) {
1418 return nodes_iterator(G->getFunc().begin());
1419 }
1420 static nodes_iterator nodes_end(const PGOUseFunc *G) {
1421 return nodes_iterator(G->getFunc().end());
1422 }
1423};
1424
Xinliang David Li6144a592017-02-03 21:57:51 +00001425static std::string getSimpleNodeName(const BasicBlock *Node) {
1426 if (!Node->getName().empty())
1427 return Node->getName();
1428
1429 std::string SimpleNodeName;
1430 raw_string_ostream OS(SimpleNodeName);
1431 Node->printAsOperand(OS, false);
1432 return OS.str();
1433}
1434
Xinliang David Lid289e452017-01-27 19:06:25 +00001435template <> struct DOTGraphTraits<PGOUseFunc *> : DefaultDOTGraphTraits {
1436 explicit DOTGraphTraits(bool isSimple = false)
1437 : DefaultDOTGraphTraits(isSimple) {}
1438
1439 static std::string getGraphName(const PGOUseFunc *G) {
1440 return G->getFunc().getName();
1441 }
1442
1443 std::string getNodeLabel(const BasicBlock *Node, const PGOUseFunc *Graph) {
1444 std::string Result;
1445 raw_string_ostream OS(Result);
Xinliang David Li6144a592017-02-03 21:57:51 +00001446
1447 OS << getSimpleNodeName(Node) << ":\\l";
Xinliang David Lid289e452017-01-27 19:06:25 +00001448 UseBBInfo *BI = Graph->findBBInfo(Node);
Xinliang David Li6144a592017-02-03 21:57:51 +00001449 OS << "Count : ";
Xinliang David Lid289e452017-01-27 19:06:25 +00001450 if (BI && BI->CountValid)
Xinliang David Li6144a592017-02-03 21:57:51 +00001451 OS << BI->CountValue << "\\l";
Xinliang David Lid289e452017-01-27 19:06:25 +00001452 else
Xinliang David Li6144a592017-02-03 21:57:51 +00001453 OS << "Unknown\\l";
1454
1455 if (!PGOInstrSelect)
1456 return Result;
1457
1458 for (auto BI = Node->begin(); BI != Node->end(); ++BI) {
1459 auto *I = &*BI;
1460 if (!isa<SelectInst>(I))
1461 continue;
1462 // Display scaled counts for SELECT instruction:
1463 OS << "SELECT : { T = ";
1464 uint64_t TC, FC;
Xinliang David Lic7db0d02017-02-04 07:40:43 +00001465 bool HasProf = I->extractProfMetadata(TC, FC);
1466 if (!HasProf)
Xinliang David Li6144a592017-02-03 21:57:51 +00001467 OS << "Unknown, F = Unknown }\\l";
1468 else
1469 OS << TC << ", F = " << FC << " }\\l";
1470 }
Xinliang David Lid289e452017-01-27 19:06:25 +00001471 return Result;
1472 }
1473};
Rong Xu0a2a1312017-03-09 19:08:55 +00001474} // namespace llvm