blob: aaeafd1a64dfca049a4293bf4d6ad9a78847aa80 [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"
16#include "clang/AST/RecursiveASTVisitor.h"
17#include "clang/AST/StmtVisitor.h"
Duncan P. N. Exon Smithe9624292014-04-10 23:37:34 +000018#include "llvm/Config/config.h" // for strtoull()/strtoul() define
Justin Bogneref512b92014-01-06 22:27:43 +000019#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
Bob Wilsonda1ebed2014-03-06 04:55:41 +000028void CodeGenPGO::setFuncName(llvm::Function *Fn) {
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000029 RawFuncName = Fn->getName();
Bob Wilsonda1ebed2014-03-06 04:55:41 +000030
31 // Function names may be prefixed with a binary '1' to indicate
32 // that the backend should not modify the symbols due to any platform
33 // naming convention. Do not include that '1' in the PGO profile name.
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000034 if (RawFuncName[0] == '\1')
35 RawFuncName = RawFuncName.substr(1);
Bob Wilsonda1ebed2014-03-06 04:55:41 +000036
37 if (!Fn->hasLocalLinkage()) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +000038 PrefixedFuncName.reset(new std::string(RawFuncName));
Bob Wilsonda1ebed2014-03-06 04:55:41 +000039 return;
40 }
41
42 // For local symbols, prepend the main file name to distinguish them.
43 // Do not include the full path in the file name since there's no guarantee
44 // that it will stay the same, e.g., if the files are checked out from
45 // version control in different locations.
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +000046 PrefixedFuncName.reset(new std::string(CGM.getCodeGenOpts().MainFileName));
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000047 if (PrefixedFuncName->empty())
48 PrefixedFuncName->assign("<unknown>");
49 PrefixedFuncName->append(":");
50 PrefixedFuncName->append(RawFuncName);
Bob Wilsonda1ebed2014-03-06 04:55:41 +000051}
52
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000053static llvm::Function *getRegisterFunc(CodeGenModule &CGM) {
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +000054 return CGM.getModule().getFunction("__llvm_profile_register_functions");
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000055}
56
57static llvm::BasicBlock *getOrInsertRegisterBB(CodeGenModule &CGM) {
Duncan P. N. Exon Smith780443e2014-03-20 03:57:11 +000058 // Don't do this for Darwin. compiler-rt uses linker magic.
59 if (CGM.getTarget().getTriple().isOSDarwin())
60 return nullptr;
61
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000062 // Only need to insert this once per module.
63 if (llvm::Function *RegisterF = getRegisterFunc(CGM))
64 return &RegisterF->getEntryBlock();
65
66 // Construct the function.
67 auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
68 auto *RegisterFTy = llvm::FunctionType::get(VoidTy, false);
69 auto *RegisterF = llvm::Function::Create(RegisterFTy,
70 llvm::GlobalValue::InternalLinkage,
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +000071 "__llvm_profile_register_functions",
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000072 &CGM.getModule());
73 RegisterF->setUnnamedAddr(true);
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000074 if (CGM.getCodeGenOpts().DisableRedZone)
75 RegisterF->addFnAttr(llvm::Attribute::NoRedZone);
76
77 // Construct and return the entry block.
78 auto *BB = llvm::BasicBlock::Create(CGM.getLLVMContext(), "", RegisterF);
79 CGBuilderTy Builder(BB);
80 Builder.CreateRetVoid();
81 return BB;
82}
83
84static llvm::Constant *getOrInsertRuntimeRegister(CodeGenModule &CGM) {
85 auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
86 auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
87 auto *RuntimeRegisterTy = llvm::FunctionType::get(VoidTy, VoidPtrTy, false);
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +000088 return CGM.getModule().getOrInsertFunction("__llvm_profile_register_function",
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000089 RuntimeRegisterTy);
90}
91
Duncan P. N. Exon Smith7134d472014-03-20 03:17:15 +000092static bool isMachO(const CodeGenModule &CGM) {
93 return CGM.getTarget().getTriple().isOSBinFormatMachO();
94}
95
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000096static StringRef getCountersSection(const CodeGenModule &CGM) {
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +000097 return isMachO(CGM) ? "__DATA,__llvm_prf_cnts" : "__llvm_prf_cnts";
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000098}
99
100static StringRef getNameSection(const CodeGenModule &CGM) {
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000101 return isMachO(CGM) ? "__DATA,__llvm_prf_names" : "__llvm_prf_names";
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000102}
103
104static StringRef getDataSection(const CodeGenModule &CGM) {
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000105 return isMachO(CGM) ? "__DATA,__llvm_prf_data" : "__llvm_prf_data";
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000106}
107
108llvm::GlobalVariable *CodeGenPGO::buildDataVar() {
109 // Create name variable.
110 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
111 auto *VarName = llvm::ConstantDataArray::getString(Ctx, getFuncName(),
112 false);
113 auto *Name = new llvm::GlobalVariable(CGM.getModule(), VarName->getType(),
Duncan P. N. Exon Smith73f78622014-03-20 22:49:50 +0000114 true, VarLinkage, VarName,
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000115 getFuncVarName("name"));
116 Name->setSection(getNameSection(CGM));
117 Name->setAlignment(1);
118
119 // Create data variable.
120 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
Justin Bognerb4416f52014-03-18 21:58:06 +0000121 auto *Int64Ty = llvm::Type::getInt64Ty(Ctx);
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000122 auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
123 auto *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);
124 llvm::Type *DataTypes[] = {
Justin Bognerb4416f52014-03-18 21:58:06 +0000125 Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000126 };
127 auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes));
128 llvm::Constant *DataVals[] = {
129 llvm::ConstantInt::get(Int32Ty, getFuncName().size()),
130 llvm::ConstantInt::get(Int32Ty, NumRegionCounters),
Justin Bognerb4416f52014-03-18 21:58:06 +0000131 llvm::ConstantInt::get(Int64Ty, FunctionHash),
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000132 llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),
133 llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)
134 };
135 auto *Data =
Duncan P. N. Exon Smith73f78622014-03-20 22:49:50 +0000136 new llvm::GlobalVariable(CGM.getModule(), DataTy, true, VarLinkage,
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000137 llvm::ConstantStruct::get(DataTy, DataVals),
138 getFuncVarName("data"));
139
140 // All the data should be packed into an array in its own section.
141 Data->setSection(getDataSection(CGM));
142 Data->setAlignment(8);
143
144 // Make sure the data doesn't get deleted.
145 CGM.addUsedGlobal(Data);
146 return Data;
147}
148
149void CodeGenPGO::emitInstrumentationData() {
Justin Bogneref512b92014-01-06 22:27:43 +0000150 if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
151 return;
152
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000153 // Build the data.
154 auto *Data = buildDataVar();
Justin Bogneref512b92014-01-06 22:27:43 +0000155
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000156 // Register the data.
Duncan P. N. Exon Smith780443e2014-03-20 03:57:11 +0000157 auto *RegisterBB = getOrInsertRegisterBB(CGM);
158 if (!RegisterBB)
159 return;
160 CGBuilderTy Builder(RegisterBB->getTerminator());
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000161 auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
162 Builder.CreateCall(getOrInsertRuntimeRegister(CGM),
163 Builder.CreateBitCast(Data, VoidPtrTy));
Justin Bogneref512b92014-01-06 22:27:43 +0000164}
165
166llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) {
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000167 if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000168 return nullptr;
Justin Bogneref512b92014-01-06 22:27:43 +0000169
Justin Bognerf2ea7752014-04-10 18:13:13 +0000170 assert(CGM.getModule().getFunction("__llvm_profile_init") == nullptr &&
171 "profile initialization already emitted");
Justin Bogneref512b92014-01-06 22:27:43 +0000172
Duncan P. N. Exon Smith5188e912014-03-20 19:23:46 +0000173 // Get the function to call at initialization.
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000174 llvm::Constant *RegisterF = getRegisterFunc(CGM);
Duncan P. N. Exon Smith5188e912014-03-20 19:23:46 +0000175 if (!RegisterF)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000176 return nullptr;
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000177
178 // Create the initialization function.
179 auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
180 auto *F = llvm::Function::Create(llvm::FunctionType::get(VoidTy, false),
181 llvm::GlobalValue::InternalLinkage,
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000182 "__llvm_profile_init", &CGM.getModule());
Justin Bogneref512b92014-01-06 22:27:43 +0000183 F->setUnnamedAddr(true);
Justin Bogneref512b92014-01-06 22:27:43 +0000184 F->addFnAttr(llvm::Attribute::NoInline);
185 if (CGM.getCodeGenOpts().DisableRedZone)
186 F->addFnAttr(llvm::Attribute::NoRedZone);
187
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000188 // Add the basic block and the necessary calls.
189 CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", F));
Duncan P. N. Exon Smith5188e912014-03-20 19:23:46 +0000190 Builder.CreateCall(RegisterF);
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000191 Builder.CreateRetVoid();
Justin Bogneref512b92014-01-06 22:27:43 +0000192
193 return F;
194}
195
196namespace {
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000197/// \brief Stable hasher for PGO region counters.
198///
199/// PGOHash produces a stable hash of a given function's control flow.
200///
201/// Changing the output of this hash will invalidate all previously generated
202/// profiles -- i.e., don't do it.
203///
204/// \note When this hash does eventually change (years?), we still need to
205/// support old hashes. We'll need to pull in the version number from the
206/// profile data format and use the matching hash function.
207class PGOHash {
208 uint64_t Working;
209 unsigned Count;
210 llvm::MD5 MD5;
211
212 static const int NumBitsPerType = 6;
213 static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
214 static const unsigned TooBig = 1u << NumBitsPerType;
215
216public:
217 /// \brief Hash values for AST nodes.
218 ///
219 /// Distinct values for AST nodes that have region counters attached.
220 ///
221 /// These values must be stable. All new members must be added at the end,
222 /// and no members should be removed. Changing the enumeration value for an
223 /// AST node will affect the hash of every function that contains that node.
224 enum HashType : unsigned char {
225 None = 0,
226 LabelStmt = 1,
227 WhileStmt,
228 DoStmt,
229 ForStmt,
230 CXXForRangeStmt,
231 ObjCForCollectionStmt,
232 SwitchStmt,
233 CaseStmt,
234 DefaultStmt,
235 IfStmt,
236 CXXTryStmt,
237 CXXCatchStmt,
238 ConditionalOperator,
239 BinaryOperatorLAnd,
240 BinaryOperatorLOr,
241 BinaryConditionalOperator,
242
243 // Keep this last. It's for the static assert that follows.
244 LastHashType
245 };
246 static_assert(LastHashType <= TooBig, "Too many types in HashType");
247
248 // TODO: When this format changes, take in a version number here, and use the
249 // old hash calculation for file formats that used the old hash.
250 PGOHash() : Working(0), Count(0) {}
251 void combine(HashType Type);
252 uint64_t finalize();
253};
254const int PGOHash::NumBitsPerType;
255const unsigned PGOHash::NumTypesPerWord;
256const unsigned PGOHash::TooBig;
257
Bob Wilsond8931422014-04-11 17:16:13 +0000258 /// A RecursiveASTVisitor that fills a map of statements to PGO counters.
259 struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
Justin Bogneref512b92014-01-06 22:27:43 +0000260 /// The next counter value to assign.
261 unsigned NextCounter;
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000262 /// The function hash.
263 PGOHash Hash;
Justin Bogneref512b92014-01-06 22:27:43 +0000264 /// The map of statements to counters.
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000265 llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
Justin Bogneref512b92014-01-06 22:27:43 +0000266
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000267 MapRegionCounters(llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
268 : NextCounter(0), CounterMap(CounterMap) {}
Justin Bogneref512b92014-01-06 22:27:43 +0000269
Justin Bogner191ec632014-04-11 23:06:35 +0000270 // Blocks and lambdas are handled as separate functions, so we need not
271 // traverse them in the parent context.
272 bool TraverseBlockExpr(BlockExpr *BE) { return true; }
273 bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
Justin Bogner81ab90f2014-04-15 00:50:54 +0000274 bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
Justin Bogneref512b92014-01-06 22:27:43 +0000275
Bob Wilsond8931422014-04-11 17:16:13 +0000276 bool VisitDecl(const Decl *D) {
277 switch (D->getKind()) {
278 default:
279 break;
280 case Decl::Function:
281 case Decl::CXXMethod:
282 case Decl::CXXConstructor:
283 case Decl::CXXDestructor:
284 case Decl::CXXConversion:
285 case Decl::ObjCMethod:
286 case Decl::Block:
Justin Bogner81ab90f2014-04-15 00:50:54 +0000287 case Decl::Captured:
Bob Wilsond8931422014-04-11 17:16:13 +0000288 CounterMap[D->getBody()] = NextCounter++;
289 break;
290 }
291 return true;
Justin Bogneref512b92014-01-06 22:27:43 +0000292 }
Bob Wilsond8931422014-04-11 17:16:13 +0000293
294 bool VisitStmt(const Stmt *S) {
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000295 auto Type = getHashType(S);
296 if (Type == PGOHash::None)
297 return true;
298
299 CounterMap[S] = NextCounter++;
300 Hash.combine(Type);
301 return true;
302 }
303 PGOHash::HashType getHashType(const Stmt *S) {
Bob Wilsond8931422014-04-11 17:16:13 +0000304 switch (S->getStmtClass()) {
305 default:
306 break;
307 case Stmt::LabelStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000308 return PGOHash::LabelStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000309 case Stmt::WhileStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000310 return PGOHash::WhileStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000311 case Stmt::DoStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000312 return PGOHash::DoStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000313 case Stmt::ForStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000314 return PGOHash::ForStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000315 case Stmt::CXXForRangeStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000316 return PGOHash::CXXForRangeStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000317 case Stmt::ObjCForCollectionStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000318 return PGOHash::ObjCForCollectionStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000319 case Stmt::SwitchStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000320 return PGOHash::SwitchStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000321 case Stmt::CaseStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000322 return PGOHash::CaseStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000323 case Stmt::DefaultStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000324 return PGOHash::DefaultStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000325 case Stmt::IfStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000326 return PGOHash::IfStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000327 case Stmt::CXXTryStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000328 return PGOHash::CXXTryStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000329 case Stmt::CXXCatchStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000330 return PGOHash::CXXCatchStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000331 case Stmt::ConditionalOperatorClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000332 return PGOHash::ConditionalOperator;
Bob Wilsond8931422014-04-11 17:16:13 +0000333 case Stmt::BinaryConditionalOperatorClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000334 return PGOHash::BinaryConditionalOperator;
Bob Wilsond8931422014-04-11 17:16:13 +0000335 case Stmt::BinaryOperatorClass: {
336 const BinaryOperator *BO = cast<BinaryOperator>(S);
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000337 if (BO->getOpcode() == BO_LAnd)
338 return PGOHash::BinaryOperatorLAnd;
339 if (BO->getOpcode() == BO_LOr)
340 return PGOHash::BinaryOperatorLOr;
Bob Wilsond8931422014-04-11 17:16:13 +0000341 break;
342 }
343 }
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000344 return PGOHash::None;
Justin Bogneref512b92014-01-06 22:27:43 +0000345 }
346 };
Bob Wilsonbf854f02014-02-17 19:21:09 +0000347
348 /// A StmtVisitor that propagates the raw counts through the AST and
349 /// records the count at statements where the value may change.
350 struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
351 /// PGO state.
352 CodeGenPGO &PGO;
353
354 /// A flag that is set when the current count should be recorded on the
355 /// next statement, such as at the exit of a loop.
356 bool RecordNextStmtCount;
357
358 /// The map of statements to count values.
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000359 llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000360
Justin Bognerfc83c112014-04-18 21:51:09 +0000361 /// BreakContinueStack - Keep counts of breaks and continues inside loops.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000362 struct BreakContinue {
363 uint64_t BreakCount;
364 uint64_t ContinueCount;
365 BreakContinue() : BreakCount(0), ContinueCount(0) {}
366 };
367 SmallVector<BreakContinue, 8> BreakContinueStack;
368
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000369 ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
370 CodeGenPGO &PGO)
371 : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
Bob Wilsonbf854f02014-02-17 19:21:09 +0000372
373 void RecordStmtCount(const Stmt *S) {
374 if (RecordNextStmtCount) {
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000375 CountMap[S] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000376 RecordNextStmtCount = false;
377 }
378 }
379
380 void VisitStmt(const Stmt *S) {
381 RecordStmtCount(S);
382 for (Stmt::const_child_range I = S->children(); I; ++I) {
383 if (*I)
384 this->Visit(*I);
385 }
386 }
387
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000388 void VisitFunctionDecl(const FunctionDecl *D) {
Bob Wilsond8931422014-04-11 17:16:13 +0000389 // Counter tracks entry to the function body.
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000390 RegionCounter Cnt(PGO, D->getBody());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000391 Cnt.beginRegion();
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000392 CountMap[D->getBody()] = PGO.getCurrentRegionCount();
393 Visit(D->getBody());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000394 }
395
Justin Bogner191ec632014-04-11 23:06:35 +0000396 // Skip lambda expressions. We visit these as FunctionDecls when we're
397 // generating them and aren't interested in the body when generating a
398 // parent context.
399 void VisitLambdaExpr(const LambdaExpr *LE) {}
400
Justin Bogner81ab90f2014-04-15 00:50:54 +0000401 void VisitCapturedDecl(const CapturedDecl *D) {
402 // Counter tracks entry to the capture body.
403 RegionCounter Cnt(PGO, D->getBody());
404 Cnt.beginRegion();
405 CountMap[D->getBody()] = PGO.getCurrentRegionCount();
406 Visit(D->getBody());
407 }
408
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000409 void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
Bob Wilsond8931422014-04-11 17:16:13 +0000410 // Counter tracks entry to the method body.
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000411 RegionCounter Cnt(PGO, D->getBody());
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000412 Cnt.beginRegion();
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000413 CountMap[D->getBody()] = PGO.getCurrentRegionCount();
414 Visit(D->getBody());
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000415 }
416
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000417 void VisitBlockDecl(const BlockDecl *D) {
Bob Wilsond8931422014-04-11 17:16:13 +0000418 // Counter tracks entry to the block body.
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000419 RegionCounter Cnt(PGO, D->getBody());
Bob Wilsonc845c002014-03-06 20:24:27 +0000420 Cnt.beginRegion();
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000421 CountMap[D->getBody()] = PGO.getCurrentRegionCount();
422 Visit(D->getBody());
Bob Wilsonc845c002014-03-06 20:24:27 +0000423 }
424
Bob Wilsonbf854f02014-02-17 19:21:09 +0000425 void VisitReturnStmt(const ReturnStmt *S) {
426 RecordStmtCount(S);
427 if (S->getRetValue())
428 Visit(S->getRetValue());
429 PGO.setCurrentRegionUnreachable();
430 RecordNextStmtCount = true;
431 }
432
433 void VisitGotoStmt(const GotoStmt *S) {
434 RecordStmtCount(S);
435 PGO.setCurrentRegionUnreachable();
436 RecordNextStmtCount = true;
437 }
438
439 void VisitLabelStmt(const LabelStmt *S) {
440 RecordNextStmtCount = false;
Bob Wilsond8931422014-04-11 17:16:13 +0000441 // Counter tracks the block following the label.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000442 RegionCounter Cnt(PGO, S);
443 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000444 CountMap[S] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000445 Visit(S->getSubStmt());
446 }
447
448 void VisitBreakStmt(const BreakStmt *S) {
449 RecordStmtCount(S);
450 assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
451 BreakContinueStack.back().BreakCount += PGO.getCurrentRegionCount();
452 PGO.setCurrentRegionUnreachable();
453 RecordNextStmtCount = true;
454 }
455
456 void VisitContinueStmt(const ContinueStmt *S) {
457 RecordStmtCount(S);
458 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
459 BreakContinueStack.back().ContinueCount += PGO.getCurrentRegionCount();
460 PGO.setCurrentRegionUnreachable();
461 RecordNextStmtCount = true;
462 }
463
464 void VisitWhileStmt(const WhileStmt *S) {
465 RecordStmtCount(S);
Bob Wilsond8931422014-04-11 17:16:13 +0000466 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000467 RegionCounter Cnt(PGO, S);
468 BreakContinueStack.push_back(BreakContinue());
469 // Visit the body region first so the break/continue adjustments can be
470 // included when visiting the condition.
471 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000472 CountMap[S->getBody()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000473 Visit(S->getBody());
474 Cnt.adjustForControlFlow();
475
476 // ...then go back and propagate counts through the condition. The count
477 // at the start of the condition is the sum of the incoming edges,
478 // the backedge from the end of the loop body, and the edges from
479 // continue statements.
480 BreakContinue BC = BreakContinueStack.pop_back_val();
481 Cnt.setCurrentRegionCount(Cnt.getParentCount() +
482 Cnt.getAdjustedCount() + BC.ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000483 CountMap[S->getCond()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000484 Visit(S->getCond());
485 Cnt.adjustForControlFlow();
486 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
487 RecordNextStmtCount = true;
488 }
489
490 void VisitDoStmt(const DoStmt *S) {
491 RecordStmtCount(S);
Bob Wilsond8931422014-04-11 17:16:13 +0000492 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000493 RegionCounter Cnt(PGO, S);
494 BreakContinueStack.push_back(BreakContinue());
495 Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000496 CountMap[S->getBody()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000497 Visit(S->getBody());
498 Cnt.adjustForControlFlow();
499
500 BreakContinue BC = BreakContinueStack.pop_back_val();
501 // The count at the start of the condition is equal to the count at the
502 // end of the body. The adjusted count does not include either the
503 // fall-through count coming into the loop or the continue count, so add
504 // both of those separately. This is coincidentally the same equation as
505 // with while loops but for different reasons.
506 Cnt.setCurrentRegionCount(Cnt.getParentCount() +
507 Cnt.getAdjustedCount() + BC.ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000508 CountMap[S->getCond()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000509 Visit(S->getCond());
510 Cnt.adjustForControlFlow();
511 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
512 RecordNextStmtCount = true;
513 }
514
515 void VisitForStmt(const ForStmt *S) {
516 RecordStmtCount(S);
517 if (S->getInit())
518 Visit(S->getInit());
Bob Wilsond8931422014-04-11 17:16:13 +0000519 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000520 RegionCounter Cnt(PGO, S);
521 BreakContinueStack.push_back(BreakContinue());
522 // Visit the body region first. (This is basically the same as a while
523 // loop; see further comments in VisitWhileStmt.)
524 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000525 CountMap[S->getBody()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000526 Visit(S->getBody());
527 Cnt.adjustForControlFlow();
528
529 // The increment is essentially part of the body but it needs to include
530 // the count for all the continue statements.
531 if (S->getInc()) {
532 Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
533 BreakContinueStack.back().ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000534 CountMap[S->getInc()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000535 Visit(S->getInc());
536 Cnt.adjustForControlFlow();
537 }
538
539 BreakContinue BC = BreakContinueStack.pop_back_val();
540
541 // ...then go back and propagate counts through the condition.
542 if (S->getCond()) {
543 Cnt.setCurrentRegionCount(Cnt.getParentCount() +
544 Cnt.getAdjustedCount() +
545 BC.ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000546 CountMap[S->getCond()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000547 Visit(S->getCond());
548 Cnt.adjustForControlFlow();
549 }
550 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
551 RecordNextStmtCount = true;
552 }
553
554 void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
555 RecordStmtCount(S);
556 Visit(S->getRangeStmt());
557 Visit(S->getBeginEndStmt());
Bob Wilsond8931422014-04-11 17:16:13 +0000558 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000559 RegionCounter Cnt(PGO, S);
560 BreakContinueStack.push_back(BreakContinue());
561 // Visit the body region first. (This is basically the same as a while
562 // loop; see further comments in VisitWhileStmt.)
563 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000564 CountMap[S->getLoopVarStmt()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000565 Visit(S->getLoopVarStmt());
566 Visit(S->getBody());
567 Cnt.adjustForControlFlow();
568
569 // The increment is essentially part of the body but it needs to include
570 // the count for all the continue statements.
571 Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
572 BreakContinueStack.back().ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000573 CountMap[S->getInc()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000574 Visit(S->getInc());
575 Cnt.adjustForControlFlow();
576
577 BreakContinue BC = BreakContinueStack.pop_back_val();
578
579 // ...then go back and propagate counts through the condition.
580 Cnt.setCurrentRegionCount(Cnt.getParentCount() +
581 Cnt.getAdjustedCount() +
582 BC.ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000583 CountMap[S->getCond()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000584 Visit(S->getCond());
585 Cnt.adjustForControlFlow();
586 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
587 RecordNextStmtCount = true;
588 }
589
590 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
591 RecordStmtCount(S);
592 Visit(S->getElement());
Bob Wilsond8931422014-04-11 17:16:13 +0000593 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000594 RegionCounter Cnt(PGO, S);
595 BreakContinueStack.push_back(BreakContinue());
596 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000597 CountMap[S->getBody()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000598 Visit(S->getBody());
599 BreakContinue BC = BreakContinueStack.pop_back_val();
600 Cnt.adjustForControlFlow();
601 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
602 RecordNextStmtCount = true;
603 }
604
605 void VisitSwitchStmt(const SwitchStmt *S) {
606 RecordStmtCount(S);
607 Visit(S->getCond());
608 PGO.setCurrentRegionUnreachable();
609 BreakContinueStack.push_back(BreakContinue());
610 Visit(S->getBody());
611 // If the switch is inside a loop, add the continue counts.
612 BreakContinue BC = BreakContinueStack.pop_back_val();
613 if (!BreakContinueStack.empty())
614 BreakContinueStack.back().ContinueCount += BC.ContinueCount;
Bob Wilsond8931422014-04-11 17:16:13 +0000615 // Counter tracks the exit block of the switch.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000616 RegionCounter ExitCnt(PGO, S);
617 ExitCnt.beginRegion();
618 RecordNextStmtCount = true;
619 }
620
621 void VisitCaseStmt(const CaseStmt *S) {
622 RecordNextStmtCount = false;
Bob Wilsond8931422014-04-11 17:16:13 +0000623 // Counter for this particular case. This counts only jumps from the
624 // switch header and does not include fallthrough from the case before
625 // this one.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000626 RegionCounter Cnt(PGO, S);
627 Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000628 CountMap[S] = Cnt.getCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000629 RecordNextStmtCount = true;
630 Visit(S->getSubStmt());
631 }
632
633 void VisitDefaultStmt(const DefaultStmt *S) {
634 RecordNextStmtCount = false;
Bob Wilsond8931422014-04-11 17:16:13 +0000635 // Counter for this default case. This does not include fallthrough from
636 // the previous case.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000637 RegionCounter Cnt(PGO, S);
638 Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000639 CountMap[S] = Cnt.getCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000640 RecordNextStmtCount = true;
641 Visit(S->getSubStmt());
642 }
643
644 void VisitIfStmt(const IfStmt *S) {
645 RecordStmtCount(S);
Bob Wilsond8931422014-04-11 17:16:13 +0000646 // Counter tracks the "then" part of an if statement. The count for
647 // the "else" part, if it exists, will be calculated from this counter.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000648 RegionCounter Cnt(PGO, S);
649 Visit(S->getCond());
650
651 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000652 CountMap[S->getThen()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000653 Visit(S->getThen());
654 Cnt.adjustForControlFlow();
655
656 if (S->getElse()) {
657 Cnt.beginElseRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000658 CountMap[S->getElse()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000659 Visit(S->getElse());
660 Cnt.adjustForControlFlow();
661 }
662 Cnt.applyAdjustmentsToRegion(0);
663 RecordNextStmtCount = true;
664 }
665
666 void VisitCXXTryStmt(const CXXTryStmt *S) {
667 RecordStmtCount(S);
668 Visit(S->getTryBlock());
669 for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
670 Visit(S->getHandler(I));
Bob Wilsond8931422014-04-11 17:16:13 +0000671 // Counter tracks the continuation block of the try statement.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000672 RegionCounter Cnt(PGO, S);
673 Cnt.beginRegion();
674 RecordNextStmtCount = true;
675 }
676
677 void VisitCXXCatchStmt(const CXXCatchStmt *S) {
678 RecordNextStmtCount = false;
Bob Wilsond8931422014-04-11 17:16:13 +0000679 // Counter tracks the catch statement's handler block.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000680 RegionCounter Cnt(PGO, S);
681 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000682 CountMap[S] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000683 Visit(S->getHandlerBlock());
684 }
685
Justin Bogner53c55d92014-04-11 06:10:10 +0000686 void VisitAbstractConditionalOperator(
687 const AbstractConditionalOperator *E) {
Bob Wilsonbf854f02014-02-17 19:21:09 +0000688 RecordStmtCount(E);
Bob Wilsond8931422014-04-11 17:16:13 +0000689 // Counter tracks the "true" part of a conditional operator. The
690 // count in the "false" part will be calculated from this counter.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000691 RegionCounter Cnt(PGO, E);
692 Visit(E->getCond());
693
694 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000695 CountMap[E->getTrueExpr()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000696 Visit(E->getTrueExpr());
697 Cnt.adjustForControlFlow();
698
699 Cnt.beginElseRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000700 CountMap[E->getFalseExpr()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000701 Visit(E->getFalseExpr());
702 Cnt.adjustForControlFlow();
703
704 Cnt.applyAdjustmentsToRegion(0);
705 RecordNextStmtCount = true;
706 }
707
708 void VisitBinLAnd(const BinaryOperator *E) {
709 RecordStmtCount(E);
Bob Wilsond8931422014-04-11 17:16:13 +0000710 // Counter tracks the right hand side of a logical and operator.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000711 RegionCounter Cnt(PGO, E);
712 Visit(E->getLHS());
713 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000714 CountMap[E->getRHS()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000715 Visit(E->getRHS());
716 Cnt.adjustForControlFlow();
717 Cnt.applyAdjustmentsToRegion(0);
718 RecordNextStmtCount = true;
719 }
720
721 void VisitBinLOr(const BinaryOperator *E) {
722 RecordStmtCount(E);
Bob Wilsond8931422014-04-11 17:16:13 +0000723 // Counter tracks the right hand side of a logical or operator.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000724 RegionCounter Cnt(PGO, E);
725 Visit(E->getLHS());
726 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000727 CountMap[E->getRHS()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000728 Visit(E->getRHS());
729 Cnt.adjustForControlFlow();
730 Cnt.applyAdjustmentsToRegion(0);
731 RecordNextStmtCount = true;
732 }
733 };
Justin Bogneref512b92014-01-06 22:27:43 +0000734}
735
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000736void PGOHash::combine(HashType Type) {
737 // Check that we never combine 0 and only have six bits.
738 assert(Type && "Hash is invalid: unexpected type 0");
739 assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
740
741 // Pass through MD5 if enough work has built up.
742 if (Count && Count % NumTypesPerWord == 0) {
743 using namespace llvm::support;
744 uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
745 MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
746 Working = 0;
747 }
748
749 // Accumulate the current type.
750 ++Count;
751 Working = Working << NumBitsPerType | Type;
752}
753
754uint64_t PGOHash::finalize() {
755 // Use Working as the hash directly if we never used MD5.
756 if (Count <= NumTypesPerWord)
757 // No need to byte swap here, since none of the math was endian-dependent.
758 // This number will be byte-swapped as required on endianness transitions,
759 // so we will see the same value on the other side.
760 return Working;
761
762 // Check for remaining work in Working.
763 if (Working)
764 MD5.update(Working);
765
766 // Finalize the MD5 and return the hash.
767 llvm::MD5::MD5Result Result;
768 MD5.final(Result);
769 using namespace llvm::support;
770 return endian::read<uint64_t, little, unaligned>(Result);
771}
772
Duncan P. N. Exon Smithd971cd12014-03-28 17:53:22 +0000773static void emitRuntimeHook(CodeGenModule &CGM) {
Duncan P. N. Exon Smith3fefedb2014-04-11 00:43:16 +0000774 const char *const RuntimeVarName = "__llvm_profile_runtime";
775 const char *const RuntimeUserName = "__llvm_profile_runtime_user";
Duncan P. N. Exon Smithd971cd12014-03-28 17:53:22 +0000776 if (CGM.getModule().getGlobalVariable(RuntimeVarName))
777 return;
778
779 // Declare the runtime hook.
780 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
781 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
782 auto *Var = new llvm::GlobalVariable(CGM.getModule(), Int32Ty, false,
783 llvm::GlobalValue::ExternalLinkage,
784 nullptr, RuntimeVarName);
785
786 // Make a function that uses it.
787 auto *User = llvm::Function::Create(llvm::FunctionType::get(Int32Ty, false),
788 llvm::GlobalValue::LinkOnceODRLinkage,
789 RuntimeUserName, &CGM.getModule());
790 User->addFnAttr(llvm::Attribute::NoInline);
791 if (CGM.getCodeGenOpts().DisableRedZone)
792 User->addFnAttr(llvm::Attribute::NoRedZone);
793 CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", User));
794 auto *Load = Builder.CreateLoad(Var);
795 Builder.CreateRet(Load);
796
797 // Create a use of the function. Now the definition of the runtime variable
798 // should get pulled in, along with any static initializears.
799 CGM.addUsedGlobal(User);
800}
801
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000802void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
Justin Bogneref512b92014-01-06 22:27:43 +0000803 bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
Justin Bogner837a6f62014-04-18 21:52:00 +0000804 llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
805 if (!InstrumentRegions && !PGOReader)
Justin Bogneref512b92014-01-06 22:27:43 +0000806 return;
Justin Bogneref512b92014-01-06 22:27:43 +0000807 if (!D)
808 return;
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000809 setFuncName(Fn);
Duncan P. N. Exon Smith7c414512014-03-20 22:50:08 +0000810
811 // Set the linkage for variables based on the function linkage. Usually, we
812 // want to match it, but available_externally and extern_weak both have the
813 // wrong semantics.
Duncan P. N. Exon Smith73f78622014-03-20 22:49:50 +0000814 VarLinkage = Fn->getLinkage();
Duncan P. N. Exon Smith7c414512014-03-20 22:50:08 +0000815 switch (VarLinkage) {
816 case llvm::GlobalValue::ExternalWeakLinkage:
817 VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;
818 break;
819 case llvm::GlobalValue::AvailableExternallyLinkage:
820 VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage;
821 break;
822 default:
823 break;
824 }
825
Justin Bogneref512b92014-01-06 22:27:43 +0000826 mapRegionCounters(D);
Duncan P. N. Exon Smithd971cd12014-03-28 17:53:22 +0000827 if (InstrumentRegions) {
828 emitRuntimeHook(CGM);
Justin Bogneref512b92014-01-06 22:27:43 +0000829 emitCounterVariables();
Duncan P. N. Exon Smithd971cd12014-03-28 17:53:22 +0000830 }
Justin Bogner837a6f62014-04-18 21:52:00 +0000831 if (PGOReader) {
832 loadRegionCounts(PGOReader);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000833 computeRegionCounts(D);
Justin Bogner837a6f62014-04-18 21:52:00 +0000834 applyFunctionAttributes(PGOReader, Fn);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000835 }
Justin Bogneref512b92014-01-06 22:27:43 +0000836}
837
838void CodeGenPGO::mapRegionCounters(const Decl *D) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000839 RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000840 MapRegionCounters Walker(*RegionCounterMap);
Justin Bogneref512b92014-01-06 22:27:43 +0000841 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000842 Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000843 else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000844 Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
Bob Wilsonc845c002014-03-06 20:24:27 +0000845 else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000846 Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
Justin Bogner81ab90f2014-04-15 00:50:54 +0000847 else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
848 Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
Justin Bogneref512b92014-01-06 22:27:43 +0000849 NumRegionCounters = Walker.NextCounter;
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000850 FunctionHash = Walker.Hash.finalize();
Justin Bogneref512b92014-01-06 22:27:43 +0000851}
852
Bob Wilsonbf854f02014-02-17 19:21:09 +0000853void CodeGenPGO::computeRegionCounts(const Decl *D) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000854 StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000855 ComputeRegionCounts Walker(*StmtCountMap, *this);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000856 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
857 Walker.VisitFunctionDecl(FD);
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000858 else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
859 Walker.VisitObjCMethodDecl(MD);
Bob Wilsonc845c002014-03-06 20:24:27 +0000860 else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
861 Walker.VisitBlockDecl(BD);
Justin Bogner81ab90f2014-04-15 00:50:54 +0000862 else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
863 Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
Bob Wilsonbf854f02014-02-17 19:21:09 +0000864}
865
Justin Bogner837a6f62014-04-18 21:52:00 +0000866void
867CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
868 llvm::Function *Fn) {
Justin Bogner4c9c45c2014-03-12 18:14:32 +0000869 if (!haveRegionCounts())
870 return;
871
Justin Bogner837a6f62014-04-18 21:52:00 +0000872 uint64_t MaxFunctionCount = PGOReader->getMaximumFunctionCount();
Justin Bogner4c9c45c2014-03-12 18:14:32 +0000873 uint64_t FunctionCount = getRegionCount(0);
874 if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount))
875 // Turn on InlineHint attribute for hot functions.
876 // FIXME: 30% is from preliminary tuning on SPEC, it may not be optimal.
877 Fn->addFnAttr(llvm::Attribute::InlineHint);
878 else if (FunctionCount <= (uint64_t)(0.01 * (double)MaxFunctionCount))
879 // Turn on Cold attribute for cold functions.
880 // FIXME: 1% is from preliminary tuning on SPEC, it may not be optimal.
881 Fn->addFnAttr(llvm::Attribute::Cold);
882}
883
Justin Bogneref512b92014-01-06 22:27:43 +0000884void CodeGenPGO::emitCounterVariables() {
885 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
886 llvm::ArrayType *CounterTy = llvm::ArrayType::get(llvm::Type::getInt64Ty(Ctx),
887 NumRegionCounters);
888 RegionCounters =
Duncan P. N. Exon Smith73f78622014-03-20 22:49:50 +0000889 new llvm::GlobalVariable(CGM.getModule(), CounterTy, false, VarLinkage,
Justin Bogneref512b92014-01-06 22:27:43 +0000890 llvm::Constant::getNullValue(CounterTy),
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000891 getFuncVarName("counters"));
892 RegionCounters->setAlignment(8);
893 RegionCounters->setSection(getCountersSection(CGM));
Justin Bogneref512b92014-01-06 22:27:43 +0000894}
895
896void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) {
Bob Wilson749ebc72014-03-06 04:55:28 +0000897 if (!RegionCounters)
Justin Bogneref512b92014-01-06 22:27:43 +0000898 return;
899 llvm::Value *Addr =
900 Builder.CreateConstInBoundsGEP2_64(RegionCounters, 0, Counter);
901 llvm::Value *Count = Builder.CreateLoad(Addr, "pgocount");
902 Count = Builder.CreateAdd(Count, Builder.getInt64(1));
903 Builder.CreateStore(Count, Addr);
904}
905
Justin Bogner837a6f62014-04-18 21:52:00 +0000906void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader) {
Justin Bognere2ef2a02014-04-15 21:22:35 +0000907 CGM.getPGOStats().Visited++;
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000908 RegionCounts.reset(new std::vector<uint64_t>);
Justin Bognerb4416f52014-03-18 21:58:06 +0000909 uint64_t Hash;
Justin Bogner837a6f62014-04-18 21:52:00 +0000910 if (PGOReader->getFunctionCounts(getFuncName(), Hash, *RegionCounts)) {
Justin Bognere2ef2a02014-04-15 21:22:35 +0000911 CGM.getPGOStats().Missing++;
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000912 RegionCounts.reset();
Justin Bognere2ef2a02014-04-15 21:22:35 +0000913 } else if (Hash != FunctionHash ||
914 RegionCounts->size() != NumRegionCounters) {
915 CGM.getPGOStats().Mismatched++;
916 RegionCounts.reset();
917 }
Justin Bogneref512b92014-01-06 22:27:43 +0000918}
919
920void CodeGenPGO::destroyRegionCounters() {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000921 RegionCounterMap.reset();
922 StmtCountMap.reset();
923 RegionCounts.reset();
Justin Bogneref512b92014-01-06 22:27:43 +0000924}
925
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000926/// \brief Calculate what to divide by to scale weights.
927///
928/// Given the maximum weight, calculate a divisor that will scale all the
929/// weights to strictly less than UINT32_MAX.
930static uint64_t calculateWeightScale(uint64_t MaxWeight) {
931 return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
932}
933
934/// \brief Scale an individual branch weight (and add 1).
935///
936/// Scale a 64-bit weight down to 32-bits using \c Scale.
937///
938/// According to Laplace's Rule of Succession, it is better to compute the
939/// weight based on the count plus 1, so universally add 1 to the value.
940///
941/// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
942/// greater than \c Weight.
943static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
944 assert(Scale && "scale by 0?");
945 uint64_t Scaled = Weight / Scale + 1;
946 assert(Scaled <= UINT32_MAX && "overflow 32-bits");
947 return Scaled;
948}
949
Justin Bogneref512b92014-01-06 22:27:43 +0000950llvm::MDNode *CodeGenPGO::createBranchWeights(uint64_t TrueCount,
951 uint64_t FalseCount) {
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000952 // Check for empty weights.
Justin Bogneref512b92014-01-06 22:27:43 +0000953 if (!TrueCount && !FalseCount)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000954 return nullptr;
Justin Bogneref512b92014-01-06 22:27:43 +0000955
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000956 // Calculate how to scale down to 32-bits.
957 uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
958
Justin Bogneref512b92014-01-06 22:27:43 +0000959 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000960 return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
961 scaleBranchWeight(FalseCount, Scale));
Justin Bogneref512b92014-01-06 22:27:43 +0000962}
963
Bob Wilson95a27b02014-02-17 19:20:59 +0000964llvm::MDNode *CodeGenPGO::createBranchWeights(ArrayRef<uint64_t> Weights) {
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000965 // We need at least two elements to create meaningful weights.
966 if (Weights.size() < 2)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000967 return nullptr;
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000968
Justin Bognerf3aefca2014-04-04 02:48:51 +0000969 // Check for empty weights.
970 uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
971 if (MaxWeight == 0)
972 return nullptr;
973
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000974 // Calculate how to scale down to 32-bits.
Justin Bognerf3aefca2014-04-04 02:48:51 +0000975 uint64_t Scale = calculateWeightScale(MaxWeight);
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000976
Justin Bogneref512b92014-01-06 22:27:43 +0000977 SmallVector<uint32_t, 16> ScaledWeights;
978 ScaledWeights.reserve(Weights.size());
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +0000979 for (uint64_t W : Weights)
980 ScaledWeights.push_back(scaleBranchWeight(W, Scale));
981
982 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
Justin Bogneref512b92014-01-06 22:27:43 +0000983 return MDHelper.createBranchWeights(ScaledWeights);
984}
Bob Wilsonbf854f02014-02-17 19:21:09 +0000985
986llvm::MDNode *CodeGenPGO::createLoopWeights(const Stmt *Cond,
987 RegionCounter &Cnt) {
988 if (!haveRegionCounts())
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000989 return nullptr;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000990 uint64_t LoopCount = Cnt.getCount();
991 uint64_t CondCount = 0;
992 bool Found = getStmtCount(Cond, CondCount);
993 assert(Found && "missing expected loop condition count");
994 (void)Found;
995 if (CondCount == 0)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000996 return nullptr;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000997 return createBranchWeights(LoopCount,
998 std::max(CondCount, LoopCount) - LoopCount);
999}