blob: e810f608ab787fcf1b41f2d3ba615ec54ab6f7d7 [file] [log] [blame]
Justin Bogneref512b92014-01-06 22:27:43 +00001//===--- CodeGenPGO.cpp - PGO Instrumentation for LLVM CodeGen --*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Justin Bogneref512b92014-01-06 22:27:43 +00006//
7//===----------------------------------------------------------------------===//
8//
9// Instrumentation-based profile-guided optimization
10//
11//===----------------------------------------------------------------------===//
12
13#include "CodeGenPGO.h"
14#include "CodeGenFunction.h"
Alex Lorenzee024992014-08-04 18:41:51 +000015#include "CoverageMappingGen.h"
Justin Bogneref512b92014-01-06 22:27:43 +000016#include "clang/AST/RecursiveASTVisitor.h"
17#include "clang/AST/StmtVisitor.h"
Justin Bogner970ac602014-12-08 19:04:51 +000018#include "llvm/IR/Intrinsics.h"
Justin Bogneref512b92014-01-06 22:27:43 +000019#include "llvm/IR/MDBuilder.h"
Reid Kleckner4c1a1d32019-11-14 15:15:48 -080020#include "llvm/Support/CommandLine.h"
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +000021#include "llvm/Support/Endian.h"
Justin Bogneref512b92014-01-06 22:27:43 +000022#include "llvm/Support/FileSystem.h"
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +000023#include "llvm/Support/MD5.h"
Justin Bogneref512b92014-01-06 22:27:43 +000024
Zachary Turner8065f0b2017-12-01 00:53:10 +000025static llvm::cl::opt<bool>
26 EnableValueProfiling("enable-value-profiling", llvm::cl::ZeroOrMore,
27 llvm::cl::desc("Enable value profiling"),
28 llvm::cl::Hidden, llvm::cl::init(false));
Betul Buyukkurt518276a2016-01-23 22:50:44 +000029
Justin Bogneref512b92014-01-06 22:27:43 +000030using namespace clang;
31using namespace CodeGen;
32
Alex Lorenzee024992014-08-04 18:41:51 +000033void CodeGenPGO::setFuncName(StringRef Name,
34 llvm::GlobalValue::LinkageTypes Linkage) {
Xinliang David Lia569e242015-12-05 05:37:15 +000035 llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
36 FuncName = llvm::getPGOFuncName(
37 Name, Linkage, CGM.getCodeGenOpts().MainFileName,
38 PGOReader ? PGOReader->getVersion() : llvm::IndexedInstrProf::Version);
Justin Bogner970ac602014-12-08 19:04:51 +000039
40 // If we're generating a profile, create a variable for the name.
Rong Xu9837ef52016-02-04 18:39:09 +000041 if (CGM.getCodeGenOpts().hasProfileClangInstr())
Xinliang David Li2d7ec5a2015-11-09 00:04:16 +000042 FuncNameVar = llvm::createPGOFuncNameVar(CGM.getModule(), Linkage, FuncName);
Bob Wilsonda1ebed2014-03-06 04:55:41 +000043}
44
Alex Lorenzee024992014-08-04 18:41:51 +000045void CodeGenPGO::setFuncName(llvm::Function *Fn) {
46 setFuncName(Fn->getName(), Fn->getLinkage());
Rong Xuf932f542016-04-22 21:19:05 +000047 // Create PGOFuncName meta data.
48 llvm::createPGOFuncNameMetadata(*Fn, FuncName);
Alex Lorenzee024992014-08-04 18:41:51 +000049}
50
Vedant Kumar61869712017-11-14 23:56:53 +000051/// The version of the PGO hash algorithm.
52enum PGOHashVersion : unsigned {
53 PGO_HASH_V1,
54 PGO_HASH_V2,
serge-sans-paillede02a752020-05-25 20:44:35 +020055 PGO_HASH_V3,
Vedant Kumar61869712017-11-14 23:56:53 +000056
57 // Keep this set to the latest hash version.
serge-sans-paillede02a752020-05-25 20:44:35 +020058 PGO_HASH_LATEST = PGO_HASH_V3
Vedant Kumar61869712017-11-14 23:56:53 +000059};
60
Justin Bogneref512b92014-01-06 22:27:43 +000061namespace {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000062/// Stable hasher for PGO region counters.
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +000063///
64/// PGOHash produces a stable hash of a given function's control flow.
65///
66/// Changing the output of this hash will invalidate all previously generated
67/// profiles -- i.e., don't do it.
68///
69/// \note When this hash does eventually change (years?), we still need to
70/// support old hashes. We'll need to pull in the version number from the
71/// profile data format and use the matching hash function.
72class PGOHash {
73 uint64_t Working;
74 unsigned Count;
Vedant Kumar61869712017-11-14 23:56:53 +000075 PGOHashVersion HashVersion;
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +000076 llvm::MD5 MD5;
77
78 static const int NumBitsPerType = 6;
79 static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
80 static const unsigned TooBig = 1u << NumBitsPerType;
81
82public:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000083 /// Hash values for AST nodes.
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +000084 ///
85 /// Distinct values for AST nodes that have region counters attached.
86 ///
87 /// These values must be stable. All new members must be added at the end,
88 /// and no members should be removed. Changing the enumeration value for an
89 /// AST node will affect the hash of every function that contains that node.
90 enum HashType : unsigned char {
91 None = 0,
92 LabelStmt = 1,
93 WhileStmt,
94 DoStmt,
95 ForStmt,
96 CXXForRangeStmt,
97 ObjCForCollectionStmt,
98 SwitchStmt,
99 CaseStmt,
100 DefaultStmt,
101 IfStmt,
102 CXXTryStmt,
103 CXXCatchStmt,
104 ConditionalOperator,
105 BinaryOperatorLAnd,
106 BinaryOperatorLOr,
107 BinaryConditionalOperator,
Vedant Kumar61869712017-11-14 23:56:53 +0000108 // The preceding values are available with PGO_HASH_V1.
109
110 EndOfScope,
111 IfThenBranch,
112 IfElseBranch,
113 GotoStmt,
114 IndirectGotoStmt,
115 BreakStmt,
116 ContinueStmt,
117 ReturnStmt,
118 ThrowExpr,
119 UnaryOperatorLNot,
120 BinaryOperatorLT,
121 BinaryOperatorGT,
122 BinaryOperatorLE,
123 BinaryOperatorGE,
124 BinaryOperatorEQ,
125 BinaryOperatorNE,
serge-sans-paillede02a752020-05-25 20:44:35 +0200126 // The preceding values are available since PGO_HASH_V2.
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000127
128 // Keep this last. It's for the static assert that follows.
129 LastHashType
130 };
131 static_assert(LastHashType <= TooBig, "Too many types in HashType");
132
Vedant Kumar61869712017-11-14 23:56:53 +0000133 PGOHash(PGOHashVersion HashVersion)
134 : Working(0), Count(0), HashVersion(HashVersion), MD5() {}
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000135 void combine(HashType Type);
136 uint64_t finalize();
Vedant Kumar61869712017-11-14 23:56:53 +0000137 PGOHashVersion getHashVersion() const { return HashVersion; }
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000138};
139const int PGOHash::NumBitsPerType;
140const unsigned PGOHash::NumTypesPerWord;
141const unsigned PGOHash::TooBig;
142
Vedant Kumar61869712017-11-14 23:56:53 +0000143/// Get the PGO hash version used in the given indexed profile.
144static PGOHashVersion getPGOHashVersion(llvm::IndexedInstrProfReader *PGOReader,
145 CodeGenModule &CGM) {
146 if (PGOReader->getVersion() <= 4)
147 return PGO_HASH_V1;
serge-sans-paillede02a752020-05-25 20:44:35 +0200148 if (PGOReader->getVersion() <= 5)
149 return PGO_HASH_V2;
150 return PGO_HASH_V3;
Vedant Kumar61869712017-11-14 23:56:53 +0000151}
152
Justin Bognere4ca4412015-02-23 19:27:00 +0000153/// A RecursiveASTVisitor that fills a map of statements to PGO counters.
154struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
Vedant Kumar61869712017-11-14 23:56:53 +0000155 using Base = RecursiveASTVisitor<MapRegionCounters>;
156
Justin Bognere4ca4412015-02-23 19:27:00 +0000157 /// The next counter value to assign.
158 unsigned NextCounter;
159 /// The function hash.
160 PGOHash Hash;
161 /// The map of statements to counters.
162 llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
Justin Bogneref512b92014-01-06 22:27:43 +0000163
Vedant Kumar61869712017-11-14 23:56:53 +0000164 MapRegionCounters(PGOHashVersion HashVersion,
165 llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
166 : NextCounter(0), Hash(HashVersion), CounterMap(CounterMap) {}
Justin Bogneref512b92014-01-06 22:27:43 +0000167
Justin Bognere4ca4412015-02-23 19:27:00 +0000168 // Blocks and lambdas are handled as separate functions, so we need not
169 // traverse them in the parent context.
170 bool TraverseBlockExpr(BlockExpr *BE) { return true; }
Sam McCalle60151c2019-01-14 10:31:42 +0000171 bool TraverseLambdaExpr(LambdaExpr *LE) {
172 // Traverse the captures, but not the body.
Mark de Wever8dc7b982020-01-01 17:23:21 +0100173 for (auto C : zip(LE->captures(), LE->capture_inits()))
Sam McCalle60151c2019-01-14 10:31:42 +0000174 TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
175 return true;
176 }
Justin Bognere4ca4412015-02-23 19:27:00 +0000177 bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
Justin Bogneref512b92014-01-06 22:27:43 +0000178
Justin Bognere4ca4412015-02-23 19:27:00 +0000179 bool VisitDecl(const Decl *D) {
180 switch (D->getKind()) {
181 default:
182 break;
183 case Decl::Function:
184 case Decl::CXXMethod:
185 case Decl::CXXConstructor:
186 case Decl::CXXDestructor:
187 case Decl::CXXConversion:
188 case Decl::ObjCMethod:
189 case Decl::Block:
190 case Decl::Captured:
191 CounterMap[D->getBody()] = NextCounter++;
192 break;
193 }
194 return true;
195 }
196
Vedant Kumar61869712017-11-14 23:56:53 +0000197 /// If \p S gets a fresh counter, update the counter mappings. Return the
198 /// V1 hash of \p S.
199 PGOHash::HashType updateCounterMappings(Stmt *S) {
200 auto Type = getHashType(PGO_HASH_V1, S);
201 if (Type != PGOHash::None)
202 CounterMap[S] = NextCounter++;
203 return Type;
204 }
Bob Wilsond8931422014-04-11 17:16:13 +0000205
Vedant Kumar61869712017-11-14 23:56:53 +0000206 /// Include \p S in the function hash.
207 bool VisitStmt(Stmt *S) {
208 auto Type = updateCounterMappings(S);
209 if (Hash.getHashVersion() != PGO_HASH_V1)
210 Type = getHashType(Hash.getHashVersion(), S);
211 if (Type != PGOHash::None)
212 Hash.combine(Type);
Justin Bognere4ca4412015-02-23 19:27:00 +0000213 return true;
214 }
Vedant Kumar61869712017-11-14 23:56:53 +0000215
216 bool TraverseIfStmt(IfStmt *If) {
217 // If we used the V1 hash, use the default traversal.
218 if (Hash.getHashVersion() == PGO_HASH_V1)
219 return Base::TraverseIfStmt(If);
220
221 // Otherwise, keep track of which branch we're in while traversing.
222 VisitStmt(If);
223 for (Stmt *CS : If->children()) {
224 if (!CS)
225 continue;
226 if (CS == If->getThen())
227 Hash.combine(PGOHash::IfThenBranch);
228 else if (CS == If->getElse())
229 Hash.combine(PGOHash::IfElseBranch);
230 TraverseStmt(CS);
231 }
232 Hash.combine(PGOHash::EndOfScope);
233 return true;
234 }
235
236// If the statement type \p N is nestable, and its nesting impacts profile
237// stability, define a custom traversal which tracks the end of the statement
238// in the hash (provided we're not using the V1 hash).
239#define DEFINE_NESTABLE_TRAVERSAL(N) \
240 bool Traverse##N(N *S) { \
241 Base::Traverse##N(S); \
242 if (Hash.getHashVersion() != PGO_HASH_V1) \
243 Hash.combine(PGOHash::EndOfScope); \
244 return true; \
245 }
246
247 DEFINE_NESTABLE_TRAVERSAL(WhileStmt)
248 DEFINE_NESTABLE_TRAVERSAL(DoStmt)
249 DEFINE_NESTABLE_TRAVERSAL(ForStmt)
250 DEFINE_NESTABLE_TRAVERSAL(CXXForRangeStmt)
251 DEFINE_NESTABLE_TRAVERSAL(ObjCForCollectionStmt)
252 DEFINE_NESTABLE_TRAVERSAL(CXXTryStmt)
253 DEFINE_NESTABLE_TRAVERSAL(CXXCatchStmt)
254
255 /// Get version \p HashVersion of the PGO hash for \p S.
256 PGOHash::HashType getHashType(PGOHashVersion HashVersion, const Stmt *S) {
Justin Bognere4ca4412015-02-23 19:27:00 +0000257 switch (S->getStmtClass()) {
258 default:
259 break;
260 case Stmt::LabelStmtClass:
261 return PGOHash::LabelStmt;
262 case Stmt::WhileStmtClass:
263 return PGOHash::WhileStmt;
264 case Stmt::DoStmtClass:
265 return PGOHash::DoStmt;
266 case Stmt::ForStmtClass:
267 return PGOHash::ForStmt;
268 case Stmt::CXXForRangeStmtClass:
269 return PGOHash::CXXForRangeStmt;
270 case Stmt::ObjCForCollectionStmtClass:
271 return PGOHash::ObjCForCollectionStmt;
272 case Stmt::SwitchStmtClass:
273 return PGOHash::SwitchStmt;
274 case Stmt::CaseStmtClass:
275 return PGOHash::CaseStmt;
276 case Stmt::DefaultStmtClass:
277 return PGOHash::DefaultStmt;
278 case Stmt::IfStmtClass:
279 return PGOHash::IfStmt;
280 case Stmt::CXXTryStmtClass:
281 return PGOHash::CXXTryStmt;
282 case Stmt::CXXCatchStmtClass:
283 return PGOHash::CXXCatchStmt;
284 case Stmt::ConditionalOperatorClass:
285 return PGOHash::ConditionalOperator;
286 case Stmt::BinaryConditionalOperatorClass:
287 return PGOHash::BinaryConditionalOperator;
288 case Stmt::BinaryOperatorClass: {
289 const BinaryOperator *BO = cast<BinaryOperator>(S);
290 if (BO->getOpcode() == BO_LAnd)
291 return PGOHash::BinaryOperatorLAnd;
292 if (BO->getOpcode() == BO_LOr)
293 return PGOHash::BinaryOperatorLOr;
serge-sans-paillede02a752020-05-25 20:44:35 +0200294 if (HashVersion >= PGO_HASH_V2) {
Vedant Kumar61869712017-11-14 23:56:53 +0000295 switch (BO->getOpcode()) {
296 default:
297 break;
298 case BO_LT:
299 return PGOHash::BinaryOperatorLT;
300 case BO_GT:
301 return PGOHash::BinaryOperatorGT;
302 case BO_LE:
303 return PGOHash::BinaryOperatorLE;
304 case BO_GE:
305 return PGOHash::BinaryOperatorGE;
306 case BO_EQ:
307 return PGOHash::BinaryOperatorEQ;
308 case BO_NE:
309 return PGOHash::BinaryOperatorNE;
310 }
311 }
Justin Bognere4ca4412015-02-23 19:27:00 +0000312 break;
313 }
314 }
Vedant Kumar61869712017-11-14 23:56:53 +0000315
serge-sans-paillede02a752020-05-25 20:44:35 +0200316 if (HashVersion >= PGO_HASH_V2) {
Vedant Kumar61869712017-11-14 23:56:53 +0000317 switch (S->getStmtClass()) {
318 default:
319 break;
320 case Stmt::GotoStmtClass:
321 return PGOHash::GotoStmt;
322 case Stmt::IndirectGotoStmtClass:
323 return PGOHash::IndirectGotoStmt;
324 case Stmt::BreakStmtClass:
325 return PGOHash::BreakStmt;
326 case Stmt::ContinueStmtClass:
327 return PGOHash::ContinueStmt;
328 case Stmt::ReturnStmtClass:
329 return PGOHash::ReturnStmt;
330 case Stmt::CXXThrowExprClass:
331 return PGOHash::ThrowExpr;
332 case Stmt::UnaryOperatorClass: {
333 const UnaryOperator *UO = cast<UnaryOperator>(S);
334 if (UO->getOpcode() == UO_LNot)
335 return PGOHash::UnaryOperatorLNot;
336 break;
337 }
338 }
339 }
340
Justin Bognere4ca4412015-02-23 19:27:00 +0000341 return PGOHash::None;
342 }
343};
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000344
Justin Bognere4ca4412015-02-23 19:27:00 +0000345/// A StmtVisitor that propagates the raw counts through the AST and
346/// records the count at statements where the value may change.
347struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
348 /// PGO state.
349 CodeGenPGO &PGO;
350
351 /// A flag that is set when the current count should be recorded on the
352 /// next statement, such as at the exit of a loop.
353 bool RecordNextStmtCount;
354
Justin Bognera909abf2015-05-02 00:48:27 +0000355 /// The count at the current location in the traversal.
356 uint64_t CurrentCount;
357
Justin Bognere4ca4412015-02-23 19:27:00 +0000358 /// The map of statements to count values.
359 llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
360
361 /// BreakContinueStack - Keep counts of breaks and continues inside loops.
362 struct BreakContinue {
363 uint64_t BreakCount;
364 uint64_t ContinueCount;
365 BreakContinue() : BreakCount(0), ContinueCount(0) {}
Justin Bogneref512b92014-01-06 22:27:43 +0000366 };
Justin Bognere4ca4412015-02-23 19:27:00 +0000367 SmallVector<BreakContinue, 8> BreakContinueStack;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000368
Justin Bognere4ca4412015-02-23 19:27:00 +0000369 ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
370 CodeGenPGO &PGO)
371 : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
Bob Wilsonbf854f02014-02-17 19:21:09 +0000372
Justin Bognere4ca4412015-02-23 19:27:00 +0000373 void RecordStmtCount(const Stmt *S) {
374 if (RecordNextStmtCount) {
Justin Bognera909abf2015-05-02 00:48:27 +0000375 CountMap[S] = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000376 RecordNextStmtCount = false;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000377 }
Justin Bognere4ca4412015-02-23 19:27:00 +0000378 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000379
Justin Bogner07193cc2015-05-01 23:41:09 +0000380 /// Set and return the current count.
381 uint64_t setCount(uint64_t Count) {
Justin Bognera909abf2015-05-02 00:48:27 +0000382 CurrentCount = Count;
Justin Bogner07193cc2015-05-01 23:41:09 +0000383 return Count;
384 }
385
Justin Bognere4ca4412015-02-23 19:27:00 +0000386 void VisitStmt(const Stmt *S) {
387 RecordStmtCount(S);
Benjamin Kramer642f1732015-07-02 21:03:14 +0000388 for (const Stmt *Child : S->children())
389 if (Child)
390 this->Visit(Child);
Justin Bognere4ca4412015-02-23 19:27:00 +0000391 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000392
Justin Bognere4ca4412015-02-23 19:27:00 +0000393 void VisitFunctionDecl(const FunctionDecl *D) {
394 // Counter tracks entry to the function body.
Justin Bogner07193cc2015-05-01 23:41:09 +0000395 uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
396 CountMap[D->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000397 Visit(D->getBody());
398 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000399
Justin Bognere4ca4412015-02-23 19:27:00 +0000400 // Skip lambda expressions. We visit these as FunctionDecls when we're
401 // generating them and aren't interested in the body when generating a
402 // parent context.
403 void VisitLambdaExpr(const LambdaExpr *LE) {}
Bob Wilsonbf854f02014-02-17 19:21:09 +0000404
Justin Bognere4ca4412015-02-23 19:27:00 +0000405 void VisitCapturedDecl(const CapturedDecl *D) {
406 // Counter tracks entry to the capture body.
Justin Bogner07193cc2015-05-01 23:41:09 +0000407 uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
408 CountMap[D->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000409 Visit(D->getBody());
410 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000411
Justin Bognere4ca4412015-02-23 19:27:00 +0000412 void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
413 // Counter tracks entry to the method body.
Justin Bogner07193cc2015-05-01 23:41:09 +0000414 uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
415 CountMap[D->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000416 Visit(D->getBody());
417 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000418
Justin Bognere4ca4412015-02-23 19:27:00 +0000419 void VisitBlockDecl(const BlockDecl *D) {
420 // Counter tracks entry to the block body.
Justin Bogner07193cc2015-05-01 23:41:09 +0000421 uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
422 CountMap[D->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000423 Visit(D->getBody());
424 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000425
Justin Bognere4ca4412015-02-23 19:27:00 +0000426 void VisitReturnStmt(const ReturnStmt *S) {
427 RecordStmtCount(S);
428 if (S->getRetValue())
429 Visit(S->getRetValue());
Justin Bognera909abf2015-05-02 00:48:27 +0000430 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000431 RecordNextStmtCount = true;
432 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000433
Justin Bognerf959feb2015-04-28 06:31:55 +0000434 void VisitCXXThrowExpr(const CXXThrowExpr *E) {
435 RecordStmtCount(E);
436 if (E->getSubExpr())
437 Visit(E->getSubExpr());
Justin Bognera909abf2015-05-02 00:48:27 +0000438 CurrentCount = 0;
Justin Bognerf959feb2015-04-28 06:31:55 +0000439 RecordNextStmtCount = true;
440 }
441
Justin Bognere4ca4412015-02-23 19:27:00 +0000442 void VisitGotoStmt(const GotoStmt *S) {
443 RecordStmtCount(S);
Justin Bognera909abf2015-05-02 00:48:27 +0000444 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000445 RecordNextStmtCount = true;
446 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000447
Justin Bognere4ca4412015-02-23 19:27:00 +0000448 void VisitLabelStmt(const LabelStmt *S) {
449 RecordNextStmtCount = false;
450 // Counter tracks the block following the label.
Justin Bogner07193cc2015-05-01 23:41:09 +0000451 uint64_t BlockCount = setCount(PGO.getRegionCount(S));
452 CountMap[S] = BlockCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000453 Visit(S->getSubStmt());
454 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000455
Justin Bognere4ca4412015-02-23 19:27:00 +0000456 void VisitBreakStmt(const BreakStmt *S) {
457 RecordStmtCount(S);
458 assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
Justin Bognera909abf2015-05-02 00:48:27 +0000459 BreakContinueStack.back().BreakCount += CurrentCount;
460 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000461 RecordNextStmtCount = true;
462 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000463
Justin Bognere4ca4412015-02-23 19:27:00 +0000464 void VisitContinueStmt(const ContinueStmt *S) {
465 RecordStmtCount(S);
466 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
Justin Bognera909abf2015-05-02 00:48:27 +0000467 BreakContinueStack.back().ContinueCount += CurrentCount;
468 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000469 RecordNextStmtCount = true;
470 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000471
Justin Bognere4ca4412015-02-23 19:27:00 +0000472 void VisitWhileStmt(const WhileStmt *S) {
473 RecordStmtCount(S);
Justin Bognera909abf2015-05-02 00:48:27 +0000474 uint64_t ParentCount = CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000475
Justin Bognere4ca4412015-02-23 19:27:00 +0000476 BreakContinueStack.push_back(BreakContinue());
477 // Visit the body region first so the break/continue adjustments can be
478 // included when visiting the condition.
Justin Bogner07193cc2015-05-01 23:41:09 +0000479 uint64_t BodyCount = setCount(PGO.getRegionCount(S));
Justin Bognera909abf2015-05-02 00:48:27 +0000480 CountMap[S->getBody()] = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000481 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000482 uint64_t BackedgeCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000483
484 // ...then go back and propagate counts through the condition. The count
485 // at the start of the condition is the sum of the incoming edges,
486 // the backedge from the end of the loop body, and the edges from
487 // continue statements.
488 BreakContinue BC = BreakContinueStack.pop_back_val();
Justin Bogner07193cc2015-05-01 23:41:09 +0000489 uint64_t CondCount =
490 setCount(ParentCount + BackedgeCount + BC.ContinueCount);
491 CountMap[S->getCond()] = CondCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000492 Visit(S->getCond());
Justin Bogner07193cc2015-05-01 23:41:09 +0000493 setCount(BC.BreakCount + CondCount - BodyCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000494 RecordNextStmtCount = true;
495 }
496
497 void VisitDoStmt(const DoStmt *S) {
498 RecordStmtCount(S);
Justin Bogner07193cc2015-05-01 23:41:09 +0000499 uint64_t LoopCount = PGO.getRegionCount(S);
500
Justin Bognere4ca4412015-02-23 19:27:00 +0000501 BreakContinueStack.push_back(BreakContinue());
Justin Bogner07193cc2015-05-01 23:41:09 +0000502 // The count doesn't include the fallthrough from the parent scope. Add it.
Justin Bognera909abf2015-05-02 00:48:27 +0000503 uint64_t BodyCount = setCount(LoopCount + CurrentCount);
Justin Bogner07193cc2015-05-01 23:41:09 +0000504 CountMap[S->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000505 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000506 uint64_t BackedgeCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000507
508 BreakContinue BC = BreakContinueStack.pop_back_val();
509 // The count at the start of the condition is equal to the count at the
Justin Bogner07193cc2015-05-01 23:41:09 +0000510 // end of the body, plus any continues.
511 uint64_t CondCount = setCount(BackedgeCount + BC.ContinueCount);
512 CountMap[S->getCond()] = CondCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000513 Visit(S->getCond());
Justin Bogner07193cc2015-05-01 23:41:09 +0000514 setCount(BC.BreakCount + CondCount - LoopCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000515 RecordNextStmtCount = true;
516 }
517
518 void VisitForStmt(const ForStmt *S) {
519 RecordStmtCount(S);
520 if (S->getInit())
521 Visit(S->getInit());
Justin Bogner07193cc2015-05-01 23:41:09 +0000522
Justin Bognera909abf2015-05-02 00:48:27 +0000523 uint64_t ParentCount = CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000524
Justin Bognere4ca4412015-02-23 19:27:00 +0000525 BreakContinueStack.push_back(BreakContinue());
526 // Visit the body region first. (This is basically the same as a while
527 // loop; see further comments in VisitWhileStmt.)
Justin Bogner07193cc2015-05-01 23:41:09 +0000528 uint64_t BodyCount = setCount(PGO.getRegionCount(S));
529 CountMap[S->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000530 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000531 uint64_t BackedgeCount = CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000532 BreakContinue BC = BreakContinueStack.pop_back_val();
Justin Bognere4ca4412015-02-23 19:27:00 +0000533
534 // The increment is essentially part of the body but it needs to include
535 // the count for all the continue statements.
536 if (S->getInc()) {
Justin Bogner07193cc2015-05-01 23:41:09 +0000537 uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
538 CountMap[S->getInc()] = IncCount;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000539 Visit(S->getInc());
Justin Bognere4ca4412015-02-23 19:27:00 +0000540 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000541
Justin Bognere4ca4412015-02-23 19:27:00 +0000542 // ...then go back and propagate counts through the condition.
Justin Bogner07193cc2015-05-01 23:41:09 +0000543 uint64_t CondCount =
544 setCount(ParentCount + BackedgeCount + BC.ContinueCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000545 if (S->getCond()) {
Justin Bogner07193cc2015-05-01 23:41:09 +0000546 CountMap[S->getCond()] = CondCount;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000547 Visit(S->getCond());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000548 }
Justin Bogner07193cc2015-05-01 23:41:09 +0000549 setCount(BC.BreakCount + CondCount - BodyCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000550 RecordNextStmtCount = true;
551 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000552
Justin Bognere4ca4412015-02-23 19:27:00 +0000553 void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
554 RecordStmtCount(S);
Richard Smith8baa5002018-09-28 18:44:09 +0000555 if (S->getInit())
556 Visit(S->getInit());
Justin Bogner2e5d4842015-04-30 22:58:28 +0000557 Visit(S->getLoopVarStmt());
Justin Bognere4ca4412015-02-23 19:27:00 +0000558 Visit(S->getRangeStmt());
Richard Smith01694c32016-03-20 10:33:40 +0000559 Visit(S->getBeginStmt());
560 Visit(S->getEndStmt());
Justin Bogner07193cc2015-05-01 23:41:09 +0000561
Justin Bognera909abf2015-05-02 00:48:27 +0000562 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000563 BreakContinueStack.push_back(BreakContinue());
564 // Visit the body region first. (This is basically the same as a while
565 // loop; see further comments in VisitWhileStmt.)
Justin Bogner07193cc2015-05-01 23:41:09 +0000566 uint64_t BodyCount = setCount(PGO.getRegionCount(S));
567 CountMap[S->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000568 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000569 uint64_t BackedgeCount = CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000570 BreakContinue BC = BreakContinueStack.pop_back_val();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000571
Justin Bognere4ca4412015-02-23 19:27:00 +0000572 // The increment is essentially part of the body but it needs to include
573 // the count for all the continue statements.
Justin Bogner07193cc2015-05-01 23:41:09 +0000574 uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
575 CountMap[S->getInc()] = IncCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000576 Visit(S->getInc());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000577
Justin Bognere4ca4412015-02-23 19:27:00 +0000578 // ...then go back and propagate counts through the condition.
Justin Bogner07193cc2015-05-01 23:41:09 +0000579 uint64_t CondCount =
580 setCount(ParentCount + BackedgeCount + BC.ContinueCount);
581 CountMap[S->getCond()] = CondCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000582 Visit(S->getCond());
Justin Bogner07193cc2015-05-01 23:41:09 +0000583 setCount(BC.BreakCount + CondCount - BodyCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000584 RecordNextStmtCount = true;
585 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000586
Justin Bognere4ca4412015-02-23 19:27:00 +0000587 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
588 RecordStmtCount(S);
589 Visit(S->getElement());
Justin Bognera909abf2015-05-02 00:48:27 +0000590 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000591 BreakContinueStack.push_back(BreakContinue());
Justin Bogner07193cc2015-05-01 23:41:09 +0000592 // Counter tracks the body of the loop.
593 uint64_t BodyCount = setCount(PGO.getRegionCount(S));
594 CountMap[S->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000595 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000596 uint64_t BackedgeCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000597 BreakContinue BC = BreakContinueStack.pop_back_val();
Justin Bogner07193cc2015-05-01 23:41:09 +0000598
599 setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount -
600 BodyCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000601 RecordNextStmtCount = true;
602 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000603
Justin Bognere4ca4412015-02-23 19:27:00 +0000604 void VisitSwitchStmt(const SwitchStmt *S) {
605 RecordStmtCount(S);
Vedant Kumarf2a6ec52016-10-14 23:38:13 +0000606 if (S->getInit())
607 Visit(S->getInit());
Justin Bognere4ca4412015-02-23 19:27:00 +0000608 Visit(S->getCond());
Justin Bognera909abf2015-05-02 00:48:27 +0000609 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000610 BreakContinueStack.push_back(BreakContinue());
611 Visit(S->getBody());
612 // If the switch is inside a loop, add the continue counts.
613 BreakContinue BC = BreakContinueStack.pop_back_val();
614 if (!BreakContinueStack.empty())
615 BreakContinueStack.back().ContinueCount += BC.ContinueCount;
616 // Counter tracks the exit block of the switch.
Justin Bogner07193cc2015-05-01 23:41:09 +0000617 setCount(PGO.getRegionCount(S));
Justin Bognere4ca4412015-02-23 19:27:00 +0000618 RecordNextStmtCount = true;
619 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000620
Justin Bogner07193cc2015-05-01 23:41:09 +0000621 void VisitSwitchCase(const SwitchCase *S) {
Justin Bognere4ca4412015-02-23 19:27:00 +0000622 RecordNextStmtCount = false;
623 // Counter for this particular case. This counts only jumps from the
624 // switch header and does not include fallthrough from the case before
625 // this one.
Justin Bogner07193cc2015-05-01 23:41:09 +0000626 uint64_t CaseCount = PGO.getRegionCount(S);
Justin Bognera909abf2015-05-02 00:48:27 +0000627 setCount(CurrentCount + CaseCount);
Justin Bogner07193cc2015-05-01 23:41:09 +0000628 // We need the count without fallthrough in the mapping, so it's more useful
629 // for branch probabilities.
630 CountMap[S] = CaseCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000631 RecordNextStmtCount = true;
632 Visit(S->getSubStmt());
633 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000634
Justin Bognere4ca4412015-02-23 19:27:00 +0000635 void VisitIfStmt(const IfStmt *S) {
636 RecordStmtCount(S);
Justin Bognera909abf2015-05-02 00:48:27 +0000637 uint64_t ParentCount = CurrentCount;
Vedant Kumar9d2a16b2016-10-14 23:38:16 +0000638 if (S->getInit())
639 Visit(S->getInit());
Justin Bognere4ca4412015-02-23 19:27:00 +0000640 Visit(S->getCond());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000641
Justin Bogner07193cc2015-05-01 23:41:09 +0000642 // Counter tracks the "then" part of an if statement. The count for
643 // the "else" part, if it exists, will be calculated from this counter.
644 uint64_t ThenCount = setCount(PGO.getRegionCount(S));
645 CountMap[S->getThen()] = ThenCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000646 Visit(S->getThen());
Justin Bognera909abf2015-05-02 00:48:27 +0000647 uint64_t OutCount = CurrentCount;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000648
Justin Bogner07193cc2015-05-01 23:41:09 +0000649 uint64_t ElseCount = ParentCount - ThenCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000650 if (S->getElse()) {
Justin Bogner07193cc2015-05-01 23:41:09 +0000651 setCount(ElseCount);
652 CountMap[S->getElse()] = ElseCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000653 Visit(S->getElse());
Justin Bognera909abf2015-05-02 00:48:27 +0000654 OutCount += CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000655 } else
656 OutCount += ElseCount;
657 setCount(OutCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000658 RecordNextStmtCount = true;
659 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000660
Justin Bognere4ca4412015-02-23 19:27:00 +0000661 void VisitCXXTryStmt(const CXXTryStmt *S) {
662 RecordStmtCount(S);
663 Visit(S->getTryBlock());
664 for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
665 Visit(S->getHandler(I));
666 // Counter tracks the continuation block of the try statement.
Justin Bogner07193cc2015-05-01 23:41:09 +0000667 setCount(PGO.getRegionCount(S));
Justin Bognere4ca4412015-02-23 19:27:00 +0000668 RecordNextStmtCount = true;
669 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000670
Justin Bognere4ca4412015-02-23 19:27:00 +0000671 void VisitCXXCatchStmt(const CXXCatchStmt *S) {
672 RecordNextStmtCount = false;
673 // Counter tracks the catch statement's handler block.
Justin Bogner07193cc2015-05-01 23:41:09 +0000674 uint64_t CatchCount = setCount(PGO.getRegionCount(S));
675 CountMap[S] = CatchCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000676 Visit(S->getHandlerBlock());
677 }
678
679 void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
680 RecordStmtCount(E);
Justin Bognera909abf2015-05-02 00:48:27 +0000681 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000682 Visit(E->getCond());
683
Justin Bogner07193cc2015-05-01 23:41:09 +0000684 // Counter tracks the "true" part of a conditional operator. The
685 // count in the "false" part will be calculated from this counter.
686 uint64_t TrueCount = setCount(PGO.getRegionCount(E));
687 CountMap[E->getTrueExpr()] = TrueCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000688 Visit(E->getTrueExpr());
Justin Bognera909abf2015-05-02 00:48:27 +0000689 uint64_t OutCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000690
Justin Bogner07193cc2015-05-01 23:41:09 +0000691 uint64_t FalseCount = setCount(ParentCount - TrueCount);
692 CountMap[E->getFalseExpr()] = FalseCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000693 Visit(E->getFalseExpr());
Justin Bognera909abf2015-05-02 00:48:27 +0000694 OutCount += CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000695
Justin Bogner07193cc2015-05-01 23:41:09 +0000696 setCount(OutCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000697 RecordNextStmtCount = true;
698 }
699
700 void VisitBinLAnd(const BinaryOperator *E) {
701 RecordStmtCount(E);
Justin Bognera909abf2015-05-02 00:48:27 +0000702 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000703 Visit(E->getLHS());
Justin Bogner07193cc2015-05-01 23:41:09 +0000704 // Counter tracks the right hand side of a logical and operator.
705 uint64_t RHSCount = setCount(PGO.getRegionCount(E));
706 CountMap[E->getRHS()] = RHSCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000707 Visit(E->getRHS());
Justin Bognera909abf2015-05-02 00:48:27 +0000708 setCount(ParentCount + RHSCount - CurrentCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000709 RecordNextStmtCount = true;
710 }
711
712 void VisitBinLOr(const BinaryOperator *E) {
713 RecordStmtCount(E);
Justin Bognera909abf2015-05-02 00:48:27 +0000714 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000715 Visit(E->getLHS());
Justin Bogner07193cc2015-05-01 23:41:09 +0000716 // Counter tracks the right hand side of a logical or operator.
717 uint64_t RHSCount = setCount(PGO.getRegionCount(E));
718 CountMap[E->getRHS()] = RHSCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000719 Visit(E->getRHS());
Justin Bognera909abf2015-05-02 00:48:27 +0000720 setCount(ParentCount + RHSCount - CurrentCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000721 RecordNextStmtCount = true;
722 }
723};
Hans Wennborgdcfba332015-10-06 23:40:43 +0000724} // end anonymous namespace
Justin Bogneref512b92014-01-06 22:27:43 +0000725
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000726void PGOHash::combine(HashType Type) {
727 // Check that we never combine 0 and only have six bits.
728 assert(Type && "Hash is invalid: unexpected type 0");
729 assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
730
731 // Pass through MD5 if enough work has built up.
732 if (Count && Count % NumTypesPerWord == 0) {
733 using namespace llvm::support;
734 uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
735 MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
736 Working = 0;
737 }
738
739 // Accumulate the current type.
740 ++Count;
741 Working = Working << NumBitsPerType | Type;
742}
743
744uint64_t PGOHash::finalize() {
745 // Use Working as the hash directly if we never used MD5.
746 if (Count <= NumTypesPerWord)
747 // No need to byte swap here, since none of the math was endian-dependent.
748 // This number will be byte-swapped as required on endianness transitions,
749 // so we will see the same value on the other side.
750 return Working;
751
752 // Check for remaining work in Working.
serge-sans-paillede02a752020-05-25 20:44:35 +0200753 if (Working) {
754 // Keep the buggy behavior from v1 and v2 for backward-compatibility. This
755 // is buggy because it converts a uint64_t into an array of uint8_t.
756 if (HashVersion < PGO_HASH_V3) {
757 MD5.update({(uint8_t)Working});
758 } else {
759 using namespace llvm::support;
760 uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
761 MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
762 }
763 }
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000764
765 // Finalize the MD5 and return the hash.
766 llvm::MD5::MD5Result Result;
767 MD5.final(Result);
Zachary Turner82a0c972017-03-20 23:33:18 +0000768 return Result.low();
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000769}
770
Serge Pavlov3a561452015-12-06 14:32:39 +0000771void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
772 const Decl *D = GD.getDecl();
Vedant Kumar33d0a1c2017-06-30 21:02:14 +0000773 if (!D->hasBody())
774 return;
775
Rong Xu9837ef52016-02-04 18:39:09 +0000776 bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();
Justin Bogner837a6f62014-04-18 21:52:00 +0000777 llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
778 if (!InstrumentRegions && !PGOReader)
Justin Bogneref512b92014-01-06 22:27:43 +0000779 return;
Justin Bogner3212b182014-04-25 07:20:05 +0000780 if (D->isImplicit())
Justin Bogneref512b92014-01-06 22:27:43 +0000781 return;
Serge Pavlov3a561452015-12-06 14:32:39 +0000782 // Constructors and destructors may be represented by several functions in IR.
783 // If so, instrument only base variant, others are implemented by delegation
784 // to the base one, it would be counted twice otherwise.
Vedant Kumar7f809b22017-02-24 01:15:19 +0000785 if (CGM.getTarget().getCXXABI().hasConstructorVariants()) {
Vedant Kumar7f809b22017-02-24 01:15:19 +0000786 if (const auto *CCD = dyn_cast<CXXConstructorDecl>(D))
787 if (GD.getCtorType() != Ctor_Base &&
788 CodeGenFunction::IsConstructorDelegationValid(CCD))
789 return;
Serge Pavlov3a561452015-12-06 14:32:39 +0000790 }
Reid Klecknerf9ef9f82019-02-26 20:42:52 +0000791 if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
792 return;
793
Alex Lorenzee024992014-08-04 18:41:51 +0000794 CGM.ClearUnusedCoverageMapping(D);
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000795 setFuncName(Fn);
Duncan P. N. Exon Smith7c414512014-03-20 22:50:08 +0000796
Justin Bogneref512b92014-01-06 22:27:43 +0000797 mapRegionCounters(D);
Justin Bogner970ac602014-12-08 19:04:51 +0000798 if (CGM.getCodeGenOpts().CoverageMapping)
799 emitCounterRegionMapping(D);
Justin Bogner837a6f62014-04-18 21:52:00 +0000800 if (PGOReader) {
Justin Bogner40b8ba12014-06-26 01:45:07 +0000801 SourceManager &SM = CGM.getContext().getSourceManager();
802 loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
Bob Wilsonbf854f02014-02-17 19:21:09 +0000803 computeRegionCounts(D);
Justin Bogner837a6f62014-04-18 21:52:00 +0000804 applyFunctionAttributes(PGOReader, Fn);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000805 }
Justin Bogneref512b92014-01-06 22:27:43 +0000806}
807
808void CodeGenPGO::mapRegionCounters(const Decl *D) {
Vedant Kumar61869712017-11-14 23:56:53 +0000809 // Use the latest hash version when inserting instrumentation, but use the
810 // version in the indexed profile if we're reading PGO data.
811 PGOHashVersion HashVersion = PGO_HASH_LATEST;
812 if (auto *PGOReader = CGM.getPGOReader())
813 HashVersion = getPGOHashVersion(PGOReader, CGM);
814
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000815 RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
Vedant Kumar61869712017-11-14 23:56:53 +0000816 MapRegionCounters Walker(HashVersion, *RegionCounterMap);
Justin Bogneref512b92014-01-06 22:27:43 +0000817 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000818 Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000819 else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000820 Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
Bob Wilsonc845c002014-03-06 20:24:27 +0000821 else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000822 Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
Justin Bogner81ab90f2014-04-15 00:50:54 +0000823 else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
824 Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
Justin Bogner3212b182014-04-25 07:20:05 +0000825 assert(Walker.NextCounter > 0 && "no entry counter mapped for decl");
Justin Bogneref512b92014-01-06 22:27:43 +0000826 NumRegionCounters = Walker.NextCounter;
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000827 FunctionHash = Walker.Hash.finalize();
Justin Bogneref512b92014-01-06 22:27:43 +0000828}
829
Vedant Kumarc468bb82016-07-11 22:57:44 +0000830bool CodeGenPGO::skipRegionMappingForDecl(const Decl *D) {
Vedant Kumarbc370f02017-04-24 20:52:04 +0000831 if (!D->getBody())
832 return true;
833
Vedant Kumarc468bb82016-07-11 22:57:44 +0000834 // Don't map the functions in system headers.
835 const auto &SM = CGM.getContext().getSourceManager();
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000836 auto Loc = D->getBody()->getBeginLoc();
Vedant Kumarc468bb82016-07-11 22:57:44 +0000837 return SM.isInSystemHeader(Loc);
838}
839
840void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
841 if (skipRegionMappingForDecl(D))
Alex Lorenzee024992014-08-04 18:41:51 +0000842 return;
843
Justin Bogner970ac602014-12-08 19:04:51 +0000844 std::string CoverageMapping;
Alex Lorenzee024992014-08-04 18:41:51 +0000845 llvm::raw_string_ostream OS(CoverageMapping);
846 CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
847 CGM.getContext().getSourceManager(),
Justin Bognere5ee6c52014-10-02 16:44:01 +0000848 CGM.getLangOpts(), RegionCounterMap.get());
Alex Lorenzee024992014-08-04 18:41:51 +0000849 MappingGen.emitCounterMapping(D, OS);
850 OS.flush();
Justin Bogner970ac602014-12-08 19:04:51 +0000851
852 if (CoverageMapping.empty())
853 return;
854
855 CGM.getCoverageMapping()->addFunctionMappingRecord(
856 FuncNameVar, FuncName, FunctionHash, CoverageMapping);
Alex Lorenzee024992014-08-04 18:41:51 +0000857}
858
859void
Justin Bogner60d852b2015-04-23 00:31:16 +0000860CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef Name,
Alex Lorenzee024992014-08-04 18:41:51 +0000861 llvm::GlobalValue::LinkageTypes Linkage) {
Vedant Kumarc468bb82016-07-11 22:57:44 +0000862 if (skipRegionMappingForDecl(D))
Alex Lorenzee024992014-08-04 18:41:51 +0000863 return;
864
Justin Bogner970ac602014-12-08 19:04:51 +0000865 std::string CoverageMapping;
Alex Lorenzee024992014-08-04 18:41:51 +0000866 llvm::raw_string_ostream OS(CoverageMapping);
867 CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
868 CGM.getContext().getSourceManager(),
869 CGM.getLangOpts());
870 MappingGen.emitEmptyMapping(D, OS);
871 OS.flush();
Justin Bogner970ac602014-12-08 19:04:51 +0000872
873 if (CoverageMapping.empty())
874 return;
875
Justin Bogner60d852b2015-04-23 00:31:16 +0000876 setFuncName(Name, Linkage);
Justin Bogner970ac602014-12-08 19:04:51 +0000877 CGM.getCoverageMapping()->addFunctionMappingRecord(
Xinliang David Li2129ae52016-01-07 20:05:55 +0000878 FuncNameVar, FuncName, FunctionHash, CoverageMapping, false);
Alex Lorenzee024992014-08-04 18:41:51 +0000879}
880
Bob Wilsonbf854f02014-02-17 19:21:09 +0000881void CodeGenPGO::computeRegionCounts(const Decl *D) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000882 StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000883 ComputeRegionCounts Walker(*StmtCountMap, *this);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000884 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
885 Walker.VisitFunctionDecl(FD);
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000886 else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
887 Walker.VisitObjCMethodDecl(MD);
Bob Wilsonc845c002014-03-06 20:24:27 +0000888 else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
889 Walker.VisitBlockDecl(BD);
Justin Bogner81ab90f2014-04-15 00:50:54 +0000890 else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
891 Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
Bob Wilsonbf854f02014-02-17 19:21:09 +0000892}
893
Justin Bogner837a6f62014-04-18 21:52:00 +0000894void
895CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
896 llvm::Function *Fn) {
Justin Bogner4c9c45c2014-03-12 18:14:32 +0000897 if (!haveRegionCounts())
898 return;
899
Hans Wennborgdcfba332015-10-06 23:40:43 +0000900 uint64_t FunctionCount = getRegionCount(nullptr);
Diego Novilloaa8b1cb2015-05-27 21:58:42 +0000901 Fn->setEntryCount(FunctionCount);
Justin Bogner4c9c45c2014-03-12 18:14:32 +0000902}
903
Vedant Kumar502bbfa2017-02-25 06:35:45 +0000904void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S,
905 llvm::Value *StepV) {
Rong Xu9837ef52016-02-04 18:39:09 +0000906 if (!CGM.getCodeGenOpts().hasProfileClangInstr() || !RegionCounterMap)
Justin Bogneref512b92014-01-06 22:27:43 +0000907 return;
Duncan P. N. Exon Smith9f5260a2015-11-06 23:00:41 +0000908 if (!Builder.GetInsertBlock())
Justin Bogner203f91e2015-01-09 01:46:40 +0000909 return;
Justin Bogner66242d62015-04-23 23:06:47 +0000910
911 unsigned Counter = (*RegionCounterMap)[S];
Justin Bogner970ac602014-12-08 19:04:51 +0000912 auto *I8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
Vedant Kumar502bbfa2017-02-25 06:35:45 +0000913
914 llvm::Value *Args[] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
915 Builder.getInt64(FunctionHash),
916 Builder.getInt32(NumRegionCounters),
917 Builder.getInt32(Counter), StepV};
918 if (!StepV)
919 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
920 makeArrayRef(Args, 4));
921 else
922 Builder.CreateCall(
923 CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment_step),
924 makeArrayRef(Args));
Justin Bogneref512b92014-01-06 22:27:43 +0000925}
926
Betul Buyukkurt518276a2016-01-23 22:50:44 +0000927// This method either inserts a call to the profile run-time during
928// instrumentation or puts profile data into metadata for PGO use.
929void CodeGenPGO::valueProfile(CGBuilderTy &Builder, uint32_t ValueKind,
930 llvm::Instruction *ValueSite, llvm::Value *ValuePtr) {
931
932 if (!EnableValueProfiling)
933 return;
934
935 if (!ValuePtr || !ValueSite || !Builder.GetInsertBlock())
936 return;
937
Betul Buyukkurt3da993c2016-03-31 18:41:34 +0000938 if (isa<llvm::Constant>(ValuePtr))
939 return;
940
Rong Xu9837ef52016-02-04 18:39:09 +0000941 bool InstrumentValueSites = CGM.getCodeGenOpts().hasProfileClangInstr();
Betul Buyukkurt518276a2016-01-23 22:50:44 +0000942 if (InstrumentValueSites && RegionCounterMap) {
Betul Buyukkurtcb6f5f12016-03-29 20:44:09 +0000943 auto BuilderInsertPoint = Builder.saveIP();
944 Builder.SetInsertPoint(ValueSite);
Betul Buyukkurt518276a2016-01-23 22:50:44 +0000945 llvm::Value *Args[5] = {
Betul Buyukkurtcb6f5f12016-03-29 20:44:09 +0000946 llvm::ConstantExpr::getBitCast(FuncNameVar, Builder.getInt8PtrTy()),
Betul Buyukkurt518276a2016-01-23 22:50:44 +0000947 Builder.getInt64(FunctionHash),
948 Builder.CreatePtrToInt(ValuePtr, Builder.getInt64Ty()),
949 Builder.getInt32(ValueKind),
950 Builder.getInt32(NumValueSites[ValueKind]++)
951 };
952 Builder.CreateCall(
953 CGM.getIntrinsic(llvm::Intrinsic::instrprof_value_profile), Args);
Betul Buyukkurtcb6f5f12016-03-29 20:44:09 +0000954 Builder.restoreIP(BuilderInsertPoint);
Betul Buyukkurt518276a2016-01-23 22:50:44 +0000955 return;
956 }
957
958 llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
959 if (PGOReader && haveRegionCounts()) {
960 // We record the top most called three functions at each call site.
961 // Profile metadata contains "VP" string identifying this metadata
962 // as value profiling data, then a uint32_t value for the value profiling
963 // kind, a uint64_t value for the total number of times the call is
964 // executed, followed by the function hash and execution count (uint64_t)
965 // pairs for each function.
966 if (NumValueSites[ValueKind] >= ProfRecord->getNumValueSites(ValueKind))
967 return;
Betul Buyukkurt518276a2016-01-23 22:50:44 +0000968
Xinliang David Li5527a9d2016-02-04 19:54:17 +0000969 llvm::annotateValueSite(CGM.getModule(), *ValueSite, *ProfRecord,
970 (llvm::InstrProfValueKind)ValueKind,
971 NumValueSites[ValueKind]);
Betul Buyukkurt518276a2016-01-23 22:50:44 +0000972
Betul Buyukkurt518276a2016-01-23 22:50:44 +0000973 NumValueSites[ValueKind]++;
974 }
975}
976
Justin Bogner40b8ba12014-06-26 01:45:07 +0000977void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
978 bool IsInMainFile) {
979 CGM.getPGOStats().addVisited(IsInMainFile);
Justin Bogner7f8cf5b2014-12-02 22:38:52 +0000980 RegionCounts.clear();
Vedant Kumarfa2d5952016-05-19 03:54:54 +0000981 llvm::Expected<llvm::InstrProfRecord> RecordExpected =
Betul Buyukkurt518276a2016-01-23 22:50:44 +0000982 PGOReader->getInstrProfRecord(FuncName, FunctionHash);
Vedant Kumarfa2d5952016-05-19 03:54:54 +0000983 if (auto E = RecordExpected.takeError()) {
984 auto IPE = llvm::InstrProfError::take(std::move(E));
985 if (IPE == llvm::instrprof_error::unknown_function)
Justin Bogner9c6818e2014-08-01 22:50:16 +0000986 CGM.getPGOStats().addMissing(IsInMainFile);
Vedant Kumarfa2d5952016-05-19 03:54:54 +0000987 else if (IPE == llvm::instrprof_error::hash_mismatch)
Justin Bogner9c6818e2014-08-01 22:50:16 +0000988 CGM.getPGOStats().addMismatched(IsInMainFile);
Vedant Kumarfa2d5952016-05-19 03:54:54 +0000989 else if (IPE == llvm::instrprof_error::malformed)
Justin Bogner9c6818e2014-08-01 22:50:16 +0000990 // TODO: Consider a more specific warning for this case.
991 CGM.getPGOStats().addMismatched(IsInMainFile);
Betul Buyukkurt518276a2016-01-23 22:50:44 +0000992 return;
Justin Bognere2ef2a02014-04-15 21:22:35 +0000993 }
Betul Buyukkurt518276a2016-01-23 22:50:44 +0000994 ProfRecord =
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +0000995 std::make_unique<llvm::InstrProfRecord>(std::move(RecordExpected.get()));
Betul Buyukkurt518276a2016-01-23 22:50:44 +0000996 RegionCounts = ProfRecord->Counts;
Justin Bogneref512b92014-01-06 22:27:43 +0000997}
998
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000999/// Calculate what to divide by to scale weights.
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001000///
1001/// Given the maximum weight, calculate a divisor that will scale all the
1002/// weights to strictly less than UINT32_MAX.
1003static uint64_t calculateWeightScale(uint64_t MaxWeight) {
1004 return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
1005}
1006
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001007/// Scale an individual branch weight (and add 1).
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001008///
1009/// Scale a 64-bit weight down to 32-bits using \c Scale.
1010///
1011/// According to Laplace's Rule of Succession, it is better to compute the
1012/// weight based on the count plus 1, so universally add 1 to the value.
1013///
1014/// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
1015/// greater than \c Weight.
1016static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
1017 assert(Scale && "scale by 0?");
1018 uint64_t Scaled = Weight / Scale + 1;
1019 assert(Scaled <= UINT32_MAX && "overflow 32-bits");
1020 return Scaled;
1021}
1022
Justin Bogner65512642015-05-02 05:00:55 +00001023llvm::MDNode *CodeGenFunction::createProfileWeights(uint64_t TrueCount,
1024 uint64_t FalseCount) {
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001025 // Check for empty weights.
Justin Bogneref512b92014-01-06 22:27:43 +00001026 if (!TrueCount && !FalseCount)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +00001027 return nullptr;
Justin Bogneref512b92014-01-06 22:27:43 +00001028
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001029 // Calculate how to scale down to 32-bits.
1030 uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
1031
Justin Bogneref512b92014-01-06 22:27:43 +00001032 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001033 return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
1034 scaleBranchWeight(FalseCount, Scale));
Justin Bogneref512b92014-01-06 22:27:43 +00001035}
1036
Justin Bogner65512642015-05-02 05:00:55 +00001037llvm::MDNode *
1038CodeGenFunction::createProfileWeights(ArrayRef<uint64_t> Weights) {
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001039 // We need at least two elements to create meaningful weights.
1040 if (Weights.size() < 2)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +00001041 return nullptr;
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001042
Justin Bognerf3aefca2014-04-04 02:48:51 +00001043 // Check for empty weights.
1044 uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
1045 if (MaxWeight == 0)
1046 return nullptr;
1047
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001048 // Calculate how to scale down to 32-bits.
Justin Bognerf3aefca2014-04-04 02:48:51 +00001049 uint64_t Scale = calculateWeightScale(MaxWeight);
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001050
Justin Bogneref512b92014-01-06 22:27:43 +00001051 SmallVector<uint32_t, 16> ScaledWeights;
1052 ScaledWeights.reserve(Weights.size());
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001053 for (uint64_t W : Weights)
1054 ScaledWeights.push_back(scaleBranchWeight(W, Scale));
1055
1056 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
Justin Bogneref512b92014-01-06 22:27:43 +00001057 return MDHelper.createBranchWeights(ScaledWeights);
1058}
Bob Wilsonbf854f02014-02-17 19:21:09 +00001059
Justin Bogner65512642015-05-02 05:00:55 +00001060llvm::MDNode *CodeGenFunction::createProfileWeightsForLoop(const Stmt *Cond,
1061 uint64_t LoopCount) {
1062 if (!PGO.haveRegionCounts())
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +00001063 return nullptr;
Justin Bogner65512642015-05-02 05:00:55 +00001064 Optional<uint64_t> CondCount = PGO.getStmtCount(Cond);
Hans Wennborg55b9b112020-05-05 15:43:54 +02001065 if (!CondCount || *CondCount == 0)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +00001066 return nullptr;
Justin Bogner65512642015-05-02 05:00:55 +00001067 return createProfileWeights(LoopCount,
1068 std::max(*CondCount, LoopCount) - LoopCount);
Bob Wilsonbf854f02014-02-17 19:21:09 +00001069}