blob: 158a6ac17ba3f245f9dcc002510022bdcbac3298 [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) {
Justin Bogner111c6532014-12-02 23:15:30 +000031 StringRef RawFuncName = Name;
Bob Wilsonda1ebed2014-03-06 04:55:41 +000032
33 // Function names may be prefixed with a binary '1' to indicate
34 // that the backend should not modify the symbols due to any platform
35 // naming convention. Do not include that '1' in the PGO profile name.
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000036 if (RawFuncName[0] == '\1')
37 RawFuncName = RawFuncName.substr(1);
Bob Wilsonda1ebed2014-03-06 04:55:41 +000038
Justin Bogner111c6532014-12-02 23:15:30 +000039 FuncName = RawFuncName;
40 if (llvm::GlobalValue::isLocalLinkage(Linkage)) {
41 // For local symbols, prepend the main file name to distinguish them.
42 // Do not include the full path in the file name since there's no guarantee
43 // that it will stay the same, e.g., if the files are checked out from
44 // version control in different locations.
45 if (CGM.getCodeGenOpts().MainFileName.empty())
46 FuncName = FuncName.insert(0, "<unknown>:");
47 else
48 FuncName = FuncName.insert(0, CGM.getCodeGenOpts().MainFileName + ":");
Bob Wilsonda1ebed2014-03-06 04:55:41 +000049 }
Justin Bogner970ac602014-12-08 19:04:51 +000050
51 // If we're generating a profile, create a variable for the name.
52 if (CGM.getCodeGenOpts().ProfileInstrGenerate)
53 createFuncNameVar(Linkage);
Bob Wilsonda1ebed2014-03-06 04:55:41 +000054}
55
Alex Lorenzee024992014-08-04 18:41:51 +000056void CodeGenPGO::setFuncName(llvm::Function *Fn) {
57 setFuncName(Fn->getName(), Fn->getLinkage());
58}
59
Justin Bogner970ac602014-12-08 19:04:51 +000060void CodeGenPGO::createFuncNameVar(llvm::GlobalValue::LinkageTypes Linkage) {
Justin Bognere9fe0a22015-03-20 06:34:38 +000061 // We generally want to match the function's linkage, but available_externally
62 // and extern_weak both have the wrong semantics, and anything that doesn't
63 // need to link across compilation units doesn't need to be visible at all.
Justin Bogner970ac602014-12-08 19:04:51 +000064 if (Linkage == llvm::GlobalValue::ExternalWeakLinkage)
65 Linkage = llvm::GlobalValue::LinkOnceAnyLinkage;
66 else if (Linkage == llvm::GlobalValue::AvailableExternallyLinkage)
67 Linkage = llvm::GlobalValue::LinkOnceODRLinkage;
Justin Bognere9fe0a22015-03-20 06:34:38 +000068 else if (Linkage == llvm::GlobalValue::InternalLinkage ||
69 Linkage == llvm::GlobalValue::ExternalLinkage)
70 Linkage = llvm::GlobalValue::PrivateLinkage;
Alex Lorenzee024992014-08-04 18:41:51 +000071
Justin Bogner970ac602014-12-08 19:04:51 +000072 auto *Value =
73 llvm::ConstantDataArray::getString(CGM.getLLVMContext(), FuncName, false);
74 FuncNameVar =
75 new llvm::GlobalVariable(CGM.getModule(), Value->getType(), true, Linkage,
76 Value, "__llvm_profile_name_" + FuncName);
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000077
Justin Bogner970ac602014-12-08 19:04:51 +000078 // Hide the symbol so that we correctly get a copy for each executable.
79 if (!llvm::GlobalValue::isLocalLinkage(FuncNameVar->getLinkage()))
80 FuncNameVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
Justin Bogneref512b92014-01-06 22:27:43 +000081}
82
83namespace {
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +000084/// \brief Stable hasher for PGO region counters.
85///
86/// PGOHash produces a stable hash of a given function's control flow.
87///
88/// Changing the output of this hash will invalidate all previously generated
89/// profiles -- i.e., don't do it.
90///
91/// \note When this hash does eventually change (years?), we still need to
92/// support old hashes. We'll need to pull in the version number from the
93/// profile data format and use the matching hash function.
94class PGOHash {
95 uint64_t Working;
96 unsigned Count;
97 llvm::MD5 MD5;
98
99 static const int NumBitsPerType = 6;
100 static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
101 static const unsigned TooBig = 1u << NumBitsPerType;
102
103public:
104 /// \brief Hash values for AST nodes.
105 ///
106 /// Distinct values for AST nodes that have region counters attached.
107 ///
108 /// These values must be stable. All new members must be added at the end,
109 /// and no members should be removed. Changing the enumeration value for an
110 /// AST node will affect the hash of every function that contains that node.
111 enum HashType : unsigned char {
112 None = 0,
113 LabelStmt = 1,
114 WhileStmt,
115 DoStmt,
116 ForStmt,
117 CXXForRangeStmt,
118 ObjCForCollectionStmt,
119 SwitchStmt,
120 CaseStmt,
121 DefaultStmt,
122 IfStmt,
123 CXXTryStmt,
124 CXXCatchStmt,
125 ConditionalOperator,
126 BinaryOperatorLAnd,
127 BinaryOperatorLOr,
128 BinaryConditionalOperator,
129
130 // Keep this last. It's for the static assert that follows.
131 LastHashType
132 };
133 static_assert(LastHashType <= TooBig, "Too many types in HashType");
134
135 // TODO: When this format changes, take in a version number here, and use the
136 // old hash calculation for file formats that used the old hash.
137 PGOHash() : Working(0), Count(0) {}
138 void combine(HashType Type);
139 uint64_t finalize();
140};
141const int PGOHash::NumBitsPerType;
142const unsigned PGOHash::NumTypesPerWord;
143const unsigned PGOHash::TooBig;
144
Justin Bognere4ca4412015-02-23 19:27:00 +0000145/// A RecursiveASTVisitor that fills a map of statements to PGO counters.
146struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
147 /// The next counter value to assign.
148 unsigned NextCounter;
149 /// The function hash.
150 PGOHash Hash;
151 /// The map of statements to counters.
152 llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
Justin Bogneref512b92014-01-06 22:27:43 +0000153
Justin Bognere4ca4412015-02-23 19:27:00 +0000154 MapRegionCounters(llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
155 : NextCounter(0), CounterMap(CounterMap) {}
Justin Bogneref512b92014-01-06 22:27:43 +0000156
Justin Bognere4ca4412015-02-23 19:27:00 +0000157 // Blocks and lambdas are handled as separate functions, so we need not
158 // traverse them in the parent context.
159 bool TraverseBlockExpr(BlockExpr *BE) { return true; }
160 bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
161 bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
Justin Bogneref512b92014-01-06 22:27:43 +0000162
Justin Bognere4ca4412015-02-23 19:27:00 +0000163 bool VisitDecl(const Decl *D) {
164 switch (D->getKind()) {
165 default:
166 break;
167 case Decl::Function:
168 case Decl::CXXMethod:
169 case Decl::CXXConstructor:
170 case Decl::CXXDestructor:
171 case Decl::CXXConversion:
172 case Decl::ObjCMethod:
173 case Decl::Block:
174 case Decl::Captured:
175 CounterMap[D->getBody()] = NextCounter++;
176 break;
177 }
178 return true;
179 }
180
181 bool VisitStmt(const Stmt *S) {
182 auto Type = getHashType(S);
183 if (Type == PGOHash::None)
Bob Wilsond8931422014-04-11 17:16:13 +0000184 return true;
Bob Wilsond8931422014-04-11 17:16:13 +0000185
Justin Bognere4ca4412015-02-23 19:27:00 +0000186 CounterMap[S] = NextCounter++;
187 Hash.combine(Type);
188 return true;
189 }
190 PGOHash::HashType getHashType(const Stmt *S) {
191 switch (S->getStmtClass()) {
192 default:
193 break;
194 case Stmt::LabelStmtClass:
195 return PGOHash::LabelStmt;
196 case Stmt::WhileStmtClass:
197 return PGOHash::WhileStmt;
198 case Stmt::DoStmtClass:
199 return PGOHash::DoStmt;
200 case Stmt::ForStmtClass:
201 return PGOHash::ForStmt;
202 case Stmt::CXXForRangeStmtClass:
203 return PGOHash::CXXForRangeStmt;
204 case Stmt::ObjCForCollectionStmtClass:
205 return PGOHash::ObjCForCollectionStmt;
206 case Stmt::SwitchStmtClass:
207 return PGOHash::SwitchStmt;
208 case Stmt::CaseStmtClass:
209 return PGOHash::CaseStmt;
210 case Stmt::DefaultStmtClass:
211 return PGOHash::DefaultStmt;
212 case Stmt::IfStmtClass:
213 return PGOHash::IfStmt;
214 case Stmt::CXXTryStmtClass:
215 return PGOHash::CXXTryStmt;
216 case Stmt::CXXCatchStmtClass:
217 return PGOHash::CXXCatchStmt;
218 case Stmt::ConditionalOperatorClass:
219 return PGOHash::ConditionalOperator;
220 case Stmt::BinaryConditionalOperatorClass:
221 return PGOHash::BinaryConditionalOperator;
222 case Stmt::BinaryOperatorClass: {
223 const BinaryOperator *BO = cast<BinaryOperator>(S);
224 if (BO->getOpcode() == BO_LAnd)
225 return PGOHash::BinaryOperatorLAnd;
226 if (BO->getOpcode() == BO_LOr)
227 return PGOHash::BinaryOperatorLOr;
228 break;
229 }
230 }
231 return PGOHash::None;
232 }
233};
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000234
Justin Bognere4ca4412015-02-23 19:27:00 +0000235/// A StmtVisitor that propagates the raw counts through the AST and
236/// records the count at statements where the value may change.
237struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
238 /// PGO state.
239 CodeGenPGO &PGO;
240
241 /// A flag that is set when the current count should be recorded on the
242 /// next statement, such as at the exit of a loop.
243 bool RecordNextStmtCount;
244
Justin Bognera909abf2015-05-02 00:48:27 +0000245 /// The count at the current location in the traversal.
246 uint64_t CurrentCount;
247
Justin Bognere4ca4412015-02-23 19:27:00 +0000248 /// The map of statements to count values.
249 llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
250
251 /// BreakContinueStack - Keep counts of breaks and continues inside loops.
252 struct BreakContinue {
253 uint64_t BreakCount;
254 uint64_t ContinueCount;
255 BreakContinue() : BreakCount(0), ContinueCount(0) {}
Justin Bogneref512b92014-01-06 22:27:43 +0000256 };
Justin Bognere4ca4412015-02-23 19:27:00 +0000257 SmallVector<BreakContinue, 8> BreakContinueStack;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000258
Justin Bognere4ca4412015-02-23 19:27:00 +0000259 ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
260 CodeGenPGO &PGO)
261 : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
Bob Wilsonbf854f02014-02-17 19:21:09 +0000262
Justin Bognere4ca4412015-02-23 19:27:00 +0000263 void RecordStmtCount(const Stmt *S) {
264 if (RecordNextStmtCount) {
Justin Bognera909abf2015-05-02 00:48:27 +0000265 CountMap[S] = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000266 RecordNextStmtCount = false;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000267 }
Justin Bognere4ca4412015-02-23 19:27:00 +0000268 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000269
Justin Bogner07193cc2015-05-01 23:41:09 +0000270 /// Set and return the current count.
271 uint64_t setCount(uint64_t Count) {
Justin Bognera909abf2015-05-02 00:48:27 +0000272 CurrentCount = Count;
Justin Bogner07193cc2015-05-01 23:41:09 +0000273 return Count;
274 }
275
Justin Bognere4ca4412015-02-23 19:27:00 +0000276 void VisitStmt(const Stmt *S) {
277 RecordStmtCount(S);
278 for (Stmt::const_child_range I = S->children(); I; ++I) {
279 if (*I)
280 this->Visit(*I);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000281 }
Justin Bognere4ca4412015-02-23 19:27:00 +0000282 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000283
Justin Bognere4ca4412015-02-23 19:27:00 +0000284 void VisitFunctionDecl(const FunctionDecl *D) {
285 // Counter tracks entry to the function body.
Justin Bogner07193cc2015-05-01 23:41:09 +0000286 uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
287 CountMap[D->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000288 Visit(D->getBody());
289 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000290
Justin Bognere4ca4412015-02-23 19:27:00 +0000291 // Skip lambda expressions. We visit these as FunctionDecls when we're
292 // generating them and aren't interested in the body when generating a
293 // parent context.
294 void VisitLambdaExpr(const LambdaExpr *LE) {}
Bob Wilsonbf854f02014-02-17 19:21:09 +0000295
Justin Bognere4ca4412015-02-23 19:27:00 +0000296 void VisitCapturedDecl(const CapturedDecl *D) {
297 // Counter tracks entry to the capture body.
Justin Bogner07193cc2015-05-01 23:41:09 +0000298 uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
299 CountMap[D->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000300 Visit(D->getBody());
301 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000302
Justin Bognere4ca4412015-02-23 19:27:00 +0000303 void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
304 // Counter tracks entry to the method body.
Justin Bogner07193cc2015-05-01 23:41:09 +0000305 uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
306 CountMap[D->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000307 Visit(D->getBody());
308 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000309
Justin Bognere4ca4412015-02-23 19:27:00 +0000310 void VisitBlockDecl(const BlockDecl *D) {
311 // Counter tracks entry to the block body.
Justin Bogner07193cc2015-05-01 23:41:09 +0000312 uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
313 CountMap[D->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000314 Visit(D->getBody());
315 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000316
Justin Bognere4ca4412015-02-23 19:27:00 +0000317 void VisitReturnStmt(const ReturnStmt *S) {
318 RecordStmtCount(S);
319 if (S->getRetValue())
320 Visit(S->getRetValue());
Justin Bognera909abf2015-05-02 00:48:27 +0000321 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000322 RecordNextStmtCount = true;
323 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000324
Justin Bognerf959feb2015-04-28 06:31:55 +0000325 void VisitCXXThrowExpr(const CXXThrowExpr *E) {
326 RecordStmtCount(E);
327 if (E->getSubExpr())
328 Visit(E->getSubExpr());
Justin Bognera909abf2015-05-02 00:48:27 +0000329 CurrentCount = 0;
Justin Bognerf959feb2015-04-28 06:31:55 +0000330 RecordNextStmtCount = true;
331 }
332
Justin Bognere4ca4412015-02-23 19:27:00 +0000333 void VisitGotoStmt(const GotoStmt *S) {
334 RecordStmtCount(S);
Justin Bognera909abf2015-05-02 00:48:27 +0000335 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000336 RecordNextStmtCount = true;
337 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000338
Justin Bognere4ca4412015-02-23 19:27:00 +0000339 void VisitLabelStmt(const LabelStmt *S) {
340 RecordNextStmtCount = false;
341 // Counter tracks the block following the label.
Justin Bogner07193cc2015-05-01 23:41:09 +0000342 uint64_t BlockCount = setCount(PGO.getRegionCount(S));
343 CountMap[S] = BlockCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000344 Visit(S->getSubStmt());
345 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000346
Justin Bognere4ca4412015-02-23 19:27:00 +0000347 void VisitBreakStmt(const BreakStmt *S) {
348 RecordStmtCount(S);
349 assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
Justin Bognera909abf2015-05-02 00:48:27 +0000350 BreakContinueStack.back().BreakCount += CurrentCount;
351 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000352 RecordNextStmtCount = true;
353 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000354
Justin Bognere4ca4412015-02-23 19:27:00 +0000355 void VisitContinueStmt(const ContinueStmt *S) {
356 RecordStmtCount(S);
357 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
Justin Bognera909abf2015-05-02 00:48:27 +0000358 BreakContinueStack.back().ContinueCount += CurrentCount;
359 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000360 RecordNextStmtCount = true;
361 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000362
Justin Bognere4ca4412015-02-23 19:27:00 +0000363 void VisitWhileStmt(const WhileStmt *S) {
364 RecordStmtCount(S);
Justin Bognera909abf2015-05-02 00:48:27 +0000365 uint64_t ParentCount = CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000366
Justin Bognere4ca4412015-02-23 19:27:00 +0000367 BreakContinueStack.push_back(BreakContinue());
368 // Visit the body region first so the break/continue adjustments can be
369 // included when visiting the condition.
Justin Bogner07193cc2015-05-01 23:41:09 +0000370 uint64_t BodyCount = setCount(PGO.getRegionCount(S));
Justin Bognera909abf2015-05-02 00:48:27 +0000371 CountMap[S->getBody()] = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000372 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000373 uint64_t BackedgeCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000374
375 // ...then go back and propagate counts through the condition. The count
376 // at the start of the condition is the sum of the incoming edges,
377 // the backedge from the end of the loop body, and the edges from
378 // continue statements.
379 BreakContinue BC = BreakContinueStack.pop_back_val();
Justin Bogner07193cc2015-05-01 23:41:09 +0000380 uint64_t CondCount =
381 setCount(ParentCount + BackedgeCount + BC.ContinueCount);
382 CountMap[S->getCond()] = CondCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000383 Visit(S->getCond());
Justin Bogner07193cc2015-05-01 23:41:09 +0000384 setCount(BC.BreakCount + CondCount - BodyCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000385 RecordNextStmtCount = true;
386 }
387
388 void VisitDoStmt(const DoStmt *S) {
389 RecordStmtCount(S);
Justin Bogner07193cc2015-05-01 23:41:09 +0000390 uint64_t LoopCount = PGO.getRegionCount(S);
391
Justin Bognere4ca4412015-02-23 19:27:00 +0000392 BreakContinueStack.push_back(BreakContinue());
Justin Bogner07193cc2015-05-01 23:41:09 +0000393 // The count doesn't include the fallthrough from the parent scope. Add it.
Justin Bognera909abf2015-05-02 00:48:27 +0000394 uint64_t BodyCount = setCount(LoopCount + CurrentCount);
Justin Bogner07193cc2015-05-01 23:41:09 +0000395 CountMap[S->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000396 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000397 uint64_t BackedgeCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000398
399 BreakContinue BC = BreakContinueStack.pop_back_val();
400 // The count at the start of the condition is equal to the count at the
Justin Bogner07193cc2015-05-01 23:41:09 +0000401 // end of the body, plus any continues.
402 uint64_t CondCount = setCount(BackedgeCount + BC.ContinueCount);
403 CountMap[S->getCond()] = CondCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000404 Visit(S->getCond());
Justin Bogner07193cc2015-05-01 23:41:09 +0000405 setCount(BC.BreakCount + CondCount - LoopCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000406 RecordNextStmtCount = true;
407 }
408
409 void VisitForStmt(const ForStmt *S) {
410 RecordStmtCount(S);
411 if (S->getInit())
412 Visit(S->getInit());
Justin Bogner07193cc2015-05-01 23:41:09 +0000413
Justin Bognera909abf2015-05-02 00:48:27 +0000414 uint64_t ParentCount = CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000415
Justin Bognere4ca4412015-02-23 19:27:00 +0000416 BreakContinueStack.push_back(BreakContinue());
417 // Visit the body region first. (This is basically the same as a while
418 // loop; see further comments in VisitWhileStmt.)
Justin Bogner07193cc2015-05-01 23:41:09 +0000419 uint64_t BodyCount = setCount(PGO.getRegionCount(S));
420 CountMap[S->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000421 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000422 uint64_t BackedgeCount = CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000423 BreakContinue BC = BreakContinueStack.pop_back_val();
Justin Bognere4ca4412015-02-23 19:27:00 +0000424
425 // The increment is essentially part of the body but it needs to include
426 // the count for all the continue statements.
427 if (S->getInc()) {
Justin Bogner07193cc2015-05-01 23:41:09 +0000428 uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
429 CountMap[S->getInc()] = IncCount;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000430 Visit(S->getInc());
Justin Bognere4ca4412015-02-23 19:27:00 +0000431 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000432
Justin Bognere4ca4412015-02-23 19:27:00 +0000433 // ...then go back and propagate counts through the condition.
Justin Bogner07193cc2015-05-01 23:41:09 +0000434 uint64_t CondCount =
435 setCount(ParentCount + BackedgeCount + BC.ContinueCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000436 if (S->getCond()) {
Justin Bogner07193cc2015-05-01 23:41:09 +0000437 CountMap[S->getCond()] = CondCount;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000438 Visit(S->getCond());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000439 }
Justin Bogner07193cc2015-05-01 23:41:09 +0000440 setCount(BC.BreakCount + CondCount - BodyCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000441 RecordNextStmtCount = true;
442 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000443
Justin Bognere4ca4412015-02-23 19:27:00 +0000444 void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
445 RecordStmtCount(S);
Justin Bogner2e5d4842015-04-30 22:58:28 +0000446 Visit(S->getLoopVarStmt());
Justin Bognere4ca4412015-02-23 19:27:00 +0000447 Visit(S->getRangeStmt());
448 Visit(S->getBeginEndStmt());
Justin Bogner07193cc2015-05-01 23:41:09 +0000449
Justin Bognera909abf2015-05-02 00:48:27 +0000450 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000451 BreakContinueStack.push_back(BreakContinue());
452 // Visit the body region first. (This is basically the same as a while
453 // loop; see further comments in VisitWhileStmt.)
Justin Bogner07193cc2015-05-01 23:41:09 +0000454 uint64_t BodyCount = setCount(PGO.getRegionCount(S));
455 CountMap[S->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000456 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000457 uint64_t BackedgeCount = CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000458 BreakContinue BC = BreakContinueStack.pop_back_val();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000459
Justin Bognere4ca4412015-02-23 19:27:00 +0000460 // The increment is essentially part of the body but it needs to include
461 // the count for all the continue statements.
Justin Bogner07193cc2015-05-01 23:41:09 +0000462 uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
463 CountMap[S->getInc()] = IncCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000464 Visit(S->getInc());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000465
Justin Bognere4ca4412015-02-23 19:27:00 +0000466 // ...then go back and propagate counts through the condition.
Justin Bogner07193cc2015-05-01 23:41:09 +0000467 uint64_t CondCount =
468 setCount(ParentCount + BackedgeCount + BC.ContinueCount);
469 CountMap[S->getCond()] = CondCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000470 Visit(S->getCond());
Justin Bogner07193cc2015-05-01 23:41:09 +0000471 setCount(BC.BreakCount + CondCount - BodyCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000472 RecordNextStmtCount = true;
473 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000474
Justin Bognere4ca4412015-02-23 19:27:00 +0000475 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
476 RecordStmtCount(S);
477 Visit(S->getElement());
Justin Bognera909abf2015-05-02 00:48:27 +0000478 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000479 BreakContinueStack.push_back(BreakContinue());
Justin Bogner07193cc2015-05-01 23:41:09 +0000480 // Counter tracks the body of the loop.
481 uint64_t BodyCount = setCount(PGO.getRegionCount(S));
482 CountMap[S->getBody()] = BodyCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000483 Visit(S->getBody());
Justin Bognera909abf2015-05-02 00:48:27 +0000484 uint64_t BackedgeCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000485 BreakContinue BC = BreakContinueStack.pop_back_val();
Justin Bogner07193cc2015-05-01 23:41:09 +0000486
487 setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount -
488 BodyCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000489 RecordNextStmtCount = true;
490 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000491
Justin Bognere4ca4412015-02-23 19:27:00 +0000492 void VisitSwitchStmt(const SwitchStmt *S) {
493 RecordStmtCount(S);
494 Visit(S->getCond());
Justin Bognera909abf2015-05-02 00:48:27 +0000495 CurrentCount = 0;
Justin Bognere4ca4412015-02-23 19:27:00 +0000496 BreakContinueStack.push_back(BreakContinue());
497 Visit(S->getBody());
498 // If the switch is inside a loop, add the continue counts.
499 BreakContinue BC = BreakContinueStack.pop_back_val();
500 if (!BreakContinueStack.empty())
501 BreakContinueStack.back().ContinueCount += BC.ContinueCount;
502 // Counter tracks the exit block of the switch.
Justin Bogner07193cc2015-05-01 23:41:09 +0000503 setCount(PGO.getRegionCount(S));
Justin Bognere4ca4412015-02-23 19:27:00 +0000504 RecordNextStmtCount = true;
505 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000506
Justin Bogner07193cc2015-05-01 23:41:09 +0000507 void VisitSwitchCase(const SwitchCase *S) {
Justin Bognere4ca4412015-02-23 19:27:00 +0000508 RecordNextStmtCount = false;
509 // Counter for this particular case. This counts only jumps from the
510 // switch header and does not include fallthrough from the case before
511 // this one.
Justin Bogner07193cc2015-05-01 23:41:09 +0000512 uint64_t CaseCount = PGO.getRegionCount(S);
Justin Bognera909abf2015-05-02 00:48:27 +0000513 setCount(CurrentCount + CaseCount);
Justin Bogner07193cc2015-05-01 23:41:09 +0000514 // We need the count without fallthrough in the mapping, so it's more useful
515 // for branch probabilities.
516 CountMap[S] = CaseCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000517 RecordNextStmtCount = true;
518 Visit(S->getSubStmt());
519 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000520
Justin Bognere4ca4412015-02-23 19:27:00 +0000521 void VisitIfStmt(const IfStmt *S) {
522 RecordStmtCount(S);
Justin Bognera909abf2015-05-02 00:48:27 +0000523 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000524 Visit(S->getCond());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000525
Justin Bogner07193cc2015-05-01 23:41:09 +0000526 // Counter tracks the "then" part of an if statement. The count for
527 // the "else" part, if it exists, will be calculated from this counter.
528 uint64_t ThenCount = setCount(PGO.getRegionCount(S));
529 CountMap[S->getThen()] = ThenCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000530 Visit(S->getThen());
Justin Bognera909abf2015-05-02 00:48:27 +0000531 uint64_t OutCount = CurrentCount;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000532
Justin Bogner07193cc2015-05-01 23:41:09 +0000533 uint64_t ElseCount = ParentCount - ThenCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000534 if (S->getElse()) {
Justin Bogner07193cc2015-05-01 23:41:09 +0000535 setCount(ElseCount);
536 CountMap[S->getElse()] = ElseCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000537 Visit(S->getElse());
Justin Bognera909abf2015-05-02 00:48:27 +0000538 OutCount += CurrentCount;
Justin Bogner07193cc2015-05-01 23:41:09 +0000539 } else
540 OutCount += ElseCount;
541 setCount(OutCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000542 RecordNextStmtCount = true;
543 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000544
Justin Bognere4ca4412015-02-23 19:27:00 +0000545 void VisitCXXTryStmt(const CXXTryStmt *S) {
546 RecordStmtCount(S);
547 Visit(S->getTryBlock());
548 for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
549 Visit(S->getHandler(I));
550 // Counter tracks the continuation block of the try statement.
Justin Bogner07193cc2015-05-01 23:41:09 +0000551 setCount(PGO.getRegionCount(S));
Justin Bognere4ca4412015-02-23 19:27:00 +0000552 RecordNextStmtCount = true;
553 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000554
Justin Bognere4ca4412015-02-23 19:27:00 +0000555 void VisitCXXCatchStmt(const CXXCatchStmt *S) {
556 RecordNextStmtCount = false;
557 // Counter tracks the catch statement's handler block.
Justin Bogner07193cc2015-05-01 23:41:09 +0000558 uint64_t CatchCount = setCount(PGO.getRegionCount(S));
559 CountMap[S] = CatchCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000560 Visit(S->getHandlerBlock());
561 }
562
563 void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
564 RecordStmtCount(E);
Justin Bognera909abf2015-05-02 00:48:27 +0000565 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000566 Visit(E->getCond());
567
Justin Bogner07193cc2015-05-01 23:41:09 +0000568 // Counter tracks the "true" part of a conditional operator. The
569 // count in the "false" part will be calculated from this counter.
570 uint64_t TrueCount = setCount(PGO.getRegionCount(E));
571 CountMap[E->getTrueExpr()] = TrueCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000572 Visit(E->getTrueExpr());
Justin Bognera909abf2015-05-02 00:48:27 +0000573 uint64_t OutCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000574
Justin Bogner07193cc2015-05-01 23:41:09 +0000575 uint64_t FalseCount = setCount(ParentCount - TrueCount);
576 CountMap[E->getFalseExpr()] = FalseCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000577 Visit(E->getFalseExpr());
Justin Bognera909abf2015-05-02 00:48:27 +0000578 OutCount += CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000579
Justin Bogner07193cc2015-05-01 23:41:09 +0000580 setCount(OutCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000581 RecordNextStmtCount = true;
582 }
583
584 void VisitBinLAnd(const BinaryOperator *E) {
585 RecordStmtCount(E);
Justin Bognera909abf2015-05-02 00:48:27 +0000586 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000587 Visit(E->getLHS());
Justin Bogner07193cc2015-05-01 23:41:09 +0000588 // Counter tracks the right hand side of a logical and operator.
589 uint64_t RHSCount = setCount(PGO.getRegionCount(E));
590 CountMap[E->getRHS()] = RHSCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000591 Visit(E->getRHS());
Justin Bognera909abf2015-05-02 00:48:27 +0000592 setCount(ParentCount + RHSCount - CurrentCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000593 RecordNextStmtCount = true;
594 }
595
596 void VisitBinLOr(const BinaryOperator *E) {
597 RecordStmtCount(E);
Justin Bognera909abf2015-05-02 00:48:27 +0000598 uint64_t ParentCount = CurrentCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000599 Visit(E->getLHS());
Justin Bogner07193cc2015-05-01 23:41:09 +0000600 // Counter tracks the right hand side of a logical or operator.
601 uint64_t RHSCount = setCount(PGO.getRegionCount(E));
602 CountMap[E->getRHS()] = RHSCount;
Justin Bognere4ca4412015-02-23 19:27:00 +0000603 Visit(E->getRHS());
Justin Bognera909abf2015-05-02 00:48:27 +0000604 setCount(ParentCount + RHSCount - CurrentCount);
Justin Bognere4ca4412015-02-23 19:27:00 +0000605 RecordNextStmtCount = true;
606 }
607};
Justin Bogneref512b92014-01-06 22:27:43 +0000608}
609
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000610void PGOHash::combine(HashType Type) {
611 // Check that we never combine 0 and only have six bits.
612 assert(Type && "Hash is invalid: unexpected type 0");
613 assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
614
615 // Pass through MD5 if enough work has built up.
616 if (Count && Count % NumTypesPerWord == 0) {
617 using namespace llvm::support;
618 uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
619 MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
620 Working = 0;
621 }
622
623 // Accumulate the current type.
624 ++Count;
625 Working = Working << NumBitsPerType | Type;
626}
627
628uint64_t PGOHash::finalize() {
629 // Use Working as the hash directly if we never used MD5.
630 if (Count <= NumTypesPerWord)
631 // No need to byte swap here, since none of the math was endian-dependent.
632 // This number will be byte-swapped as required on endianness transitions,
633 // so we will see the same value on the other side.
634 return Working;
635
636 // Check for remaining work in Working.
637 if (Working)
638 MD5.update(Working);
639
640 // Finalize the MD5 and return the hash.
641 llvm::MD5::MD5Result Result;
642 MD5.final(Result);
643 using namespace llvm::support;
644 return endian::read<uint64_t, little, unaligned>(Result);
645}
646
Alex Lorenzee024992014-08-04 18:41:51 +0000647void CodeGenPGO::checkGlobalDecl(GlobalDecl GD) {
648 // Make sure we only emit coverage mapping for one constructor/destructor.
649 // Clang emits several functions for the constructor and the destructor of
650 // a class. Every function is instrumented, but we only want to provide
651 // coverage for one of them. Because of that we only emit the coverage mapping
652 // for the base constructor/destructor.
653 if ((isa<CXXConstructorDecl>(GD.getDecl()) &&
Alex Lorenzd4236742014-08-11 18:21:34 +0000654 GD.getCtorType() != Ctor_Base) ||
Alex Lorenzee024992014-08-04 18:41:51 +0000655 (isa<CXXDestructorDecl>(GD.getDecl()) &&
656 GD.getDtorType() != Dtor_Base)) {
657 SkipCoverageMapping = true;
658 }
659}
660
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000661void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
Justin Bogneref512b92014-01-06 22:27:43 +0000662 bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
Justin Bogner837a6f62014-04-18 21:52:00 +0000663 llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
664 if (!InstrumentRegions && !PGOReader)
Justin Bogneref512b92014-01-06 22:27:43 +0000665 return;
Justin Bogner3212b182014-04-25 07:20:05 +0000666 if (D->isImplicit())
Justin Bogneref512b92014-01-06 22:27:43 +0000667 return;
Alex Lorenzee024992014-08-04 18:41:51 +0000668 CGM.ClearUnusedCoverageMapping(D);
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000669 setFuncName(Fn);
Duncan P. N. Exon Smith7c414512014-03-20 22:50:08 +0000670
Justin Bogneref512b92014-01-06 22:27:43 +0000671 mapRegionCounters(D);
Justin Bogner970ac602014-12-08 19:04:51 +0000672 if (CGM.getCodeGenOpts().CoverageMapping)
673 emitCounterRegionMapping(D);
Justin Bogner837a6f62014-04-18 21:52:00 +0000674 if (PGOReader) {
Justin Bogner40b8ba12014-06-26 01:45:07 +0000675 SourceManager &SM = CGM.getContext().getSourceManager();
676 loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
Bob Wilsonbf854f02014-02-17 19:21:09 +0000677 computeRegionCounts(D);
Justin Bogner837a6f62014-04-18 21:52:00 +0000678 applyFunctionAttributes(PGOReader, Fn);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000679 }
Justin Bogneref512b92014-01-06 22:27:43 +0000680}
681
682void CodeGenPGO::mapRegionCounters(const Decl *D) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000683 RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000684 MapRegionCounters Walker(*RegionCounterMap);
Justin Bogneref512b92014-01-06 22:27:43 +0000685 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000686 Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000687 else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000688 Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
Bob Wilsonc845c002014-03-06 20:24:27 +0000689 else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000690 Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
Justin Bogner81ab90f2014-04-15 00:50:54 +0000691 else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
692 Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
Justin Bogner3212b182014-04-25 07:20:05 +0000693 assert(Walker.NextCounter > 0 && "no entry counter mapped for decl");
Justin Bogneref512b92014-01-06 22:27:43 +0000694 NumRegionCounters = Walker.NextCounter;
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000695 FunctionHash = Walker.Hash.finalize();
Justin Bogneref512b92014-01-06 22:27:43 +0000696}
697
Alex Lorenzee024992014-08-04 18:41:51 +0000698void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
699 if (SkipCoverageMapping)
700 return;
701 // Don't map the functions inside the system headers
702 auto Loc = D->getBody()->getLocStart();
703 if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))
704 return;
705
Justin Bogner970ac602014-12-08 19:04:51 +0000706 std::string CoverageMapping;
Alex Lorenzee024992014-08-04 18:41:51 +0000707 llvm::raw_string_ostream OS(CoverageMapping);
708 CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
709 CGM.getContext().getSourceManager(),
Justin Bognere5ee6c52014-10-02 16:44:01 +0000710 CGM.getLangOpts(), RegionCounterMap.get());
Alex Lorenzee024992014-08-04 18:41:51 +0000711 MappingGen.emitCounterMapping(D, OS);
712 OS.flush();
Justin Bogner970ac602014-12-08 19:04:51 +0000713
714 if (CoverageMapping.empty())
715 return;
716
717 CGM.getCoverageMapping()->addFunctionMappingRecord(
718 FuncNameVar, FuncName, FunctionHash, CoverageMapping);
Alex Lorenzee024992014-08-04 18:41:51 +0000719}
720
721void
Justin Bogner60d852b2015-04-23 00:31:16 +0000722CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef Name,
Alex Lorenzee024992014-08-04 18:41:51 +0000723 llvm::GlobalValue::LinkageTypes Linkage) {
724 if (SkipCoverageMapping)
725 return;
Alex Lorenzee024992014-08-04 18:41:51 +0000726 // Don't map the functions inside the system headers
727 auto Loc = D->getBody()->getLocStart();
728 if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))
729 return;
730
Justin Bogner970ac602014-12-08 19:04:51 +0000731 std::string CoverageMapping;
Alex Lorenzee024992014-08-04 18:41:51 +0000732 llvm::raw_string_ostream OS(CoverageMapping);
733 CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
734 CGM.getContext().getSourceManager(),
735 CGM.getLangOpts());
736 MappingGen.emitEmptyMapping(D, OS);
737 OS.flush();
Justin Bogner970ac602014-12-08 19:04:51 +0000738
739 if (CoverageMapping.empty())
740 return;
741
Justin Bogner60d852b2015-04-23 00:31:16 +0000742 setFuncName(Name, Linkage);
Justin Bogner970ac602014-12-08 19:04:51 +0000743 CGM.getCoverageMapping()->addFunctionMappingRecord(
744 FuncNameVar, FuncName, FunctionHash, CoverageMapping);
Alex Lorenzee024992014-08-04 18:41:51 +0000745}
746
Bob Wilsonbf854f02014-02-17 19:21:09 +0000747void CodeGenPGO::computeRegionCounts(const Decl *D) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000748 StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000749 ComputeRegionCounts Walker(*StmtCountMap, *this);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000750 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
751 Walker.VisitFunctionDecl(FD);
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000752 else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
753 Walker.VisitObjCMethodDecl(MD);
Bob Wilsonc845c002014-03-06 20:24:27 +0000754 else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
755 Walker.VisitBlockDecl(BD);
Justin Bogner81ab90f2014-04-15 00:50:54 +0000756 else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
757 Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
Bob Wilsonbf854f02014-02-17 19:21:09 +0000758}
759
Justin Bogner837a6f62014-04-18 21:52:00 +0000760void
761CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
762 llvm::Function *Fn) {
Justin Bogner4c9c45c2014-03-12 18:14:32 +0000763 if (!haveRegionCounts())
764 return;
765
Justin Bogner837a6f62014-04-18 21:52:00 +0000766 uint64_t MaxFunctionCount = PGOReader->getMaximumFunctionCount();
Justin Bogner4c9c45c2014-03-12 18:14:32 +0000767 uint64_t FunctionCount = getRegionCount(0);
768 if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount))
769 // Turn on InlineHint attribute for hot functions.
770 // FIXME: 30% is from preliminary tuning on SPEC, it may not be optimal.
771 Fn->addFnAttr(llvm::Attribute::InlineHint);
772 else if (FunctionCount <= (uint64_t)(0.01 * (double)MaxFunctionCount))
773 // Turn on Cold attribute for cold functions.
774 // FIXME: 1% is from preliminary tuning on SPEC, it may not be optimal.
775 Fn->addFnAttr(llvm::Attribute::Cold);
776}
777
Justin Bogner66242d62015-04-23 23:06:47 +0000778void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S) {
Justin Bogner970ac602014-12-08 19:04:51 +0000779 if (!CGM.getCodeGenOpts().ProfileInstrGenerate || !RegionCounterMap)
Justin Bogneref512b92014-01-06 22:27:43 +0000780 return;
Justin Bogner203f91e2015-01-09 01:46:40 +0000781 if (!Builder.GetInsertPoint())
782 return;
Justin Bogner66242d62015-04-23 23:06:47 +0000783
784 unsigned Counter = (*RegionCounterMap)[S];
Justin Bogner970ac602014-12-08 19:04:51 +0000785 auto *I8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
786 Builder.CreateCall4(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
787 llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
788 Builder.getInt64(FunctionHash),
789 Builder.getInt32(NumRegionCounters),
790 Builder.getInt32(Counter));
Justin Bogneref512b92014-01-06 22:27:43 +0000791}
792
Justin Bogner40b8ba12014-06-26 01:45:07 +0000793void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
794 bool IsInMainFile) {
795 CGM.getPGOStats().addVisited(IsInMainFile);
Justin Bogner7f8cf5b2014-12-02 22:38:52 +0000796 RegionCounts.clear();
Justin Bogner970ac602014-12-08 19:04:51 +0000797 if (std::error_code EC =
798 PGOReader->getFunctionCounts(FuncName, FunctionHash, RegionCounts)) {
Justin Bogner9c6818e2014-08-01 22:50:16 +0000799 if (EC == llvm::instrprof_error::unknown_function)
800 CGM.getPGOStats().addMissing(IsInMainFile);
801 else if (EC == llvm::instrprof_error::hash_mismatch)
802 CGM.getPGOStats().addMismatched(IsInMainFile);
803 else if (EC == llvm::instrprof_error::malformed)
804 // TODO: Consider a more specific warning for this case.
805 CGM.getPGOStats().addMismatched(IsInMainFile);
Justin Bogner7f8cf5b2014-12-02 22:38:52 +0000806 RegionCounts.clear();
Justin Bognere2ef2a02014-04-15 21:22:35 +0000807 }
Justin Bogneref512b92014-01-06 22:27:43 +0000808}
809
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000810/// \brief Calculate what to divide by to scale weights.
811///
812/// Given the maximum weight, calculate a divisor that will scale all the
813/// weights to strictly less than UINT32_MAX.
814static uint64_t calculateWeightScale(uint64_t MaxWeight) {
815 return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
816}
817
818/// \brief Scale an individual branch weight (and add 1).
819///
820/// Scale a 64-bit weight down to 32-bits using \c Scale.
821///
822/// According to Laplace's Rule of Succession, it is better to compute the
823/// weight based on the count plus 1, so universally add 1 to the value.
824///
825/// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
826/// greater than \c Weight.
827static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
828 assert(Scale && "scale by 0?");
829 uint64_t Scaled = Weight / Scale + 1;
830 assert(Scaled <= UINT32_MAX && "overflow 32-bits");
831 return Scaled;
832}
833
Justin Bogneref512b92014-01-06 22:27:43 +0000834llvm::MDNode *CodeGenPGO::createBranchWeights(uint64_t TrueCount,
835 uint64_t FalseCount) {
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000836 // Check for empty weights.
Justin Bogneref512b92014-01-06 22:27:43 +0000837 if (!TrueCount && !FalseCount)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000838 return nullptr;
Justin Bogneref512b92014-01-06 22:27:43 +0000839
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000840 // Calculate how to scale down to 32-bits.
841 uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
842
Justin Bogneref512b92014-01-06 22:27:43 +0000843 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000844 return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
845 scaleBranchWeight(FalseCount, Scale));
Justin Bogneref512b92014-01-06 22:27:43 +0000846}
847
Bob Wilson95a27b02014-02-17 19:20:59 +0000848llvm::MDNode *CodeGenPGO::createBranchWeights(ArrayRef<uint64_t> Weights) {
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000849 // We need at least two elements to create meaningful weights.
850 if (Weights.size() < 2)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000851 return nullptr;
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000852
Justin Bognerf3aefca2014-04-04 02:48:51 +0000853 // Check for empty weights.
854 uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
855 if (MaxWeight == 0)
856 return nullptr;
857
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000858 // Calculate how to scale down to 32-bits.
Justin Bognerf3aefca2014-04-04 02:48:51 +0000859 uint64_t Scale = calculateWeightScale(MaxWeight);
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000860
Justin Bogneref512b92014-01-06 22:27:43 +0000861 SmallVector<uint32_t, 16> ScaledWeights;
862 ScaledWeights.reserve(Weights.size());
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000863 for (uint64_t W : Weights)
864 ScaledWeights.push_back(scaleBranchWeight(W, Scale));
865
866 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
Justin Bogneref512b92014-01-06 22:27:43 +0000867 return MDHelper.createBranchWeights(ScaledWeights);
868}
Bob Wilsonbf854f02014-02-17 19:21:09 +0000869
870llvm::MDNode *CodeGenPGO::createLoopWeights(const Stmt *Cond,
Justin Bogner66242d62015-04-23 23:06:47 +0000871 uint64_t LoopCount) {
Bob Wilsonbf854f02014-02-17 19:21:09 +0000872 if (!haveRegionCounts())
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000873 return nullptr;
Justin Bogner1c21c282015-04-13 12:23:19 +0000874 Optional<uint64_t> CondCount = getStmtCount(Cond);
875 assert(CondCount.hasValue() && "missing expected loop condition count");
876 if (*CondCount == 0)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000877 return nullptr;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000878 return createBranchWeights(LoopCount,
Justin Bogner1c21c282015-04-13 12:23:19 +0000879 std::max(*CondCount, LoopCount) - LoopCount);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000880}