blob: 7fb64b85a05bc6df885a4ac4c68eff55df3f04e4 [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"
19#include "llvm/IR/MDBuilder.h"
Justin Bogner837a6f62014-04-18 21:52:00 +000020#include "llvm/ProfileData/InstrProfReader.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
25using namespace clang;
26using namespace CodeGen;
27
Alex Lorenzee024992014-08-04 18:41:51 +000028void CodeGenPGO::setFuncName(StringRef Name,
29 llvm::GlobalValue::LinkageTypes Linkage) {
30 RawFuncName = Name;
Bob Wilsonda1ebed2014-03-06 04:55:41 +000031
32 // Function names may be prefixed with a binary '1' to indicate
33 // that the backend should not modify the symbols due to any platform
34 // naming convention. Do not include that '1' in the PGO profile name.
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000035 if (RawFuncName[0] == '\1')
36 RawFuncName = RawFuncName.substr(1);
Bob Wilsonda1ebed2014-03-06 04:55:41 +000037
Alex Lorenzee024992014-08-04 18:41:51 +000038 if (!llvm::GlobalValue::isLocalLinkage(Linkage)) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +000039 PrefixedFuncName.reset(new std::string(RawFuncName));
Bob Wilsonda1ebed2014-03-06 04:55:41 +000040 return;
41 }
42
43 // For local symbols, prepend the main file name to distinguish them.
44 // Do not include the full path in the file name since there's no guarantee
45 // that it will stay the same, e.g., if the files are checked out from
46 // version control in different locations.
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +000047 PrefixedFuncName.reset(new std::string(CGM.getCodeGenOpts().MainFileName));
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000048 if (PrefixedFuncName->empty())
49 PrefixedFuncName->assign("<unknown>");
50 PrefixedFuncName->append(":");
51 PrefixedFuncName->append(RawFuncName);
Bob Wilsonda1ebed2014-03-06 04:55:41 +000052}
53
Alex Lorenzee024992014-08-04 18:41:51 +000054void CodeGenPGO::setFuncName(llvm::Function *Fn) {
55 setFuncName(Fn->getName(), Fn->getLinkage());
56}
57
58void CodeGenPGO::setVarLinkage(llvm::GlobalValue::LinkageTypes Linkage) {
59 // Set the linkage for variables based on the function linkage. Usually, we
60 // want to match it, but available_externally and extern_weak both have the
61 // wrong semantics.
62 VarLinkage = Linkage;
63 switch (VarLinkage) {
64 case llvm::GlobalValue::ExternalWeakLinkage:
65 VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;
66 break;
67 case llvm::GlobalValue::AvailableExternallyLinkage:
68 VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage;
69 break;
70 default:
71 break;
72 }
73}
74
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000075static llvm::Function *getRegisterFunc(CodeGenModule &CGM) {
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +000076 return CGM.getModule().getFunction("__llvm_profile_register_functions");
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000077}
78
79static llvm::BasicBlock *getOrInsertRegisterBB(CodeGenModule &CGM) {
Duncan P. N. Exon Smith780443e2014-03-20 03:57:11 +000080 // Don't do this for Darwin. compiler-rt uses linker magic.
81 if (CGM.getTarget().getTriple().isOSDarwin())
82 return nullptr;
83
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000084 // Only need to insert this once per module.
85 if (llvm::Function *RegisterF = getRegisterFunc(CGM))
86 return &RegisterF->getEntryBlock();
87
88 // Construct the function.
89 auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
90 auto *RegisterFTy = llvm::FunctionType::get(VoidTy, false);
91 auto *RegisterF = llvm::Function::Create(RegisterFTy,
92 llvm::GlobalValue::InternalLinkage,
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +000093 "__llvm_profile_register_functions",
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000094 &CGM.getModule());
95 RegisterF->setUnnamedAddr(true);
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000096 if (CGM.getCodeGenOpts().DisableRedZone)
97 RegisterF->addFnAttr(llvm::Attribute::NoRedZone);
98
99 // Construct and return the entry block.
100 auto *BB = llvm::BasicBlock::Create(CGM.getLLVMContext(), "", RegisterF);
101 CGBuilderTy Builder(BB);
102 Builder.CreateRetVoid();
103 return BB;
104}
105
106static llvm::Constant *getOrInsertRuntimeRegister(CodeGenModule &CGM) {
107 auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
108 auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
109 auto *RuntimeRegisterTy = llvm::FunctionType::get(VoidTy, VoidPtrTy, false);
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000110 return CGM.getModule().getOrInsertFunction("__llvm_profile_register_function",
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000111 RuntimeRegisterTy);
112}
113
Duncan P. N. Exon Smith7134d472014-03-20 03:17:15 +0000114static bool isMachO(const CodeGenModule &CGM) {
115 return CGM.getTarget().getTriple().isOSBinFormatMachO();
116}
117
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000118static StringRef getCountersSection(const CodeGenModule &CGM) {
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000119 return isMachO(CGM) ? "__DATA,__llvm_prf_cnts" : "__llvm_prf_cnts";
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000120}
121
122static StringRef getNameSection(const CodeGenModule &CGM) {
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000123 return isMachO(CGM) ? "__DATA,__llvm_prf_names" : "__llvm_prf_names";
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000124}
125
126static StringRef getDataSection(const CodeGenModule &CGM) {
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000127 return isMachO(CGM) ? "__DATA,__llvm_prf_data" : "__llvm_prf_data";
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000128}
129
130llvm::GlobalVariable *CodeGenPGO::buildDataVar() {
131 // Create name variable.
132 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
133 auto *VarName = llvm::ConstantDataArray::getString(Ctx, getFuncName(),
134 false);
135 auto *Name = new llvm::GlobalVariable(CGM.getModule(), VarName->getType(),
Duncan P. N. Exon Smith73f78622014-03-20 22:49:50 +0000136 true, VarLinkage, VarName,
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000137 getFuncVarName("name"));
138 Name->setSection(getNameSection(CGM));
139 Name->setAlignment(1);
140
141 // Create data variable.
142 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
Justin Bognerb4416f52014-03-18 21:58:06 +0000143 auto *Int64Ty = llvm::Type::getInt64Ty(Ctx);
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000144 auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
145 auto *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);
Alex Lorenzee024992014-08-04 18:41:51 +0000146 llvm::GlobalVariable *Data = nullptr;
147 if (RegionCounters) {
148 llvm::Type *DataTypes[] = {
149 Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy
150 };
151 auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes));
152 llvm::Constant *DataVals[] = {
153 llvm::ConstantInt::get(Int32Ty, getFuncName().size()),
154 llvm::ConstantInt::get(Int32Ty, NumRegionCounters),
155 llvm::ConstantInt::get(Int64Ty, FunctionHash),
156 llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),
157 llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)
158 };
159 Data =
160 new llvm::GlobalVariable(CGM.getModule(), DataTy, true, VarLinkage,
161 llvm::ConstantStruct::get(DataTy, DataVals),
162 getFuncVarName("data"));
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000163
Alex Lorenzee024992014-08-04 18:41:51 +0000164 // All the data should be packed into an array in its own section.
165 Data->setSection(getDataSection(CGM));
166 Data->setAlignment(8);
167 }
168
169 // Create coverage mapping data variable.
170 if (!CoverageMapping.empty())
171 CGM.getCoverageMapping()->addFunctionMappingRecord(Name,
Alex Lorenzf2cf38e2014-08-08 23:41:24 +0000172 getFuncName(),
Alex Lorenzee024992014-08-04 18:41:51 +0000173 CoverageMapping);
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000174
Duncan P. N. Exon Smith91212202014-05-16 01:24:00 +0000175 // Hide all these symbols so that we correctly get a copy for each
176 // executable. The profile format expects names and counters to be
177 // contiguous, so references into shared objects would be invalid.
178 if (!llvm::GlobalValue::isLocalLinkage(VarLinkage)) {
179 Name->setVisibility(llvm::GlobalValue::HiddenVisibility);
Alex Lorenzee024992014-08-04 18:41:51 +0000180 if (Data) {
181 Data->setVisibility(llvm::GlobalValue::HiddenVisibility);
182 RegionCounters->setVisibility(llvm::GlobalValue::HiddenVisibility);
183 }
Duncan P. N. Exon Smith91212202014-05-16 01:24:00 +0000184 }
185
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000186 // Make sure the data doesn't get deleted.
Alex Lorenzee024992014-08-04 18:41:51 +0000187 if (Data) CGM.addUsedGlobal(Data);
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000188 return Data;
189}
190
191void CodeGenPGO::emitInstrumentationData() {
Justin Bogner3212b182014-04-25 07:20:05 +0000192 if (!RegionCounters)
Justin Bogneref512b92014-01-06 22:27:43 +0000193 return;
194
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000195 // Build the data.
196 auto *Data = buildDataVar();
Justin Bogneref512b92014-01-06 22:27:43 +0000197
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000198 // Register the data.
Duncan P. N. Exon Smith780443e2014-03-20 03:57:11 +0000199 auto *RegisterBB = getOrInsertRegisterBB(CGM);
200 if (!RegisterBB)
201 return;
202 CGBuilderTy Builder(RegisterBB->getTerminator());
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000203 auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
204 Builder.CreateCall(getOrInsertRuntimeRegister(CGM),
205 Builder.CreateBitCast(Data, VoidPtrTy));
Justin Bogneref512b92014-01-06 22:27:43 +0000206}
207
208llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) {
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000209 if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000210 return nullptr;
Justin Bogneref512b92014-01-06 22:27:43 +0000211
Justin Bognerf2ea7752014-04-10 18:13:13 +0000212 assert(CGM.getModule().getFunction("__llvm_profile_init") == nullptr &&
213 "profile initialization already emitted");
Justin Bogneref512b92014-01-06 22:27:43 +0000214
Duncan P. N. Exon Smith5188e912014-03-20 19:23:46 +0000215 // Get the function to call at initialization.
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000216 llvm::Constant *RegisterF = getRegisterFunc(CGM);
Duncan P. N. Exon Smith5188e912014-03-20 19:23:46 +0000217 if (!RegisterF)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000218 return nullptr;
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000219
220 // Create the initialization function.
221 auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
222 auto *F = llvm::Function::Create(llvm::FunctionType::get(VoidTy, false),
223 llvm::GlobalValue::InternalLinkage,
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000224 "__llvm_profile_init", &CGM.getModule());
Justin Bogneref512b92014-01-06 22:27:43 +0000225 F->setUnnamedAddr(true);
Justin Bogneref512b92014-01-06 22:27:43 +0000226 F->addFnAttr(llvm::Attribute::NoInline);
227 if (CGM.getCodeGenOpts().DisableRedZone)
228 F->addFnAttr(llvm::Attribute::NoRedZone);
229
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000230 // Add the basic block and the necessary calls.
231 CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", F));
Duncan P. N. Exon Smith5188e912014-03-20 19:23:46 +0000232 Builder.CreateCall(RegisterF);
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000233 Builder.CreateRetVoid();
Justin Bogneref512b92014-01-06 22:27:43 +0000234
235 return F;
236}
237
238namespace {
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000239/// \brief Stable hasher for PGO region counters.
240///
241/// PGOHash produces a stable hash of a given function's control flow.
242///
243/// Changing the output of this hash will invalidate all previously generated
244/// profiles -- i.e., don't do it.
245///
246/// \note When this hash does eventually change (years?), we still need to
247/// support old hashes. We'll need to pull in the version number from the
248/// profile data format and use the matching hash function.
249class PGOHash {
250 uint64_t Working;
251 unsigned Count;
252 llvm::MD5 MD5;
253
254 static const int NumBitsPerType = 6;
255 static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
256 static const unsigned TooBig = 1u << NumBitsPerType;
257
258public:
259 /// \brief Hash values for AST nodes.
260 ///
261 /// Distinct values for AST nodes that have region counters attached.
262 ///
263 /// These values must be stable. All new members must be added at the end,
264 /// and no members should be removed. Changing the enumeration value for an
265 /// AST node will affect the hash of every function that contains that node.
266 enum HashType : unsigned char {
267 None = 0,
268 LabelStmt = 1,
269 WhileStmt,
270 DoStmt,
271 ForStmt,
272 CXXForRangeStmt,
273 ObjCForCollectionStmt,
274 SwitchStmt,
275 CaseStmt,
276 DefaultStmt,
277 IfStmt,
278 CXXTryStmt,
279 CXXCatchStmt,
280 ConditionalOperator,
281 BinaryOperatorLAnd,
282 BinaryOperatorLOr,
283 BinaryConditionalOperator,
284
285 // Keep this last. It's for the static assert that follows.
286 LastHashType
287 };
288 static_assert(LastHashType <= TooBig, "Too many types in HashType");
289
290 // TODO: When this format changes, take in a version number here, and use the
291 // old hash calculation for file formats that used the old hash.
292 PGOHash() : Working(0), Count(0) {}
293 void combine(HashType Type);
294 uint64_t finalize();
295};
296const int PGOHash::NumBitsPerType;
297const unsigned PGOHash::NumTypesPerWord;
298const unsigned PGOHash::TooBig;
299
Bob Wilsond8931422014-04-11 17:16:13 +0000300 /// A RecursiveASTVisitor that fills a map of statements to PGO counters.
301 struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
Justin Bogneref512b92014-01-06 22:27:43 +0000302 /// The next counter value to assign.
303 unsigned NextCounter;
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000304 /// The function hash.
305 PGOHash Hash;
Justin Bogneref512b92014-01-06 22:27:43 +0000306 /// The map of statements to counters.
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000307 llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
Justin Bogneref512b92014-01-06 22:27:43 +0000308
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000309 MapRegionCounters(llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
310 : NextCounter(0), CounterMap(CounterMap) {}
Justin Bogneref512b92014-01-06 22:27:43 +0000311
Justin Bogner191ec632014-04-11 23:06:35 +0000312 // Blocks and lambdas are handled as separate functions, so we need not
313 // traverse them in the parent context.
314 bool TraverseBlockExpr(BlockExpr *BE) { return true; }
315 bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
Justin Bogner81ab90f2014-04-15 00:50:54 +0000316 bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
Justin Bogneref512b92014-01-06 22:27:43 +0000317
Bob Wilsond8931422014-04-11 17:16:13 +0000318 bool VisitDecl(const Decl *D) {
319 switch (D->getKind()) {
320 default:
321 break;
322 case Decl::Function:
323 case Decl::CXXMethod:
324 case Decl::CXXConstructor:
325 case Decl::CXXDestructor:
326 case Decl::CXXConversion:
327 case Decl::ObjCMethod:
328 case Decl::Block:
Justin Bogner81ab90f2014-04-15 00:50:54 +0000329 case Decl::Captured:
Bob Wilsond8931422014-04-11 17:16:13 +0000330 CounterMap[D->getBody()] = NextCounter++;
331 break;
332 }
333 return true;
Justin Bogneref512b92014-01-06 22:27:43 +0000334 }
Bob Wilsond8931422014-04-11 17:16:13 +0000335
336 bool VisitStmt(const Stmt *S) {
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000337 auto Type = getHashType(S);
338 if (Type == PGOHash::None)
339 return true;
340
341 CounterMap[S] = NextCounter++;
342 Hash.combine(Type);
343 return true;
344 }
345 PGOHash::HashType getHashType(const Stmt *S) {
Bob Wilsond8931422014-04-11 17:16:13 +0000346 switch (S->getStmtClass()) {
347 default:
348 break;
349 case Stmt::LabelStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000350 return PGOHash::LabelStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000351 case Stmt::WhileStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000352 return PGOHash::WhileStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000353 case Stmt::DoStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000354 return PGOHash::DoStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000355 case Stmt::ForStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000356 return PGOHash::ForStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000357 case Stmt::CXXForRangeStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000358 return PGOHash::CXXForRangeStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000359 case Stmt::ObjCForCollectionStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000360 return PGOHash::ObjCForCollectionStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000361 case Stmt::SwitchStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000362 return PGOHash::SwitchStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000363 case Stmt::CaseStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000364 return PGOHash::CaseStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000365 case Stmt::DefaultStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000366 return PGOHash::DefaultStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000367 case Stmt::IfStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000368 return PGOHash::IfStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000369 case Stmt::CXXTryStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000370 return PGOHash::CXXTryStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000371 case Stmt::CXXCatchStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000372 return PGOHash::CXXCatchStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000373 case Stmt::ConditionalOperatorClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000374 return PGOHash::ConditionalOperator;
Bob Wilsond8931422014-04-11 17:16:13 +0000375 case Stmt::BinaryConditionalOperatorClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000376 return PGOHash::BinaryConditionalOperator;
Bob Wilsond8931422014-04-11 17:16:13 +0000377 case Stmt::BinaryOperatorClass: {
378 const BinaryOperator *BO = cast<BinaryOperator>(S);
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000379 if (BO->getOpcode() == BO_LAnd)
380 return PGOHash::BinaryOperatorLAnd;
381 if (BO->getOpcode() == BO_LOr)
382 return PGOHash::BinaryOperatorLOr;
Bob Wilsond8931422014-04-11 17:16:13 +0000383 break;
384 }
385 }
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000386 return PGOHash::None;
Justin Bogneref512b92014-01-06 22:27:43 +0000387 }
388 };
Bob Wilsonbf854f02014-02-17 19:21:09 +0000389
390 /// A StmtVisitor that propagates the raw counts through the AST and
391 /// records the count at statements where the value may change.
392 struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
393 /// PGO state.
394 CodeGenPGO &PGO;
395
396 /// A flag that is set when the current count should be recorded on the
397 /// next statement, such as at the exit of a loop.
398 bool RecordNextStmtCount;
399
400 /// The map of statements to count values.
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000401 llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000402
Justin Bognerfc83c112014-04-18 21:51:09 +0000403 /// BreakContinueStack - Keep counts of breaks and continues inside loops.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000404 struct BreakContinue {
405 uint64_t BreakCount;
406 uint64_t ContinueCount;
407 BreakContinue() : BreakCount(0), ContinueCount(0) {}
408 };
409 SmallVector<BreakContinue, 8> BreakContinueStack;
410
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000411 ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
412 CodeGenPGO &PGO)
413 : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
Bob Wilsonbf854f02014-02-17 19:21:09 +0000414
415 void RecordStmtCount(const Stmt *S) {
416 if (RecordNextStmtCount) {
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000417 CountMap[S] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000418 RecordNextStmtCount = false;
419 }
420 }
421
422 void VisitStmt(const Stmt *S) {
423 RecordStmtCount(S);
424 for (Stmt::const_child_range I = S->children(); I; ++I) {
425 if (*I)
426 this->Visit(*I);
427 }
428 }
429
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000430 void VisitFunctionDecl(const FunctionDecl *D) {
Bob Wilsond8931422014-04-11 17:16:13 +0000431 // Counter tracks entry to the function body.
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000432 RegionCounter Cnt(PGO, D->getBody());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000433 Cnt.beginRegion();
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000434 CountMap[D->getBody()] = PGO.getCurrentRegionCount();
435 Visit(D->getBody());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000436 }
437
Justin Bogner191ec632014-04-11 23:06:35 +0000438 // Skip lambda expressions. We visit these as FunctionDecls when we're
439 // generating them and aren't interested in the body when generating a
440 // parent context.
441 void VisitLambdaExpr(const LambdaExpr *LE) {}
442
Justin Bogner81ab90f2014-04-15 00:50:54 +0000443 void VisitCapturedDecl(const CapturedDecl *D) {
444 // Counter tracks entry to the capture body.
445 RegionCounter Cnt(PGO, D->getBody());
446 Cnt.beginRegion();
447 CountMap[D->getBody()] = PGO.getCurrentRegionCount();
448 Visit(D->getBody());
449 }
450
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000451 void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
Bob Wilsond8931422014-04-11 17:16:13 +0000452 // Counter tracks entry to the method body.
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000453 RegionCounter Cnt(PGO, D->getBody());
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000454 Cnt.beginRegion();
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000455 CountMap[D->getBody()] = PGO.getCurrentRegionCount();
456 Visit(D->getBody());
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000457 }
458
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000459 void VisitBlockDecl(const BlockDecl *D) {
Bob Wilsond8931422014-04-11 17:16:13 +0000460 // Counter tracks entry to the block body.
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000461 RegionCounter Cnt(PGO, D->getBody());
Bob Wilsonc845c002014-03-06 20:24:27 +0000462 Cnt.beginRegion();
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000463 CountMap[D->getBody()] = PGO.getCurrentRegionCount();
464 Visit(D->getBody());
Bob Wilsonc845c002014-03-06 20:24:27 +0000465 }
466
Bob Wilsonbf854f02014-02-17 19:21:09 +0000467 void VisitReturnStmt(const ReturnStmt *S) {
468 RecordStmtCount(S);
469 if (S->getRetValue())
470 Visit(S->getRetValue());
471 PGO.setCurrentRegionUnreachable();
472 RecordNextStmtCount = true;
473 }
474
475 void VisitGotoStmt(const GotoStmt *S) {
476 RecordStmtCount(S);
477 PGO.setCurrentRegionUnreachable();
478 RecordNextStmtCount = true;
479 }
480
481 void VisitLabelStmt(const LabelStmt *S) {
482 RecordNextStmtCount = false;
Bob Wilsond8931422014-04-11 17:16:13 +0000483 // Counter tracks the block following the label.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000484 RegionCounter Cnt(PGO, S);
485 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000486 CountMap[S] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000487 Visit(S->getSubStmt());
488 }
489
490 void VisitBreakStmt(const BreakStmt *S) {
491 RecordStmtCount(S);
492 assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
493 BreakContinueStack.back().BreakCount += PGO.getCurrentRegionCount();
494 PGO.setCurrentRegionUnreachable();
495 RecordNextStmtCount = true;
496 }
497
498 void VisitContinueStmt(const ContinueStmt *S) {
499 RecordStmtCount(S);
500 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
501 BreakContinueStack.back().ContinueCount += PGO.getCurrentRegionCount();
502 PGO.setCurrentRegionUnreachable();
503 RecordNextStmtCount = true;
504 }
505
506 void VisitWhileStmt(const WhileStmt *S) {
507 RecordStmtCount(S);
Bob Wilsond8931422014-04-11 17:16:13 +0000508 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000509 RegionCounter Cnt(PGO, S);
510 BreakContinueStack.push_back(BreakContinue());
511 // Visit the body region first so the break/continue adjustments can be
512 // included when visiting the condition.
513 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000514 CountMap[S->getBody()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000515 Visit(S->getBody());
516 Cnt.adjustForControlFlow();
517
518 // ...then go back and propagate counts through the condition. The count
519 // at the start of the condition is the sum of the incoming edges,
520 // the backedge from the end of the loop body, and the edges from
521 // continue statements.
522 BreakContinue BC = BreakContinueStack.pop_back_val();
523 Cnt.setCurrentRegionCount(Cnt.getParentCount() +
524 Cnt.getAdjustedCount() + BC.ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000525 CountMap[S->getCond()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000526 Visit(S->getCond());
527 Cnt.adjustForControlFlow();
528 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
529 RecordNextStmtCount = true;
530 }
531
532 void VisitDoStmt(const DoStmt *S) {
533 RecordStmtCount(S);
Bob Wilsond8931422014-04-11 17:16:13 +0000534 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000535 RegionCounter Cnt(PGO, S);
536 BreakContinueStack.push_back(BreakContinue());
537 Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000538 CountMap[S->getBody()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000539 Visit(S->getBody());
540 Cnt.adjustForControlFlow();
541
542 BreakContinue BC = BreakContinueStack.pop_back_val();
543 // The count at the start of the condition is equal to the count at the
544 // end of the body. The adjusted count does not include either the
545 // fall-through count coming into the loop or the continue count, so add
546 // both of those separately. This is coincidentally the same equation as
547 // with while loops but for different reasons.
548 Cnt.setCurrentRegionCount(Cnt.getParentCount() +
549 Cnt.getAdjustedCount() + BC.ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000550 CountMap[S->getCond()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000551 Visit(S->getCond());
552 Cnt.adjustForControlFlow();
553 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
554 RecordNextStmtCount = true;
555 }
556
557 void VisitForStmt(const ForStmt *S) {
558 RecordStmtCount(S);
559 if (S->getInit())
560 Visit(S->getInit());
Bob Wilsond8931422014-04-11 17:16:13 +0000561 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000562 RegionCounter Cnt(PGO, S);
563 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.)
566 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000567 CountMap[S->getBody()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000568 Visit(S->getBody());
569 Cnt.adjustForControlFlow();
570
571 // The increment is essentially part of the body but it needs to include
572 // the count for all the continue statements.
573 if (S->getInc()) {
574 Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
575 BreakContinueStack.back().ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000576 CountMap[S->getInc()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000577 Visit(S->getInc());
578 Cnt.adjustForControlFlow();
579 }
580
581 BreakContinue BC = BreakContinueStack.pop_back_val();
582
583 // ...then go back and propagate counts through the condition.
584 if (S->getCond()) {
585 Cnt.setCurrentRegionCount(Cnt.getParentCount() +
586 Cnt.getAdjustedCount() +
587 BC.ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000588 CountMap[S->getCond()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000589 Visit(S->getCond());
590 Cnt.adjustForControlFlow();
591 }
592 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
593 RecordNextStmtCount = true;
594 }
595
596 void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
597 RecordStmtCount(S);
598 Visit(S->getRangeStmt());
599 Visit(S->getBeginEndStmt());
Bob Wilsond8931422014-04-11 17:16:13 +0000600 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000601 RegionCounter Cnt(PGO, S);
602 BreakContinueStack.push_back(BreakContinue());
603 // Visit the body region first. (This is basically the same as a while
604 // loop; see further comments in VisitWhileStmt.)
605 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000606 CountMap[S->getLoopVarStmt()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000607 Visit(S->getLoopVarStmt());
608 Visit(S->getBody());
609 Cnt.adjustForControlFlow();
610
611 // The increment is essentially part of the body but it needs to include
612 // the count for all the continue statements.
613 Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
614 BreakContinueStack.back().ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000615 CountMap[S->getInc()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000616 Visit(S->getInc());
617 Cnt.adjustForControlFlow();
618
619 BreakContinue BC = BreakContinueStack.pop_back_val();
620
621 // ...then go back and propagate counts through the condition.
622 Cnt.setCurrentRegionCount(Cnt.getParentCount() +
623 Cnt.getAdjustedCount() +
624 BC.ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000625 CountMap[S->getCond()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000626 Visit(S->getCond());
627 Cnt.adjustForControlFlow();
628 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
629 RecordNextStmtCount = true;
630 }
631
632 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
633 RecordStmtCount(S);
634 Visit(S->getElement());
Bob Wilsond8931422014-04-11 17:16:13 +0000635 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000636 RegionCounter Cnt(PGO, S);
637 BreakContinueStack.push_back(BreakContinue());
638 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000639 CountMap[S->getBody()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000640 Visit(S->getBody());
641 BreakContinue BC = BreakContinueStack.pop_back_val();
642 Cnt.adjustForControlFlow();
643 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
644 RecordNextStmtCount = true;
645 }
646
647 void VisitSwitchStmt(const SwitchStmt *S) {
648 RecordStmtCount(S);
649 Visit(S->getCond());
650 PGO.setCurrentRegionUnreachable();
651 BreakContinueStack.push_back(BreakContinue());
652 Visit(S->getBody());
653 // If the switch is inside a loop, add the continue counts.
654 BreakContinue BC = BreakContinueStack.pop_back_val();
655 if (!BreakContinueStack.empty())
656 BreakContinueStack.back().ContinueCount += BC.ContinueCount;
Bob Wilsond8931422014-04-11 17:16:13 +0000657 // Counter tracks the exit block of the switch.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000658 RegionCounter ExitCnt(PGO, S);
659 ExitCnt.beginRegion();
660 RecordNextStmtCount = true;
661 }
662
663 void VisitCaseStmt(const CaseStmt *S) {
664 RecordNextStmtCount = false;
Bob Wilsond8931422014-04-11 17:16:13 +0000665 // Counter for this particular case. This counts only jumps from the
666 // switch header and does not include fallthrough from the case before
667 // this one.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000668 RegionCounter Cnt(PGO, S);
669 Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000670 CountMap[S] = Cnt.getCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000671 RecordNextStmtCount = true;
672 Visit(S->getSubStmt());
673 }
674
675 void VisitDefaultStmt(const DefaultStmt *S) {
676 RecordNextStmtCount = false;
Bob Wilsond8931422014-04-11 17:16:13 +0000677 // Counter for this default case. This does not include fallthrough from
678 // the previous case.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000679 RegionCounter Cnt(PGO, S);
680 Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000681 CountMap[S] = Cnt.getCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000682 RecordNextStmtCount = true;
683 Visit(S->getSubStmt());
684 }
685
686 void VisitIfStmt(const IfStmt *S) {
687 RecordStmtCount(S);
Bob Wilsond8931422014-04-11 17:16:13 +0000688 // Counter tracks the "then" part of an if statement. The count for
689 // the "else" part, if it exists, will be calculated from this counter.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000690 RegionCounter Cnt(PGO, S);
691 Visit(S->getCond());
692
693 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000694 CountMap[S->getThen()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000695 Visit(S->getThen());
696 Cnt.adjustForControlFlow();
697
698 if (S->getElse()) {
699 Cnt.beginElseRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000700 CountMap[S->getElse()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000701 Visit(S->getElse());
702 Cnt.adjustForControlFlow();
703 }
704 Cnt.applyAdjustmentsToRegion(0);
705 RecordNextStmtCount = true;
706 }
707
708 void VisitCXXTryStmt(const CXXTryStmt *S) {
709 RecordStmtCount(S);
710 Visit(S->getTryBlock());
711 for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
712 Visit(S->getHandler(I));
Bob Wilsond8931422014-04-11 17:16:13 +0000713 // Counter tracks the continuation block of the try statement.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000714 RegionCounter Cnt(PGO, S);
715 Cnt.beginRegion();
716 RecordNextStmtCount = true;
717 }
718
719 void VisitCXXCatchStmt(const CXXCatchStmt *S) {
720 RecordNextStmtCount = false;
Bob Wilsond8931422014-04-11 17:16:13 +0000721 // Counter tracks the catch statement's handler block.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000722 RegionCounter Cnt(PGO, S);
723 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000724 CountMap[S] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000725 Visit(S->getHandlerBlock());
726 }
727
Justin Bogner53c55d92014-04-11 06:10:10 +0000728 void VisitAbstractConditionalOperator(
729 const AbstractConditionalOperator *E) {
Bob Wilsonbf854f02014-02-17 19:21:09 +0000730 RecordStmtCount(E);
Bob Wilsond8931422014-04-11 17:16:13 +0000731 // Counter tracks the "true" part of a conditional operator. The
732 // count in the "false" part will be calculated from this counter.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000733 RegionCounter Cnt(PGO, E);
734 Visit(E->getCond());
735
736 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000737 CountMap[E->getTrueExpr()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000738 Visit(E->getTrueExpr());
739 Cnt.adjustForControlFlow();
740
741 Cnt.beginElseRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000742 CountMap[E->getFalseExpr()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000743 Visit(E->getFalseExpr());
744 Cnt.adjustForControlFlow();
745
746 Cnt.applyAdjustmentsToRegion(0);
747 RecordNextStmtCount = true;
748 }
749
750 void VisitBinLAnd(const BinaryOperator *E) {
751 RecordStmtCount(E);
Bob Wilsond8931422014-04-11 17:16:13 +0000752 // Counter tracks the right hand side of a logical and operator.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000753 RegionCounter Cnt(PGO, E);
754 Visit(E->getLHS());
755 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000756 CountMap[E->getRHS()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000757 Visit(E->getRHS());
758 Cnt.adjustForControlFlow();
759 Cnt.applyAdjustmentsToRegion(0);
760 RecordNextStmtCount = true;
761 }
762
763 void VisitBinLOr(const BinaryOperator *E) {
764 RecordStmtCount(E);
Bob Wilsond8931422014-04-11 17:16:13 +0000765 // Counter tracks the right hand side of a logical or operator.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000766 RegionCounter Cnt(PGO, E);
767 Visit(E->getLHS());
768 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000769 CountMap[E->getRHS()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000770 Visit(E->getRHS());
771 Cnt.adjustForControlFlow();
772 Cnt.applyAdjustmentsToRegion(0);
773 RecordNextStmtCount = true;
774 }
775 };
Justin Bogneref512b92014-01-06 22:27:43 +0000776}
777
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000778void PGOHash::combine(HashType Type) {
779 // Check that we never combine 0 and only have six bits.
780 assert(Type && "Hash is invalid: unexpected type 0");
781 assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
782
783 // Pass through MD5 if enough work has built up.
784 if (Count && Count % NumTypesPerWord == 0) {
785 using namespace llvm::support;
786 uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
787 MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
788 Working = 0;
789 }
790
791 // Accumulate the current type.
792 ++Count;
793 Working = Working << NumBitsPerType | Type;
794}
795
796uint64_t PGOHash::finalize() {
797 // Use Working as the hash directly if we never used MD5.
798 if (Count <= NumTypesPerWord)
799 // No need to byte swap here, since none of the math was endian-dependent.
800 // This number will be byte-swapped as required on endianness transitions,
801 // so we will see the same value on the other side.
802 return Working;
803
804 // Check for remaining work in Working.
805 if (Working)
806 MD5.update(Working);
807
808 // Finalize the MD5 and return the hash.
809 llvm::MD5::MD5Result Result;
810 MD5.final(Result);
811 using namespace llvm::support;
812 return endian::read<uint64_t, little, unaligned>(Result);
813}
814
Duncan P. N. Exon Smithd971cd12014-03-28 17:53:22 +0000815static void emitRuntimeHook(CodeGenModule &CGM) {
Duncan P. N. Exon Smith3fefedb2014-04-11 00:43:16 +0000816 const char *const RuntimeVarName = "__llvm_profile_runtime";
817 const char *const RuntimeUserName = "__llvm_profile_runtime_user";
Duncan P. N. Exon Smithd971cd12014-03-28 17:53:22 +0000818 if (CGM.getModule().getGlobalVariable(RuntimeVarName))
819 return;
820
821 // Declare the runtime hook.
822 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
823 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
824 auto *Var = new llvm::GlobalVariable(CGM.getModule(), Int32Ty, false,
825 llvm::GlobalValue::ExternalLinkage,
826 nullptr, RuntimeVarName);
827
828 // Make a function that uses it.
829 auto *User = llvm::Function::Create(llvm::FunctionType::get(Int32Ty, false),
830 llvm::GlobalValue::LinkOnceODRLinkage,
831 RuntimeUserName, &CGM.getModule());
832 User->addFnAttr(llvm::Attribute::NoInline);
833 if (CGM.getCodeGenOpts().DisableRedZone)
834 User->addFnAttr(llvm::Attribute::NoRedZone);
835 CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", User));
836 auto *Load = Builder.CreateLoad(Var);
837 Builder.CreateRet(Load);
838
839 // Create a use of the function. Now the definition of the runtime variable
840 // should get pulled in, along with any static initializears.
841 CGM.addUsedGlobal(User);
842}
843
Alex Lorenzee024992014-08-04 18:41:51 +0000844void CodeGenPGO::checkGlobalDecl(GlobalDecl GD) {
845 // Make sure we only emit coverage mapping for one constructor/destructor.
846 // Clang emits several functions for the constructor and the destructor of
847 // a class. Every function is instrumented, but we only want to provide
848 // coverage for one of them. Because of that we only emit the coverage mapping
849 // for the base constructor/destructor.
850 if ((isa<CXXConstructorDecl>(GD.getDecl()) &&
Alex Lorenzd4236742014-08-11 18:21:34 +0000851 GD.getCtorType() != Ctor_Base) ||
Alex Lorenzee024992014-08-04 18:41:51 +0000852 (isa<CXXDestructorDecl>(GD.getDecl()) &&
853 GD.getDtorType() != Dtor_Base)) {
854 SkipCoverageMapping = true;
855 }
856}
857
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000858void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
Justin Bogneref512b92014-01-06 22:27:43 +0000859 bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
Justin Bogner837a6f62014-04-18 21:52:00 +0000860 llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
861 if (!InstrumentRegions && !PGOReader)
Justin Bogneref512b92014-01-06 22:27:43 +0000862 return;
Justin Bogner3212b182014-04-25 07:20:05 +0000863 if (D->isImplicit())
Justin Bogneref512b92014-01-06 22:27:43 +0000864 return;
Alex Lorenzee024992014-08-04 18:41:51 +0000865 CGM.ClearUnusedCoverageMapping(D);
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000866 setFuncName(Fn);
Alex Lorenzee024992014-08-04 18:41:51 +0000867 setVarLinkage(Fn->getLinkage());
Duncan P. N. Exon Smith7c414512014-03-20 22:50:08 +0000868
Justin Bogneref512b92014-01-06 22:27:43 +0000869 mapRegionCounters(D);
Duncan P. N. Exon Smithd971cd12014-03-28 17:53:22 +0000870 if (InstrumentRegions) {
871 emitRuntimeHook(CGM);
Justin Bogneref512b92014-01-06 22:27:43 +0000872 emitCounterVariables();
Alex Lorenzee024992014-08-04 18:41:51 +0000873 if (CGM.getCodeGenOpts().CoverageMapping)
874 emitCounterRegionMapping(D);
Duncan P. N. Exon Smithd971cd12014-03-28 17:53:22 +0000875 }
Justin Bogner837a6f62014-04-18 21:52:00 +0000876 if (PGOReader) {
Justin Bogner40b8ba12014-06-26 01:45:07 +0000877 SourceManager &SM = CGM.getContext().getSourceManager();
878 loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
Bob Wilsonbf854f02014-02-17 19:21:09 +0000879 computeRegionCounts(D);
Justin Bogner837a6f62014-04-18 21:52:00 +0000880 applyFunctionAttributes(PGOReader, Fn);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000881 }
Justin Bogneref512b92014-01-06 22:27:43 +0000882}
883
884void CodeGenPGO::mapRegionCounters(const Decl *D) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000885 RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000886 MapRegionCounters Walker(*RegionCounterMap);
Justin Bogneref512b92014-01-06 22:27:43 +0000887 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000888 Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000889 else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000890 Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
Bob Wilsonc845c002014-03-06 20:24:27 +0000891 else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000892 Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
Justin Bogner81ab90f2014-04-15 00:50:54 +0000893 else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
894 Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
Justin Bogner3212b182014-04-25 07:20:05 +0000895 assert(Walker.NextCounter > 0 && "no entry counter mapped for decl");
Justin Bogneref512b92014-01-06 22:27:43 +0000896 NumRegionCounters = Walker.NextCounter;
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000897 FunctionHash = Walker.Hash.finalize();
Justin Bogneref512b92014-01-06 22:27:43 +0000898}
899
Alex Lorenzee024992014-08-04 18:41:51 +0000900void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
901 if (SkipCoverageMapping)
902 return;
903 // Don't map the functions inside the system headers
904 auto Loc = D->getBody()->getLocStart();
905 if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))
906 return;
907
908 llvm::raw_string_ostream OS(CoverageMapping);
909 CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
910 CGM.getContext().getSourceManager(),
911 CGM.getLangOpts(), RegionCounterMap.get(),
912 NumRegionCounters);
913 MappingGen.emitCounterMapping(D, OS);
914 OS.flush();
915}
916
917void
918CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef FuncName,
919 llvm::GlobalValue::LinkageTypes Linkage) {
920 if (SkipCoverageMapping)
921 return;
922 setFuncName(FuncName, Linkage);
923 setVarLinkage(Linkage);
924
925 // Don't map the functions inside the system headers
926 auto Loc = D->getBody()->getLocStart();
927 if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))
928 return;
929
930 llvm::raw_string_ostream OS(CoverageMapping);
931 CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
932 CGM.getContext().getSourceManager(),
933 CGM.getLangOpts());
934 MappingGen.emitEmptyMapping(D, OS);
935 OS.flush();
936 buildDataVar();
937}
938
Bob Wilsonbf854f02014-02-17 19:21:09 +0000939void CodeGenPGO::computeRegionCounts(const Decl *D) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000940 StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000941 ComputeRegionCounts Walker(*StmtCountMap, *this);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000942 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
943 Walker.VisitFunctionDecl(FD);
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000944 else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
945 Walker.VisitObjCMethodDecl(MD);
Bob Wilsonc845c002014-03-06 20:24:27 +0000946 else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
947 Walker.VisitBlockDecl(BD);
Justin Bogner81ab90f2014-04-15 00:50:54 +0000948 else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
949 Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
Bob Wilsonbf854f02014-02-17 19:21:09 +0000950}
951
Justin Bogner837a6f62014-04-18 21:52:00 +0000952void
953CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
954 llvm::Function *Fn) {
Justin Bogner4c9c45c2014-03-12 18:14:32 +0000955 if (!haveRegionCounts())
956 return;
957
Justin Bogner837a6f62014-04-18 21:52:00 +0000958 uint64_t MaxFunctionCount = PGOReader->getMaximumFunctionCount();
Justin Bogner4c9c45c2014-03-12 18:14:32 +0000959 uint64_t FunctionCount = getRegionCount(0);
960 if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount))
961 // Turn on InlineHint attribute for hot functions.
962 // FIXME: 30% is from preliminary tuning on SPEC, it may not be optimal.
963 Fn->addFnAttr(llvm::Attribute::InlineHint);
964 else if (FunctionCount <= (uint64_t)(0.01 * (double)MaxFunctionCount))
965 // Turn on Cold attribute for cold functions.
966 // FIXME: 1% is from preliminary tuning on SPEC, it may not be optimal.
967 Fn->addFnAttr(llvm::Attribute::Cold);
968}
969
Justin Bogneref512b92014-01-06 22:27:43 +0000970void CodeGenPGO::emitCounterVariables() {
971 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
972 llvm::ArrayType *CounterTy = llvm::ArrayType::get(llvm::Type::getInt64Ty(Ctx),
973 NumRegionCounters);
974 RegionCounters =
Duncan P. N. Exon Smith73f78622014-03-20 22:49:50 +0000975 new llvm::GlobalVariable(CGM.getModule(), CounterTy, false, VarLinkage,
Justin Bogneref512b92014-01-06 22:27:43 +0000976 llvm::Constant::getNullValue(CounterTy),
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000977 getFuncVarName("counters"));
978 RegionCounters->setAlignment(8);
979 RegionCounters->setSection(getCountersSection(CGM));
Justin Bogneref512b92014-01-06 22:27:43 +0000980}
981
982void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) {
Bob Wilson749ebc72014-03-06 04:55:28 +0000983 if (!RegionCounters)
Justin Bogneref512b92014-01-06 22:27:43 +0000984 return;
985 llvm::Value *Addr =
986 Builder.CreateConstInBoundsGEP2_64(RegionCounters, 0, Counter);
987 llvm::Value *Count = Builder.CreateLoad(Addr, "pgocount");
988 Count = Builder.CreateAdd(Count, Builder.getInt64(1));
989 Builder.CreateStore(Count, Addr);
990}
991
Justin Bogner40b8ba12014-06-26 01:45:07 +0000992void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
993 bool IsInMainFile) {
994 CGM.getPGOStats().addVisited(IsInMainFile);
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000995 RegionCounts.reset(new std::vector<uint64_t>);
Justin Bogner9c6818e2014-08-01 22:50:16 +0000996 if (std::error_code EC = PGOReader->getFunctionCounts(
997 getFuncName(), FunctionHash, *RegionCounts)) {
998 if (EC == llvm::instrprof_error::unknown_function)
999 CGM.getPGOStats().addMissing(IsInMainFile);
1000 else if (EC == llvm::instrprof_error::hash_mismatch)
1001 CGM.getPGOStats().addMismatched(IsInMainFile);
1002 else if (EC == llvm::instrprof_error::malformed)
1003 // TODO: Consider a more specific warning for this case.
1004 CGM.getPGOStats().addMismatched(IsInMainFile);
Justin Bognere2ef2a02014-04-15 21:22:35 +00001005 RegionCounts.reset();
1006 }
Justin Bogneref512b92014-01-06 22:27:43 +00001007}
1008
1009void CodeGenPGO::destroyRegionCounters() {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +00001010 RegionCounterMap.reset();
1011 StmtCountMap.reset();
1012 RegionCounts.reset();
Justin Bogner3212b182014-04-25 07:20:05 +00001013 RegionCounters = nullptr;
Justin Bogneref512b92014-01-06 22:27:43 +00001014}
1015
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001016/// \brief Calculate what to divide by to scale weights.
1017///
1018/// Given the maximum weight, calculate a divisor that will scale all the
1019/// weights to strictly less than UINT32_MAX.
1020static uint64_t calculateWeightScale(uint64_t MaxWeight) {
1021 return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
1022}
1023
1024/// \brief Scale an individual branch weight (and add 1).
1025///
1026/// Scale a 64-bit weight down to 32-bits using \c Scale.
1027///
1028/// According to Laplace's Rule of Succession, it is better to compute the
1029/// weight based on the count plus 1, so universally add 1 to the value.
1030///
1031/// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
1032/// greater than \c Weight.
1033static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
1034 assert(Scale && "scale by 0?");
1035 uint64_t Scaled = Weight / Scale + 1;
1036 assert(Scaled <= UINT32_MAX && "overflow 32-bits");
1037 return Scaled;
1038}
1039
Justin Bogneref512b92014-01-06 22:27:43 +00001040llvm::MDNode *CodeGenPGO::createBranchWeights(uint64_t TrueCount,
1041 uint64_t FalseCount) {
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001042 // Check for empty weights.
Justin Bogneref512b92014-01-06 22:27:43 +00001043 if (!TrueCount && !FalseCount)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +00001044 return nullptr;
Justin Bogneref512b92014-01-06 22:27:43 +00001045
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001046 // Calculate how to scale down to 32-bits.
1047 uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
1048
Justin Bogneref512b92014-01-06 22:27:43 +00001049 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001050 return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
1051 scaleBranchWeight(FalseCount, Scale));
Justin Bogneref512b92014-01-06 22:27:43 +00001052}
1053
Bob Wilson95a27b02014-02-17 19:20:59 +00001054llvm::MDNode *CodeGenPGO::createBranchWeights(ArrayRef<uint64_t> Weights) {
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001055 // We need at least two elements to create meaningful weights.
1056 if (Weights.size() < 2)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +00001057 return nullptr;
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001058
Justin Bognerf3aefca2014-04-04 02:48:51 +00001059 // Check for empty weights.
1060 uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
1061 if (MaxWeight == 0)
1062 return nullptr;
1063
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001064 // Calculate how to scale down to 32-bits.
Justin Bognerf3aefca2014-04-04 02:48:51 +00001065 uint64_t Scale = calculateWeightScale(MaxWeight);
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001066
Justin Bogneref512b92014-01-06 22:27:43 +00001067 SmallVector<uint32_t, 16> ScaledWeights;
1068 ScaledWeights.reserve(Weights.size());
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001069 for (uint64_t W : Weights)
1070 ScaledWeights.push_back(scaleBranchWeight(W, Scale));
1071
1072 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
Justin Bogneref512b92014-01-06 22:27:43 +00001073 return MDHelper.createBranchWeights(ScaledWeights);
1074}
Bob Wilsonbf854f02014-02-17 19:21:09 +00001075
1076llvm::MDNode *CodeGenPGO::createLoopWeights(const Stmt *Cond,
1077 RegionCounter &Cnt) {
1078 if (!haveRegionCounts())
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +00001079 return nullptr;
Bob Wilsonbf854f02014-02-17 19:21:09 +00001080 uint64_t LoopCount = Cnt.getCount();
1081 uint64_t CondCount = 0;
1082 bool Found = getStmtCount(Cond, CondCount);
1083 assert(Found && "missing expected loop condition count");
1084 (void)Found;
1085 if (CondCount == 0)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +00001086 return nullptr;
Bob Wilsonbf854f02014-02-17 19:21:09 +00001087 return createBranchWeights(LoopCount,
1088 std::max(CondCount, LoopCount) - LoopCount);
1089}