blob: 38774332f31d687bb8817fb7640997640cc0366e [file] [log] [blame]
Justin Bogneref512b92014-01-06 22:27:43 +00001//===--- CodeGenPGO.cpp - PGO Instrumentation for LLVM CodeGen --*- C++ -*-===//
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// Instrumentation-based profile-guided optimization
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenPGO.h"
15#include "CodeGenFunction.h"
Alex Lorenzee024992014-08-04 18:41:51 +000016#include "CoverageMappingGen.h"
Justin Bogneref512b92014-01-06 22:27:43 +000017#include "clang/AST/RecursiveASTVisitor.h"
18#include "clang/AST/StmtVisitor.h"
Justin Bogner970ac602014-12-08 19:04:51 +000019#include "llvm/IR/Intrinsics.h"
Justin Bogneref512b92014-01-06 22:27:43 +000020#include "llvm/IR/MDBuilder.h"
Justin Bogner837a6f62014-04-18 21:52:00 +000021#include "llvm/ProfileData/InstrProfReader.h"
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +000022#include "llvm/Support/Endian.h"
Justin Bogneref512b92014-01-06 22:27:43 +000023#include "llvm/Support/FileSystem.h"
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +000024#include "llvm/Support/MD5.h"
Justin Bogneref512b92014-01-06 22:27:43 +000025
26using namespace clang;
27using namespace CodeGen;
28
Alex Lorenzee024992014-08-04 18:41:51 +000029void CodeGenPGO::setFuncName(StringRef Name,
30 llvm::GlobalValue::LinkageTypes Linkage) {
Xinliang David Lia569e242015-12-05 05:37:15 +000031 llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
32 FuncName = llvm::getPGOFuncName(
33 Name, Linkage, CGM.getCodeGenOpts().MainFileName,
34 PGOReader ? PGOReader->getVersion() : llvm::IndexedInstrProf::Version);
Justin Bogner970ac602014-12-08 19:04:51 +000035
36 // If we're generating a profile, create a variable for the name.
37 if (CGM.getCodeGenOpts().ProfileInstrGenerate)
Xinliang David Li2d7ec5a2015-11-09 00:04:16 +000038 FuncNameVar = llvm::createPGOFuncNameVar(CGM.getModule(), Linkage, FuncName);
Bob Wilsonda1ebed2014-03-06 04:55:41 +000039}
40
Alex Lorenzee024992014-08-04 18:41:51 +000041void CodeGenPGO::setFuncName(llvm::Function *Fn) {
42 setFuncName(Fn->getName(), Fn->getLinkage());
43}
44
Justin Bogneref512b92014-01-06 22:27:43 +000045namespace {
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +000046/// \brief Stable hasher for PGO region counters.
47///
48/// PGOHash produces a stable hash of a given function's control flow.
49///
50/// Changing the output of this hash will invalidate all previously generated
51/// profiles -- i.e., don't do it.
52///
53/// \note When this hash does eventually change (years?), we still need to
54/// support old hashes. We'll need to pull in the version number from the
55/// profile data format and use the matching hash function.
56class PGOHash {
57 uint64_t Working;
58 unsigned Count;
59 llvm::MD5 MD5;
60
61 static const int NumBitsPerType = 6;
62 static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
63 static const unsigned TooBig = 1u << NumBitsPerType;
64
65public:
66 /// \brief Hash values for AST nodes.
67 ///
68 /// Distinct values for AST nodes that have region counters attached.
69 ///
70 /// These values must be stable. All new members must be added at the end,
71 /// and no members should be removed. Changing the enumeration value for an
72 /// AST node will affect the hash of every function that contains that node.
73 enum HashType : unsigned char {
74 None = 0,
75 LabelStmt = 1,
76 WhileStmt,
77 DoStmt,
78 ForStmt,
79 CXXForRangeStmt,
80 ObjCForCollectionStmt,
81 SwitchStmt,
82 CaseStmt,
83 DefaultStmt,
84 IfStmt,
85 CXXTryStmt,
86 CXXCatchStmt,
87 ConditionalOperator,
88 BinaryOperatorLAnd,
89 BinaryOperatorLOr,
90 BinaryConditionalOperator,
91
92 // Keep this last. It's for the static assert that follows.
93 LastHashType
94 };
95 static_assert(LastHashType <= TooBig, "Too many types in HashType");
96
97 // TODO: When this format changes, take in a version number here, and use the
98 // old hash calculation for file formats that used the old hash.
99 PGOHash() : Working(0), Count(0) {}
100 void combine(HashType Type);
101 uint64_t finalize();
102};
103const int PGOHash::NumBitsPerType;
104const unsigned PGOHash::NumTypesPerWord;
105const unsigned PGOHash::TooBig;
106
Justin Bognere4ca4412015-02-23 19:27:00 +0000107/// A RecursiveASTVisitor that fills a map of statements to PGO counters.
108struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
109 /// The next counter value to assign.
110 unsigned NextCounter;
111 /// The function hash.
112 PGOHash Hash;
113 /// The map of statements to counters.
114 llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
Justin Bogneref512b92014-01-06 22:27:43 +0000115
Justin Bognere4ca4412015-02-23 19:27:00 +0000116 MapRegionCounters(llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
117 : NextCounter(0), CounterMap(CounterMap) {}
Justin Bogneref512b92014-01-06 22:27:43 +0000118
Justin Bognere4ca4412015-02-23 19:27:00 +0000119 // Blocks and lambdas are handled as separate functions, so we need not
120 // traverse them in the parent context.
121 bool TraverseBlockExpr(BlockExpr *BE) { return true; }
122 bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
123 bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
Justin Bogneref512b92014-01-06 22:27:43 +0000124
Justin Bognere4ca4412015-02-23 19:27:00 +0000125 bool VisitDecl(const Decl *D) {
126 switch (D->getKind()) {
127 default:
128 break;
129 case Decl::Function:
130 case Decl::CXXMethod:
131 case Decl::CXXConstructor:
132 case Decl::CXXDestructor:
133 case Decl::CXXConversion:
134 case Decl::ObjCMethod:
135 case Decl::Block:
136 case Decl::Captured:
137 CounterMap[D->getBody()] = NextCounter++;
138 break;
139 }
140 return true;
141 }
142
143 bool VisitStmt(const Stmt *S) {
144 auto Type = getHashType(S);
145 if (Type == PGOHash::None)
Bob Wilsond8931422014-04-11 17:16:13 +0000146 return true;
Bob Wilsond8931422014-04-11 17:16:13 +0000147
Justin Bognere4ca4412015-02-23 19:27:00 +0000148 CounterMap[S] = NextCounter++;
149 Hash.combine(Type);
150 return true;
151 }
152 PGOHash::HashType getHashType(const Stmt *S) {
153 switch (S->getStmtClass()) {
154 default:
155 break;
156 case Stmt::LabelStmtClass:
157 return PGOHash::LabelStmt;
158 case Stmt::WhileStmtClass:
159 return PGOHash::WhileStmt;
160 case Stmt::DoStmtClass:
161 return PGOHash::DoStmt;
162 case Stmt::ForStmtClass:
163 return PGOHash::ForStmt;
164 case Stmt::CXXForRangeStmtClass:
165 return PGOHash::CXXForRangeStmt;
166 case Stmt::ObjCForCollectionStmtClass:
167 return PGOHash::ObjCForCollectionStmt;
168 case Stmt::SwitchStmtClass:
169 return PGOHash::SwitchStmt;
170 case Stmt::CaseStmtClass:
171 return PGOHash::CaseStmt;
172 case Stmt::DefaultStmtClass:
173 return PGOHash::DefaultStmt;
174 case Stmt::IfStmtClass:
175 return PGOHash::IfStmt;
176 case Stmt::CXXTryStmtClass:
177 return PGOHash::CXXTryStmt;
178 case Stmt::CXXCatchStmtClass:
179 return PGOHash::CXXCatchStmt;
180 case Stmt::ConditionalOperatorClass:
181 return PGOHash::ConditionalOperator;
182 case Stmt::BinaryConditionalOperatorClass:
183 return PGOHash::BinaryConditionalOperator;
184 case Stmt::BinaryOperatorClass: {
185 const BinaryOperator *BO = cast<BinaryOperator>(S);
186 if (BO->getOpcode() == BO_LAnd)
187 return PGOHash::BinaryOperatorLAnd;
188 if (BO->getOpcode() == BO_LOr)
189 return PGOHash::BinaryOperatorLOr;
190 break;
191 }
192 }
193 return PGOHash::None;
194 }
195};
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000196
Justin Bognere4ca4412015-02-23 19:27:00 +0000197/// A StmtVisitor that propagates the raw counts through the AST and
198/// records the count at statements where the value may change.
199struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
200 /// PGO state.
201 CodeGenPGO &PGO;
202
203 /// A flag that is set when the current count should be recorded on the
204 /// next statement, such as at the exit of a loop.
205 bool RecordNextStmtCount;
206
Justin Bognera909abf2015-05-02 00:48:27 +0000207 /// The count at the current location in the traversal.
208 uint64_t CurrentCount;
209
Justin Bognere4ca4412015-02-23 19:27:00 +0000210 /// The map of statements to count values.
211 llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
212
213 /// BreakContinueStack - Keep counts of breaks and continues inside loops.
214 struct BreakContinue {
215 uint64_t BreakCount;
216 uint64_t ContinueCount;
217 BreakContinue() : BreakCount(0), ContinueCount(0) {}
Justin Bogneref512b92014-01-06 22:27:43 +0000218 };
Justin Bognere4ca4412015-02-23 19:27:00 +0000219 SmallVector<BreakContinue, 8> BreakContinueStack;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000220
Justin Bognere4ca4412015-02-23 19:27:00 +0000221 ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
222 CodeGenPGO &PGO)
223 : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
Bob Wilsonbf854f02014-02-17 19:21:09 +0000224
Justin Bognere4ca4412015-02-23 19:27:00 +0000225 void RecordStmtCount(const Stmt *S) {
226 if (RecordNextStmtCount) {
Justin Bognera909abf2015-05-02 00:48:27 +0000227 CountMap[S] = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000228 RecordNextStmtCount = false;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000229 }
Justin Bognere4ca4412015-02-23 19:27:00 +0000230 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000231
Justin Bogner07193cc2015-05-01 23:41:09 +0000232 /// Set and return the current count.
233 uint64_t setCount(uint64_t Count) {
Justin Bognera909abf2015-05-02 00:48:27 +0000234 CurrentCount = Count;
Justin Bogner07193cc2015-05-01 23:41:09 +0000235 return Count;
236 }
237
Justin Bognere4ca4412015-02-23 19:27:00 +0000238 void VisitStmt(const Stmt *S) {
239 RecordStmtCount(S);
Benjamin Kramer642f1732015-07-02 21:03:14 +0000240 for (const Stmt *Child : S->children())
241 if (Child)
242 this->Visit(Child);
Justin Bognere4ca4412015-02-23 19:27:00 +0000243 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000244
Justin Bognere4ca4412015-02-23 19:27:00 +0000245 void VisitFunctionDecl(const FunctionDecl *D) {
246 // Counter tracks entry to the function body.
Justin Bogner07193cc2015-05-01 23:41:09 +0000247 uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
248 CountMap[D->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000249 Visit(D->getBody());
250 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000251
Justin Bognere4ca4412015-02-23 19:27:00 +0000252 // Skip lambda expressions. We visit these as FunctionDecls when we're
253 // generating them and aren't interested in the body when generating a
254 // parent context.
255 void VisitLambdaExpr(const LambdaExpr *LE) {}
Bob Wilsonbf854f02014-02-17 19:21:09 +0000256
Justin Bognere4ca4412015-02-23 19:27:00 +0000257 void VisitCapturedDecl(const CapturedDecl *D) {
258 // Counter tracks entry to the capture body.
Justin Bogner07193cc2015-05-01 23:41:09 +0000259 uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
260 CountMap[D->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000261 Visit(D->getBody());
262 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000263
Justin Bognere4ca4412015-02-23 19:27:00 +0000264 void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
265 // Counter tracks entry to the method body.
Justin Bogner07193cc2015-05-01 23:41:09 +0000266 uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
267 CountMap[D->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000268 Visit(D->getBody());
269 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000270
Justin Bognere4ca4412015-02-23 19:27:00 +0000271 void VisitBlockDecl(const BlockDecl *D) {
272 // Counter tracks entry to the block body.
Justin Bogner07193cc2015-05-01 23:41:09 +0000273 uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
274 CountMap[D->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000275 Visit(D->getBody());
276 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000277
Justin Bognere4ca4412015-02-23 19:27:00 +0000278 void VisitReturnStmt(const ReturnStmt *S) {
279 RecordStmtCount(S);
280 if (S->getRetValue())
281 Visit(S->getRetValue());
Justin Bognera909abf2015-05-02 00:48:27 +0000282 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000283 RecordNextStmtCount = true;
284 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000285
Justin Bognerf959feb2015-04-28 06:31:55 +0000286 void VisitCXXThrowExpr(const CXXThrowExpr *E) {
287 RecordStmtCount(E);
288 if (E->getSubExpr())
289 Visit(E->getSubExpr());
Justin Bognera909abf2015-05-02 00:48:27 +0000290 CurrentCount = 0;
Justin Bognerf959feb2015-04-28 06:31:55 +0000291 RecordNextStmtCount = true;
292 }
293
Justin Bognere4ca4412015-02-23 19:27:00 +0000294 void VisitGotoStmt(const GotoStmt *S) {
295 RecordStmtCount(S);
Justin Bognera909abf2015-05-02 00:48:27 +0000296 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000297 RecordNextStmtCount = true;
298 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000299
Justin Bognere4ca4412015-02-23 19:27:00 +0000300 void VisitLabelStmt(const LabelStmt *S) {
301 RecordNextStmtCount = false;
302 // Counter tracks the block following the label.
Justin Bogner07193cc2015-05-01 23:41:09 +0000303 uint64_t BlockCount = setCount(PGO.getRegionCount(S));
304 CountMap[S] = BlockCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000305 Visit(S->getSubStmt());
306 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000307
Justin Bognere4ca4412015-02-23 19:27:00 +0000308 void VisitBreakStmt(const BreakStmt *S) {
309 RecordStmtCount(S);
310 assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
Justin Bognera909abf2015-05-02 00:48:27 +0000311 BreakContinueStack.back().BreakCount += CurrentCount;
312 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000313 RecordNextStmtCount = true;
314 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000315
Justin Bognere4ca4412015-02-23 19:27:00 +0000316 void VisitContinueStmt(const ContinueStmt *S) {
317 RecordStmtCount(S);
318 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
Justin Bognera909abf2015-05-02 00:48:27 +0000319 BreakContinueStack.back().ContinueCount += CurrentCount;
320 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000321 RecordNextStmtCount = true;
322 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000323
Justin Bognere4ca4412015-02-23 19:27:00 +0000324 void VisitWhileStmt(const WhileStmt *S) {
325 RecordStmtCount(S);
Justin Bognera909abf2015-05-02 00:48:27 +0000326 uint64_t ParentCount = CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000327
Justin Bognere4ca4412015-02-23 19:27:00 +0000328 BreakContinueStack.push_back(BreakContinue());
329 // Visit the body region first so the break/continue adjustments can be
330 // included when visiting the condition.
Justin Bogner07193cc2015-05-01 23:41:09 +0000331 uint64_t BodyCount = setCount(PGO.getRegionCount(S));
Justin Bognera909abf2015-05-02 00:48:27 +0000332 CountMap[S->getBody()] = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000333 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000334 uint64_t BackedgeCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000335
336 // ...then go back and propagate counts through the condition. The count
337 // at the start of the condition is the sum of the incoming edges,
338 // the backedge from the end of the loop body, and the edges from
339 // continue statements.
340 BreakContinue BC = BreakContinueStack.pop_back_val();
Justin Bogner07193cc2015-05-01 23:41:09 +0000341 uint64_t CondCount =
342 setCount(ParentCount + BackedgeCount + BC.ContinueCount);
343 CountMap[S->getCond()] = CondCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000344 Visit(S->getCond());
Justin Bogner07193cc2015-05-01 23:41:09 +0000345 setCount(BC.BreakCount + CondCount - BodyCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000346 RecordNextStmtCount = true;
347 }
348
349 void VisitDoStmt(const DoStmt *S) {
350 RecordStmtCount(S);
Justin Bogner07193cc2015-05-01 23:41:09 +0000351 uint64_t LoopCount = PGO.getRegionCount(S);
352
Justin Bognere4ca4412015-02-23 19:27:00 +0000353 BreakContinueStack.push_back(BreakContinue());
Justin Bogner07193cc2015-05-01 23:41:09 +0000354 // The count doesn't include the fallthrough from the parent scope. Add it.
Justin Bognera909abf2015-05-02 00:48:27 +0000355 uint64_t BodyCount = setCount(LoopCount + CurrentCount);
Justin Bogner07193cc2015-05-01 23:41:09 +0000356 CountMap[S->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000357 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000358 uint64_t BackedgeCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000359
360 BreakContinue BC = BreakContinueStack.pop_back_val();
361 // The count at the start of the condition is equal to the count at the
Justin Bogner07193cc2015-05-01 23:41:09 +0000362 // end of the body, plus any continues.
363 uint64_t CondCount = setCount(BackedgeCount + BC.ContinueCount);
364 CountMap[S->getCond()] = CondCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000365 Visit(S->getCond());
Justin Bogner07193cc2015-05-01 23:41:09 +0000366 setCount(BC.BreakCount + CondCount - LoopCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000367 RecordNextStmtCount = true;
368 }
369
370 void VisitForStmt(const ForStmt *S) {
371 RecordStmtCount(S);
372 if (S->getInit())
373 Visit(S->getInit());
Justin Bogner07193cc2015-05-01 23:41:09 +0000374
Justin Bognera909abf2015-05-02 00:48:27 +0000375 uint64_t ParentCount = CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000376
Justin Bognere4ca4412015-02-23 19:27:00 +0000377 BreakContinueStack.push_back(BreakContinue());
378 // Visit the body region first. (This is basically the same as a while
379 // loop; see further comments in VisitWhileStmt.)
Justin Bogner07193cc2015-05-01 23:41:09 +0000380 uint64_t BodyCount = setCount(PGO.getRegionCount(S));
381 CountMap[S->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000382 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000383 uint64_t BackedgeCount = CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000384 BreakContinue BC = BreakContinueStack.pop_back_val();
Justin Bognere4ca4412015-02-23 19:27:00 +0000385
386 // The increment is essentially part of the body but it needs to include
387 // the count for all the continue statements.
388 if (S->getInc()) {
Justin Bogner07193cc2015-05-01 23:41:09 +0000389 uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
390 CountMap[S->getInc()] = IncCount;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000391 Visit(S->getInc());
Justin Bognere4ca4412015-02-23 19:27:00 +0000392 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000393
Justin Bognere4ca4412015-02-23 19:27:00 +0000394 // ...then go back and propagate counts through the condition.
Justin Bogner07193cc2015-05-01 23:41:09 +0000395 uint64_t CondCount =
396 setCount(ParentCount + BackedgeCount + BC.ContinueCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000397 if (S->getCond()) {
Justin Bogner07193cc2015-05-01 23:41:09 +0000398 CountMap[S->getCond()] = CondCount;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000399 Visit(S->getCond());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000400 }
Justin Bogner07193cc2015-05-01 23:41:09 +0000401 setCount(BC.BreakCount + CondCount - BodyCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000402 RecordNextStmtCount = true;
403 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000404
Justin Bognere4ca4412015-02-23 19:27:00 +0000405 void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
406 RecordStmtCount(S);
Justin Bogner2e5d4842015-04-30 22:58:28 +0000407 Visit(S->getLoopVarStmt());
Justin Bognere4ca4412015-02-23 19:27:00 +0000408 Visit(S->getRangeStmt());
409 Visit(S->getBeginEndStmt());
Justin Bogner07193cc2015-05-01 23:41:09 +0000410
Justin Bognera909abf2015-05-02 00:48:27 +0000411 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000412 BreakContinueStack.push_back(BreakContinue());
413 // Visit the body region first. (This is basically the same as a while
414 // loop; see further comments in VisitWhileStmt.)
Justin Bogner07193cc2015-05-01 23:41:09 +0000415 uint64_t BodyCount = setCount(PGO.getRegionCount(S));
416 CountMap[S->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000417 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000418 uint64_t BackedgeCount = CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000419 BreakContinue BC = BreakContinueStack.pop_back_val();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000420
Justin Bognere4ca4412015-02-23 19:27:00 +0000421 // The increment is essentially part of the body but it needs to include
422 // the count for all the continue statements.
Justin Bogner07193cc2015-05-01 23:41:09 +0000423 uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
424 CountMap[S->getInc()] = IncCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000425 Visit(S->getInc());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000426
Justin Bognere4ca4412015-02-23 19:27:00 +0000427 // ...then go back and propagate counts through the condition.
Justin Bogner07193cc2015-05-01 23:41:09 +0000428 uint64_t CondCount =
429 setCount(ParentCount + BackedgeCount + BC.ContinueCount);
430 CountMap[S->getCond()] = CondCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000431 Visit(S->getCond());
Justin Bogner07193cc2015-05-01 23:41:09 +0000432 setCount(BC.BreakCount + CondCount - BodyCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000433 RecordNextStmtCount = true;
434 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000435
Justin Bognere4ca4412015-02-23 19:27:00 +0000436 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
437 RecordStmtCount(S);
438 Visit(S->getElement());
Justin Bognera909abf2015-05-02 00:48:27 +0000439 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000440 BreakContinueStack.push_back(BreakContinue());
Justin Bogner07193cc2015-05-01 23:41:09 +0000441 // Counter tracks the body of the loop.
442 uint64_t BodyCount = setCount(PGO.getRegionCount(S));
443 CountMap[S->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000444 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000445 uint64_t BackedgeCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000446 BreakContinue BC = BreakContinueStack.pop_back_val();
Justin Bogner07193cc2015-05-01 23:41:09 +0000447
448 setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount -
449 BodyCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000450 RecordNextStmtCount = true;
451 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000452
Justin Bognere4ca4412015-02-23 19:27:00 +0000453 void VisitSwitchStmt(const SwitchStmt *S) {
454 RecordStmtCount(S);
455 Visit(S->getCond());
Justin Bognera909abf2015-05-02 00:48:27 +0000456 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000457 BreakContinueStack.push_back(BreakContinue());
458 Visit(S->getBody());
459 // If the switch is inside a loop, add the continue counts.
460 BreakContinue BC = BreakContinueStack.pop_back_val();
461 if (!BreakContinueStack.empty())
462 BreakContinueStack.back().ContinueCount += BC.ContinueCount;
463 // Counter tracks the exit block of the switch.
Justin Bogner07193cc2015-05-01 23:41:09 +0000464 setCount(PGO.getRegionCount(S));
Justin Bognere4ca4412015-02-23 19:27:00 +0000465 RecordNextStmtCount = true;
466 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000467
Justin Bogner07193cc2015-05-01 23:41:09 +0000468 void VisitSwitchCase(const SwitchCase *S) {
Justin Bognere4ca4412015-02-23 19:27:00 +0000469 RecordNextStmtCount = false;
470 // Counter for this particular case. This counts only jumps from the
471 // switch header and does not include fallthrough from the case before
472 // this one.
Justin Bogner07193cc2015-05-01 23:41:09 +0000473 uint64_t CaseCount = PGO.getRegionCount(S);
Justin Bognera909abf2015-05-02 00:48:27 +0000474 setCount(CurrentCount + CaseCount);
Justin Bogner07193cc2015-05-01 23:41:09 +0000475 // We need the count without fallthrough in the mapping, so it's more useful
476 // for branch probabilities.
477 CountMap[S] = CaseCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000478 RecordNextStmtCount = true;
479 Visit(S->getSubStmt());
480 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000481
Justin Bognere4ca4412015-02-23 19:27:00 +0000482 void VisitIfStmt(const IfStmt *S) {
483 RecordStmtCount(S);
Justin Bognera909abf2015-05-02 00:48:27 +0000484 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000485 Visit(S->getCond());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000486
Justin Bogner07193cc2015-05-01 23:41:09 +0000487 // Counter tracks the "then" part of an if statement. The count for
488 // the "else" part, if it exists, will be calculated from this counter.
489 uint64_t ThenCount = setCount(PGO.getRegionCount(S));
490 CountMap[S->getThen()] = ThenCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000491 Visit(S->getThen());
Justin Bognera909abf2015-05-02 00:48:27 +0000492 uint64_t OutCount = CurrentCount;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000493
Justin Bogner07193cc2015-05-01 23:41:09 +0000494 uint64_t ElseCount = ParentCount - ThenCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000495 if (S->getElse()) {
Justin Bogner07193cc2015-05-01 23:41:09 +0000496 setCount(ElseCount);
497 CountMap[S->getElse()] = ElseCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000498 Visit(S->getElse());
Justin Bognera909abf2015-05-02 00:48:27 +0000499 OutCount += CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000500 } else
501 OutCount += ElseCount;
502 setCount(OutCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000503 RecordNextStmtCount = true;
504 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000505
Justin Bognere4ca4412015-02-23 19:27:00 +0000506 void VisitCXXTryStmt(const CXXTryStmt *S) {
507 RecordStmtCount(S);
508 Visit(S->getTryBlock());
509 for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
510 Visit(S->getHandler(I));
511 // Counter tracks the continuation block of the try statement.
Justin Bogner07193cc2015-05-01 23:41:09 +0000512 setCount(PGO.getRegionCount(S));
Justin Bognere4ca4412015-02-23 19:27:00 +0000513 RecordNextStmtCount = true;
514 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000515
Justin Bognere4ca4412015-02-23 19:27:00 +0000516 void VisitCXXCatchStmt(const CXXCatchStmt *S) {
517 RecordNextStmtCount = false;
518 // Counter tracks the catch statement's handler block.
Justin Bogner07193cc2015-05-01 23:41:09 +0000519 uint64_t CatchCount = setCount(PGO.getRegionCount(S));
520 CountMap[S] = CatchCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000521 Visit(S->getHandlerBlock());
522 }
523
524 void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
525 RecordStmtCount(E);
Justin Bognera909abf2015-05-02 00:48:27 +0000526 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000527 Visit(E->getCond());
528
Justin Bogner07193cc2015-05-01 23:41:09 +0000529 // Counter tracks the "true" part of a conditional operator. The
530 // count in the "false" part will be calculated from this counter.
531 uint64_t TrueCount = setCount(PGO.getRegionCount(E));
532 CountMap[E->getTrueExpr()] = TrueCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000533 Visit(E->getTrueExpr());
Justin Bognera909abf2015-05-02 00:48:27 +0000534 uint64_t OutCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000535
Justin Bogner07193cc2015-05-01 23:41:09 +0000536 uint64_t FalseCount = setCount(ParentCount - TrueCount);
537 CountMap[E->getFalseExpr()] = FalseCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000538 Visit(E->getFalseExpr());
Justin Bognera909abf2015-05-02 00:48:27 +0000539 OutCount += CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000540
Justin Bogner07193cc2015-05-01 23:41:09 +0000541 setCount(OutCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000542 RecordNextStmtCount = true;
543 }
544
545 void VisitBinLAnd(const BinaryOperator *E) {
546 RecordStmtCount(E);
Justin Bognera909abf2015-05-02 00:48:27 +0000547 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000548 Visit(E->getLHS());
Justin Bogner07193cc2015-05-01 23:41:09 +0000549 // Counter tracks the right hand side of a logical and operator.
550 uint64_t RHSCount = setCount(PGO.getRegionCount(E));
551 CountMap[E->getRHS()] = RHSCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000552 Visit(E->getRHS());
Justin Bognera909abf2015-05-02 00:48:27 +0000553 setCount(ParentCount + RHSCount - CurrentCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000554 RecordNextStmtCount = true;
555 }
556
557 void VisitBinLOr(const BinaryOperator *E) {
558 RecordStmtCount(E);
Justin Bognera909abf2015-05-02 00:48:27 +0000559 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000560 Visit(E->getLHS());
Justin Bogner07193cc2015-05-01 23:41:09 +0000561 // Counter tracks the right hand side of a logical or operator.
562 uint64_t RHSCount = setCount(PGO.getRegionCount(E));
563 CountMap[E->getRHS()] = RHSCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000564 Visit(E->getRHS());
Justin Bognera909abf2015-05-02 00:48:27 +0000565 setCount(ParentCount + RHSCount - CurrentCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000566 RecordNextStmtCount = true;
567 }
568};
Hans Wennborgdcfba332015-10-06 23:40:43 +0000569} // end anonymous namespace
Justin Bogneref512b92014-01-06 22:27:43 +0000570
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000571void PGOHash::combine(HashType Type) {
572 // Check that we never combine 0 and only have six bits.
573 assert(Type && "Hash is invalid: unexpected type 0");
574 assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
575
576 // Pass through MD5 if enough work has built up.
577 if (Count && Count % NumTypesPerWord == 0) {
578 using namespace llvm::support;
579 uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
580 MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
581 Working = 0;
582 }
583
584 // Accumulate the current type.
585 ++Count;
586 Working = Working << NumBitsPerType | Type;
587}
588
589uint64_t PGOHash::finalize() {
590 // Use Working as the hash directly if we never used MD5.
591 if (Count <= NumTypesPerWord)
592 // No need to byte swap here, since none of the math was endian-dependent.
593 // This number will be byte-swapped as required on endianness transitions,
594 // so we will see the same value on the other side.
595 return Working;
596
597 // Check for remaining work in Working.
598 if (Working)
599 MD5.update(Working);
600
601 // Finalize the MD5 and return the hash.
602 llvm::MD5::MD5Result Result;
603 MD5.final(Result);
604 using namespace llvm::support;
605 return endian::read<uint64_t, little, unaligned>(Result);
606}
607
Serge Pavlov3a561452015-12-06 14:32:39 +0000608void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
609 const Decl *D = GD.getDecl();
Justin Bogneref512b92014-01-06 22:27:43 +0000610 bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
Justin Bogner837a6f62014-04-18 21:52:00 +0000611 llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
612 if (!InstrumentRegions && !PGOReader)
Justin Bogneref512b92014-01-06 22:27:43 +0000613 return;
Justin Bogner3212b182014-04-25 07:20:05 +0000614 if (D->isImplicit())
Justin Bogneref512b92014-01-06 22:27:43 +0000615 return;
Serge Pavlov3a561452015-12-06 14:32:39 +0000616 // Constructors and destructors may be represented by several functions in IR.
617 // If so, instrument only base variant, others are implemented by delegation
618 // to the base one, it would be counted twice otherwise.
619 if (CGM.getTarget().getCXXABI().hasConstructorVariants() &&
620 ((isa<CXXConstructorDecl>(GD.getDecl()) &&
621 GD.getCtorType() != Ctor_Base) ||
622 (isa<CXXDestructorDecl>(GD.getDecl()) &&
623 GD.getDtorType() != Dtor_Base))) {
624 return;
625 }
Alex Lorenzee024992014-08-04 18:41:51 +0000626 CGM.ClearUnusedCoverageMapping(D);
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000627 setFuncName(Fn);
Duncan P. N. Exon Smith7c414512014-03-20 22:50:08 +0000628
Justin Bogneref512b92014-01-06 22:27:43 +0000629 mapRegionCounters(D);
Justin Bogner970ac602014-12-08 19:04:51 +0000630 if (CGM.getCodeGenOpts().CoverageMapping)
631 emitCounterRegionMapping(D);
Justin Bogner837a6f62014-04-18 21:52:00 +0000632 if (PGOReader) {
Justin Bogner40b8ba12014-06-26 01:45:07 +0000633 SourceManager &SM = CGM.getContext().getSourceManager();
634 loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
Bob Wilsonbf854f02014-02-17 19:21:09 +0000635 computeRegionCounts(D);
Justin Bogner837a6f62014-04-18 21:52:00 +0000636 applyFunctionAttributes(PGOReader, Fn);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000637 }
Justin Bogneref512b92014-01-06 22:27:43 +0000638}
639
640void CodeGenPGO::mapRegionCounters(const Decl *D) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000641 RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000642 MapRegionCounters Walker(*RegionCounterMap);
Justin Bogneref512b92014-01-06 22:27:43 +0000643 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000644 Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000645 else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000646 Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
Bob Wilsonc845c002014-03-06 20:24:27 +0000647 else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000648 Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
Justin Bogner81ab90f2014-04-15 00:50:54 +0000649 else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
650 Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
Justin Bogner3212b182014-04-25 07:20:05 +0000651 assert(Walker.NextCounter > 0 && "no entry counter mapped for decl");
Justin Bogneref512b92014-01-06 22:27:43 +0000652 NumRegionCounters = Walker.NextCounter;
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000653 FunctionHash = Walker.Hash.finalize();
Justin Bogneref512b92014-01-06 22:27:43 +0000654}
655
Alex Lorenzee024992014-08-04 18:41:51 +0000656void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
657 if (SkipCoverageMapping)
658 return;
659 // Don't map the functions inside the system headers
660 auto Loc = D->getBody()->getLocStart();
661 if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))
662 return;
663
Justin Bogner970ac602014-12-08 19:04:51 +0000664 std::string CoverageMapping;
Alex Lorenzee024992014-08-04 18:41:51 +0000665 llvm::raw_string_ostream OS(CoverageMapping);
666 CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
667 CGM.getContext().getSourceManager(),
Justin Bognere5ee6c52014-10-02 16:44:01 +0000668 CGM.getLangOpts(), RegionCounterMap.get());
Alex Lorenzee024992014-08-04 18:41:51 +0000669 MappingGen.emitCounterMapping(D, OS);
670 OS.flush();
Justin Bogner970ac602014-12-08 19:04:51 +0000671
672 if (CoverageMapping.empty())
673 return;
674
675 CGM.getCoverageMapping()->addFunctionMappingRecord(
676 FuncNameVar, FuncName, FunctionHash, CoverageMapping);
Alex Lorenzee024992014-08-04 18:41:51 +0000677}
678
679void
Justin Bogner60d852b2015-04-23 00:31:16 +0000680CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef Name,
Alex Lorenzee024992014-08-04 18:41:51 +0000681 llvm::GlobalValue::LinkageTypes Linkage) {
682 if (SkipCoverageMapping)
683 return;
Alex Lorenzee024992014-08-04 18:41:51 +0000684 // Don't map the functions inside the system headers
685 auto Loc = D->getBody()->getLocStart();
686 if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))
687 return;
688
Justin Bogner970ac602014-12-08 19:04:51 +0000689 std::string CoverageMapping;
Alex Lorenzee024992014-08-04 18:41:51 +0000690 llvm::raw_string_ostream OS(CoverageMapping);
691 CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
692 CGM.getContext().getSourceManager(),
693 CGM.getLangOpts());
694 MappingGen.emitEmptyMapping(D, OS);
695 OS.flush();
Justin Bogner970ac602014-12-08 19:04:51 +0000696
697 if (CoverageMapping.empty())
698 return;
699
Justin Bogner60d852b2015-04-23 00:31:16 +0000700 setFuncName(Name, Linkage);
Justin Bogner970ac602014-12-08 19:04:51 +0000701 CGM.getCoverageMapping()->addFunctionMappingRecord(
702 FuncNameVar, FuncName, FunctionHash, CoverageMapping);
Alex Lorenzee024992014-08-04 18:41:51 +0000703}
704
Bob Wilsonbf854f02014-02-17 19:21:09 +0000705void CodeGenPGO::computeRegionCounts(const Decl *D) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000706 StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000707 ComputeRegionCounts Walker(*StmtCountMap, *this);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000708 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
709 Walker.VisitFunctionDecl(FD);
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000710 else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
711 Walker.VisitObjCMethodDecl(MD);
Bob Wilsonc845c002014-03-06 20:24:27 +0000712 else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
713 Walker.VisitBlockDecl(BD);
Justin Bogner81ab90f2014-04-15 00:50:54 +0000714 else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
715 Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
Bob Wilsonbf854f02014-02-17 19:21:09 +0000716}
717
Justin Bogner837a6f62014-04-18 21:52:00 +0000718void
719CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
720 llvm::Function *Fn) {
Justin Bogner4c9c45c2014-03-12 18:14:32 +0000721 if (!haveRegionCounts())
722 return;
723
Justin Bogner837a6f62014-04-18 21:52:00 +0000724 uint64_t MaxFunctionCount = PGOReader->getMaximumFunctionCount();
Hans Wennborgdcfba332015-10-06 23:40:43 +0000725 uint64_t FunctionCount = getRegionCount(nullptr);
Justin Bogner4c9c45c2014-03-12 18:14:32 +0000726 if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount))
727 // Turn on InlineHint attribute for hot functions.
728 // FIXME: 30% is from preliminary tuning on SPEC, it may not be optimal.
729 Fn->addFnAttr(llvm::Attribute::InlineHint);
730 else if (FunctionCount <= (uint64_t)(0.01 * (double)MaxFunctionCount))
731 // Turn on Cold attribute for cold functions.
732 // FIXME: 1% is from preliminary tuning on SPEC, it may not be optimal.
733 Fn->addFnAttr(llvm::Attribute::Cold);
Diego Novilloaa8b1cb2015-05-27 21:58:42 +0000734
735 Fn->setEntryCount(FunctionCount);
Justin Bogner4c9c45c2014-03-12 18:14:32 +0000736}
737
Justin Bogner66242d62015-04-23 23:06:47 +0000738void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S) {
Justin Bogner970ac602014-12-08 19:04:51 +0000739 if (!CGM.getCodeGenOpts().ProfileInstrGenerate || !RegionCounterMap)
Justin Bogneref512b92014-01-06 22:27:43 +0000740 return;
Duncan P. N. Exon Smith9f5260a2015-11-06 23:00:41 +0000741 if (!Builder.GetInsertBlock())
Justin Bogner203f91e2015-01-09 01:46:40 +0000742 return;
Justin Bogner66242d62015-04-23 23:06:47 +0000743
744 unsigned Counter = (*RegionCounterMap)[S];
Justin Bogner970ac602014-12-08 19:04:51 +0000745 auto *I8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
David Blaikie43f9bb72015-05-18 22:14:03 +0000746 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
747 {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
Justin Bogner970ac602014-12-08 19:04:51 +0000748 Builder.getInt64(FunctionHash),
749 Builder.getInt32(NumRegionCounters),
David Blaikie43f9bb72015-05-18 22:14:03 +0000750 Builder.getInt32(Counter)});
Justin Bogneref512b92014-01-06 22:27:43 +0000751}
752
Justin Bogner40b8ba12014-06-26 01:45:07 +0000753void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
754 bool IsInMainFile) {
755 CGM.getPGOStats().addVisited(IsInMainFile);
Justin Bogner7f8cf5b2014-12-02 22:38:52 +0000756 RegionCounts.clear();
Justin Bogner970ac602014-12-08 19:04:51 +0000757 if (std::error_code EC =
758 PGOReader->getFunctionCounts(FuncName, FunctionHash, RegionCounts)) {
Justin Bogner9c6818e2014-08-01 22:50:16 +0000759 if (EC == llvm::instrprof_error::unknown_function)
760 CGM.getPGOStats().addMissing(IsInMainFile);
761 else if (EC == llvm::instrprof_error::hash_mismatch)
762 CGM.getPGOStats().addMismatched(IsInMainFile);
763 else if (EC == llvm::instrprof_error::malformed)
764 // TODO: Consider a more specific warning for this case.
765 CGM.getPGOStats().addMismatched(IsInMainFile);
Justin Bogner7f8cf5b2014-12-02 22:38:52 +0000766 RegionCounts.clear();
Justin Bognere2ef2a02014-04-15 21:22:35 +0000767 }
Justin Bogneref512b92014-01-06 22:27:43 +0000768}
769
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000770/// \brief Calculate what to divide by to scale weights.
771///
772/// Given the maximum weight, calculate a divisor that will scale all the
773/// weights to strictly less than UINT32_MAX.
774static uint64_t calculateWeightScale(uint64_t MaxWeight) {
775 return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
776}
777
778/// \brief Scale an individual branch weight (and add 1).
779///
780/// Scale a 64-bit weight down to 32-bits using \c Scale.
781///
782/// According to Laplace's Rule of Succession, it is better to compute the
783/// weight based on the count plus 1, so universally add 1 to the value.
784///
785/// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
786/// greater than \c Weight.
787static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
788 assert(Scale && "scale by 0?");
789 uint64_t Scaled = Weight / Scale + 1;
790 assert(Scaled <= UINT32_MAX && "overflow 32-bits");
791 return Scaled;
792}
793
Justin Bogner65512642015-05-02 05:00:55 +0000794llvm::MDNode *CodeGenFunction::createProfileWeights(uint64_t TrueCount,
795 uint64_t FalseCount) {
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000796 // Check for empty weights.
Justin Bogneref512b92014-01-06 22:27:43 +0000797 if (!TrueCount && !FalseCount)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000798 return nullptr;
Justin Bogneref512b92014-01-06 22:27:43 +0000799
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000800 // Calculate how to scale down to 32-bits.
801 uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
802
Justin Bogneref512b92014-01-06 22:27:43 +0000803 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000804 return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
805 scaleBranchWeight(FalseCount, Scale));
Justin Bogneref512b92014-01-06 22:27:43 +0000806}
807
Justin Bogner65512642015-05-02 05:00:55 +0000808llvm::MDNode *
809CodeGenFunction::createProfileWeights(ArrayRef<uint64_t> Weights) {
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000810 // We need at least two elements to create meaningful weights.
811 if (Weights.size() < 2)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000812 return nullptr;
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000813
Justin Bognerf3aefca2014-04-04 02:48:51 +0000814 // Check for empty weights.
815 uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
816 if (MaxWeight == 0)
817 return nullptr;
818
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000819 // Calculate how to scale down to 32-bits.
Justin Bognerf3aefca2014-04-04 02:48:51 +0000820 uint64_t Scale = calculateWeightScale(MaxWeight);
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000821
Justin Bogneref512b92014-01-06 22:27:43 +0000822 SmallVector<uint32_t, 16> ScaledWeights;
823 ScaledWeights.reserve(Weights.size());
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000824 for (uint64_t W : Weights)
825 ScaledWeights.push_back(scaleBranchWeight(W, Scale));
826
827 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
Justin Bogneref512b92014-01-06 22:27:43 +0000828 return MDHelper.createBranchWeights(ScaledWeights);
829}
Bob Wilsonbf854f02014-02-17 19:21:09 +0000830
Justin Bogner65512642015-05-02 05:00:55 +0000831llvm::MDNode *CodeGenFunction::createProfileWeightsForLoop(const Stmt *Cond,
832 uint64_t LoopCount) {
833 if (!PGO.haveRegionCounts())
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000834 return nullptr;
Justin Bogner65512642015-05-02 05:00:55 +0000835 Optional<uint64_t> CondCount = PGO.getStmtCount(Cond);
Justin Bogner1c21c282015-04-13 12:23:19 +0000836 assert(CondCount.hasValue() && "missing expected loop condition count");
837 if (*CondCount == 0)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000838 return nullptr;
Justin Bogner65512642015-05-02 05:00:55 +0000839 return createProfileWeights(LoopCount,
840 std::max(*CondCount, LoopCount) - LoopCount);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000841}