blob: d3d89e588a0dfa944ec10fe7e967af3b5a90a9bc [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"
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +000020#include "llvm/Support/Endian.h"
Justin Bogneref512b92014-01-06 22:27:43 +000021#include "llvm/Support/FileSystem.h"
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +000022#include "llvm/Support/MD5.h"
Justin Bogneref512b92014-01-06 22:27:43 +000023
24using namespace clang;
25using namespace CodeGen;
26
Justin Bognerd66a17d2014-03-12 21:06:31 +000027static void ReportBadPGOData(CodeGenModule &CGM, const char *Message) {
28 DiagnosticsEngine &Diags = CGM.getDiags();
29 unsigned diagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0");
30 Diags.Report(diagID) << Message;
31}
32
33PGOProfileData::PGOProfileData(CodeGenModule &CGM, std::string Path)
34 : CGM(CGM) {
35 if (llvm::MemoryBuffer::getFile(Path, DataBuffer)) {
36 ReportBadPGOData(CGM, "failed to open pgo data file");
37 return;
38 }
39
40 if (DataBuffer->getBufferSize() > std::numeric_limits<unsigned>::max()) {
41 ReportBadPGOData(CGM, "pgo data file too big");
42 return;
43 }
44
45 // Scan through the data file and map each function to the corresponding
46 // file offset where its counts are stored.
47 const char *BufferStart = DataBuffer->getBufferStart();
48 const char *BufferEnd = DataBuffer->getBufferEnd();
49 const char *CurPtr = BufferStart;
50 uint64_t MaxCount = 0;
51 while (CurPtr < BufferEnd) {
52 // Read the function name.
53 const char *FuncStart = CurPtr;
54 // For Objective-C methods, the name may include whitespace, so search
55 // backward from the end of the line to find the space that separates the
56 // name from the number of counters. (This is a temporary hack since we are
57 // going to completely replace this file format in the near future.)
58 CurPtr = strchr(CurPtr, '\n');
59 if (!CurPtr) {
60 ReportBadPGOData(CGM, "pgo data file has malformed function entry");
61 return;
62 }
Justin Bognerd66a17d2014-03-12 21:06:31 +000063 StringRef FuncName(FuncStart, CurPtr - FuncStart);
64
Justin Bognerb4416f52014-03-18 21:58:06 +000065 // Skip over the function hash.
66 CurPtr = strchr(++CurPtr, '\n');
67 if (!CurPtr) {
68 ReportBadPGOData(CGM, "pgo data file is missing the function hash");
69 return;
70 }
71
Justin Bognerd66a17d2014-03-12 21:06:31 +000072 // Read the number of counters.
73 char *EndPtr;
Duncan P. N. Exon Smithe9624292014-04-10 23:37:34 +000074 unsigned NumCounters = strtoul(++CurPtr, &EndPtr, 10);
Justin Bognerd66a17d2014-03-12 21:06:31 +000075 if (EndPtr == CurPtr || *EndPtr != '\n' || NumCounters <= 0) {
76 ReportBadPGOData(CGM, "pgo data file has unexpected number of counters");
77 return;
78 }
79 CurPtr = EndPtr;
80
81 // Read function count.
Duncan P. N. Exon Smithe9624292014-04-10 23:37:34 +000082 uint64_t Count = strtoull(CurPtr, &EndPtr, 10);
Justin Bognerd66a17d2014-03-12 21:06:31 +000083 if (EndPtr == CurPtr || *EndPtr != '\n') {
84 ReportBadPGOData(CGM, "pgo-data file has bad count value");
85 return;
86 }
87 CurPtr = EndPtr; // Point to '\n'.
88 FunctionCounts[FuncName] = Count;
89 MaxCount = Count > MaxCount ? Count : MaxCount;
90
91 // There is one line for each counter; skip over those lines.
92 // Since function count is already read, we start the loop from 1.
93 for (unsigned N = 1; N < NumCounters; ++N) {
94 CurPtr = strchr(++CurPtr, '\n');
95 if (!CurPtr) {
96 ReportBadPGOData(CGM, "pgo data file is missing some counter info");
97 return;
98 }
99 }
100
101 // Skip over the blank line separating functions.
102 CurPtr += 2;
103
104 DataOffsets[FuncName] = FuncStart - BufferStart;
105 }
106 MaxFunctionCount = MaxCount;
107}
108
Justin Bognerb4416f52014-03-18 21:58:06 +0000109bool PGOProfileData::getFunctionCounts(StringRef FuncName, uint64_t &FuncHash,
Justin Bognerd66a17d2014-03-12 21:06:31 +0000110 std::vector<uint64_t> &Counts) {
111 // Find the relevant section of the pgo-data file.
112 llvm::StringMap<unsigned>::const_iterator OffsetIter =
113 DataOffsets.find(FuncName);
114 if (OffsetIter == DataOffsets.end())
115 return true;
116 const char *CurPtr = DataBuffer->getBufferStart() + OffsetIter->getValue();
117
118 // Skip over the function name.
119 CurPtr = strchr(CurPtr, '\n');
120 assert(CurPtr && "pgo-data has corrupted function entry");
Justin Bognerb4416f52014-03-18 21:58:06 +0000121
122 char *EndPtr;
123 // Read the function hash.
Duncan P. N. Exon Smithe9624292014-04-10 23:37:34 +0000124 FuncHash = strtoull(++CurPtr, &EndPtr, 10);
Justin Bognerb4416f52014-03-18 21:58:06 +0000125 assert(EndPtr != CurPtr && *EndPtr == '\n' &&
126 "pgo-data file has corrupted function hash");
127 CurPtr = EndPtr;
Justin Bognerd66a17d2014-03-12 21:06:31 +0000128
129 // Read the number of counters.
Duncan P. N. Exon Smithe9624292014-04-10 23:37:34 +0000130 unsigned NumCounters = strtoul(++CurPtr, &EndPtr, 10);
Justin Bognerd66a17d2014-03-12 21:06:31 +0000131 assert(EndPtr != CurPtr && *EndPtr == '\n' && NumCounters > 0 &&
132 "pgo-data file has corrupted number of counters");
133 CurPtr = EndPtr;
134
135 Counts.reserve(NumCounters);
136
137 for (unsigned N = 0; N < NumCounters; ++N) {
138 // Read the count value.
Duncan P. N. Exon Smithe9624292014-04-10 23:37:34 +0000139 uint64_t Count = strtoull(CurPtr, &EndPtr, 10);
Justin Bognerd66a17d2014-03-12 21:06:31 +0000140 if (EndPtr == CurPtr || *EndPtr != '\n') {
141 ReportBadPGOData(CGM, "pgo-data file has bad count value");
142 return true;
143 }
144 Counts.push_back(Count);
145 CurPtr = EndPtr + 1;
146 }
147
148 // Make sure the number of counters matches up.
149 if (Counts.size() != NumCounters) {
150 ReportBadPGOData(CGM, "pgo-data file has inconsistent counters");
151 return true;
152 }
153
154 return false;
155}
156
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000157void CodeGenPGO::setFuncName(llvm::Function *Fn) {
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000158 RawFuncName = Fn->getName();
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000159
160 // Function names may be prefixed with a binary '1' to indicate
161 // that the backend should not modify the symbols due to any platform
162 // naming convention. Do not include that '1' in the PGO profile name.
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000163 if (RawFuncName[0] == '\1')
164 RawFuncName = RawFuncName.substr(1);
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000165
166 if (!Fn->hasLocalLinkage()) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000167 PrefixedFuncName.reset(new std::string(RawFuncName));
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000168 return;
169 }
170
171 // For local symbols, prepend the main file name to distinguish them.
172 // Do not include the full path in the file name since there's no guarantee
173 // that it will stay the same, e.g., if the files are checked out from
174 // version control in different locations.
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000175 PrefixedFuncName.reset(new std::string(CGM.getCodeGenOpts().MainFileName));
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000176 if (PrefixedFuncName->empty())
177 PrefixedFuncName->assign("<unknown>");
178 PrefixedFuncName->append(":");
179 PrefixedFuncName->append(RawFuncName);
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000180}
181
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000182static llvm::Function *getRegisterFunc(CodeGenModule &CGM) {
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000183 return CGM.getModule().getFunction("__llvm_profile_register_functions");
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000184}
185
186static llvm::BasicBlock *getOrInsertRegisterBB(CodeGenModule &CGM) {
Duncan P. N. Exon Smith780443e2014-03-20 03:57:11 +0000187 // Don't do this for Darwin. compiler-rt uses linker magic.
188 if (CGM.getTarget().getTriple().isOSDarwin())
189 return nullptr;
190
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000191 // Only need to insert this once per module.
192 if (llvm::Function *RegisterF = getRegisterFunc(CGM))
193 return &RegisterF->getEntryBlock();
194
195 // Construct the function.
196 auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
197 auto *RegisterFTy = llvm::FunctionType::get(VoidTy, false);
198 auto *RegisterF = llvm::Function::Create(RegisterFTy,
199 llvm::GlobalValue::InternalLinkage,
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000200 "__llvm_profile_register_functions",
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000201 &CGM.getModule());
202 RegisterF->setUnnamedAddr(true);
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000203 if (CGM.getCodeGenOpts().DisableRedZone)
204 RegisterF->addFnAttr(llvm::Attribute::NoRedZone);
205
206 // Construct and return the entry block.
207 auto *BB = llvm::BasicBlock::Create(CGM.getLLVMContext(), "", RegisterF);
208 CGBuilderTy Builder(BB);
209 Builder.CreateRetVoid();
210 return BB;
211}
212
213static llvm::Constant *getOrInsertRuntimeRegister(CodeGenModule &CGM) {
214 auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
215 auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
216 auto *RuntimeRegisterTy = llvm::FunctionType::get(VoidTy, VoidPtrTy, false);
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000217 return CGM.getModule().getOrInsertFunction("__llvm_profile_register_function",
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000218 RuntimeRegisterTy);
219}
220
Duncan P. N. Exon Smith7134d472014-03-20 03:17:15 +0000221static bool isMachO(const CodeGenModule &CGM) {
222 return CGM.getTarget().getTriple().isOSBinFormatMachO();
223}
224
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000225static StringRef getCountersSection(const CodeGenModule &CGM) {
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000226 return isMachO(CGM) ? "__DATA,__llvm_prf_cnts" : "__llvm_prf_cnts";
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000227}
228
229static StringRef getNameSection(const CodeGenModule &CGM) {
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000230 return isMachO(CGM) ? "__DATA,__llvm_prf_names" : "__llvm_prf_names";
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000231}
232
233static StringRef getDataSection(const CodeGenModule &CGM) {
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000234 return isMachO(CGM) ? "__DATA,__llvm_prf_data" : "__llvm_prf_data";
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000235}
236
237llvm::GlobalVariable *CodeGenPGO::buildDataVar() {
238 // Create name variable.
239 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
240 auto *VarName = llvm::ConstantDataArray::getString(Ctx, getFuncName(),
241 false);
242 auto *Name = new llvm::GlobalVariable(CGM.getModule(), VarName->getType(),
Duncan P. N. Exon Smith73f78622014-03-20 22:49:50 +0000243 true, VarLinkage, VarName,
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000244 getFuncVarName("name"));
245 Name->setSection(getNameSection(CGM));
246 Name->setAlignment(1);
247
248 // Create data variable.
249 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
Justin Bognerb4416f52014-03-18 21:58:06 +0000250 auto *Int64Ty = llvm::Type::getInt64Ty(Ctx);
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000251 auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
252 auto *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);
253 llvm::Type *DataTypes[] = {
Justin Bognerb4416f52014-03-18 21:58:06 +0000254 Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000255 };
256 auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes));
257 llvm::Constant *DataVals[] = {
258 llvm::ConstantInt::get(Int32Ty, getFuncName().size()),
259 llvm::ConstantInt::get(Int32Ty, NumRegionCounters),
Justin Bognerb4416f52014-03-18 21:58:06 +0000260 llvm::ConstantInt::get(Int64Ty, FunctionHash),
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000261 llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),
262 llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)
263 };
264 auto *Data =
Duncan P. N. Exon Smith73f78622014-03-20 22:49:50 +0000265 new llvm::GlobalVariable(CGM.getModule(), DataTy, true, VarLinkage,
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000266 llvm::ConstantStruct::get(DataTy, DataVals),
267 getFuncVarName("data"));
268
269 // All the data should be packed into an array in its own section.
270 Data->setSection(getDataSection(CGM));
271 Data->setAlignment(8);
272
273 // Make sure the data doesn't get deleted.
274 CGM.addUsedGlobal(Data);
275 return Data;
276}
277
278void CodeGenPGO::emitInstrumentationData() {
Justin Bogneref512b92014-01-06 22:27:43 +0000279 if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
280 return;
281
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000282 // Build the data.
283 auto *Data = buildDataVar();
Justin Bogneref512b92014-01-06 22:27:43 +0000284
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000285 // Register the data.
Duncan P. N. Exon Smith780443e2014-03-20 03:57:11 +0000286 auto *RegisterBB = getOrInsertRegisterBB(CGM);
287 if (!RegisterBB)
288 return;
289 CGBuilderTy Builder(RegisterBB->getTerminator());
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000290 auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
291 Builder.CreateCall(getOrInsertRuntimeRegister(CGM),
292 Builder.CreateBitCast(Data, VoidPtrTy));
Justin Bogneref512b92014-01-06 22:27:43 +0000293}
294
295llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) {
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000296 if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000297 return nullptr;
Justin Bogneref512b92014-01-06 22:27:43 +0000298
Justin Bognerf2ea7752014-04-10 18:13:13 +0000299 assert(CGM.getModule().getFunction("__llvm_profile_init") == nullptr &&
300 "profile initialization already emitted");
Justin Bogneref512b92014-01-06 22:27:43 +0000301
Duncan P. N. Exon Smith5188e912014-03-20 19:23:46 +0000302 // Get the function to call at initialization.
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000303 llvm::Constant *RegisterF = getRegisterFunc(CGM);
Duncan P. N. Exon Smith5188e912014-03-20 19:23:46 +0000304 if (!RegisterF)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +0000305 return nullptr;
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000306
307 // Create the initialization function.
308 auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
309 auto *F = llvm::Function::Create(llvm::FunctionType::get(VoidTy, false),
310 llvm::GlobalValue::InternalLinkage,
Duncan P. N. Exon Smitha7807632014-03-20 20:00:41 +0000311 "__llvm_profile_init", &CGM.getModule());
Justin Bogneref512b92014-01-06 22:27:43 +0000312 F->setUnnamedAddr(true);
Justin Bogneref512b92014-01-06 22:27:43 +0000313 F->addFnAttr(llvm::Attribute::NoInline);
314 if (CGM.getCodeGenOpts().DisableRedZone)
315 F->addFnAttr(llvm::Attribute::NoRedZone);
316
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000317 // Add the basic block and the necessary calls.
318 CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", F));
Duncan P. N. Exon Smith5188e912014-03-20 19:23:46 +0000319 Builder.CreateCall(RegisterF);
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000320 Builder.CreateRetVoid();
Justin Bogneref512b92014-01-06 22:27:43 +0000321
322 return F;
323}
324
325namespace {
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000326/// \brief Stable hasher for PGO region counters.
327///
328/// PGOHash produces a stable hash of a given function's control flow.
329///
330/// Changing the output of this hash will invalidate all previously generated
331/// profiles -- i.e., don't do it.
332///
333/// \note When this hash does eventually change (years?), we still need to
334/// support old hashes. We'll need to pull in the version number from the
335/// profile data format and use the matching hash function.
336class PGOHash {
337 uint64_t Working;
338 unsigned Count;
339 llvm::MD5 MD5;
340
341 static const int NumBitsPerType = 6;
342 static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
343 static const unsigned TooBig = 1u << NumBitsPerType;
344
345public:
346 /// \brief Hash values for AST nodes.
347 ///
348 /// Distinct values for AST nodes that have region counters attached.
349 ///
350 /// These values must be stable. All new members must be added at the end,
351 /// and no members should be removed. Changing the enumeration value for an
352 /// AST node will affect the hash of every function that contains that node.
353 enum HashType : unsigned char {
354 None = 0,
355 LabelStmt = 1,
356 WhileStmt,
357 DoStmt,
358 ForStmt,
359 CXXForRangeStmt,
360 ObjCForCollectionStmt,
361 SwitchStmt,
362 CaseStmt,
363 DefaultStmt,
364 IfStmt,
365 CXXTryStmt,
366 CXXCatchStmt,
367 ConditionalOperator,
368 BinaryOperatorLAnd,
369 BinaryOperatorLOr,
370 BinaryConditionalOperator,
371
372 // Keep this last. It's for the static assert that follows.
373 LastHashType
374 };
375 static_assert(LastHashType <= TooBig, "Too many types in HashType");
376
377 // TODO: When this format changes, take in a version number here, and use the
378 // old hash calculation for file formats that used the old hash.
379 PGOHash() : Working(0), Count(0) {}
380 void combine(HashType Type);
381 uint64_t finalize();
382};
383const int PGOHash::NumBitsPerType;
384const unsigned PGOHash::NumTypesPerWord;
385const unsigned PGOHash::TooBig;
386
Bob Wilsond8931422014-04-11 17:16:13 +0000387 /// A RecursiveASTVisitor that fills a map of statements to PGO counters.
388 struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
Justin Bogneref512b92014-01-06 22:27:43 +0000389 /// The next counter value to assign.
390 unsigned NextCounter;
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000391 /// The function hash.
392 PGOHash Hash;
Justin Bogneref512b92014-01-06 22:27:43 +0000393 /// The map of statements to counters.
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000394 llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
Justin Bogneref512b92014-01-06 22:27:43 +0000395
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000396 MapRegionCounters(llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
397 : NextCounter(0), CounterMap(CounterMap) {}
Justin Bogneref512b92014-01-06 22:27:43 +0000398
Justin Bogner191ec632014-04-11 23:06:35 +0000399 // Blocks and lambdas are handled as separate functions, so we need not
400 // traverse them in the parent context.
401 bool TraverseBlockExpr(BlockExpr *BE) { return true; }
402 bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
Justin Bogner81ab90f2014-04-15 00:50:54 +0000403 bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
Justin Bogneref512b92014-01-06 22:27:43 +0000404
Bob Wilsond8931422014-04-11 17:16:13 +0000405 bool VisitDecl(const Decl *D) {
406 switch (D->getKind()) {
407 default:
408 break;
409 case Decl::Function:
410 case Decl::CXXMethod:
411 case Decl::CXXConstructor:
412 case Decl::CXXDestructor:
413 case Decl::CXXConversion:
414 case Decl::ObjCMethod:
415 case Decl::Block:
Justin Bogner81ab90f2014-04-15 00:50:54 +0000416 case Decl::Captured:
Bob Wilsond8931422014-04-11 17:16:13 +0000417 CounterMap[D->getBody()] = NextCounter++;
418 break;
419 }
420 return true;
Justin Bogneref512b92014-01-06 22:27:43 +0000421 }
Bob Wilsond8931422014-04-11 17:16:13 +0000422
423 bool VisitStmt(const Stmt *S) {
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000424 auto Type = getHashType(S);
425 if (Type == PGOHash::None)
426 return true;
427
428 CounterMap[S] = NextCounter++;
429 Hash.combine(Type);
430 return true;
431 }
432 PGOHash::HashType getHashType(const Stmt *S) {
Bob Wilsond8931422014-04-11 17:16:13 +0000433 switch (S->getStmtClass()) {
434 default:
435 break;
436 case Stmt::LabelStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000437 return PGOHash::LabelStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000438 case Stmt::WhileStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000439 return PGOHash::WhileStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000440 case Stmt::DoStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000441 return PGOHash::DoStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000442 case Stmt::ForStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000443 return PGOHash::ForStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000444 case Stmt::CXXForRangeStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000445 return PGOHash::CXXForRangeStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000446 case Stmt::ObjCForCollectionStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000447 return PGOHash::ObjCForCollectionStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000448 case Stmt::SwitchStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000449 return PGOHash::SwitchStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000450 case Stmt::CaseStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000451 return PGOHash::CaseStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000452 case Stmt::DefaultStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000453 return PGOHash::DefaultStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000454 case Stmt::IfStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000455 return PGOHash::IfStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000456 case Stmt::CXXTryStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000457 return PGOHash::CXXTryStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000458 case Stmt::CXXCatchStmtClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000459 return PGOHash::CXXCatchStmt;
Bob Wilsond8931422014-04-11 17:16:13 +0000460 case Stmt::ConditionalOperatorClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000461 return PGOHash::ConditionalOperator;
Bob Wilsond8931422014-04-11 17:16:13 +0000462 case Stmt::BinaryConditionalOperatorClass:
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000463 return PGOHash::BinaryConditionalOperator;
Bob Wilsond8931422014-04-11 17:16:13 +0000464 case Stmt::BinaryOperatorClass: {
465 const BinaryOperator *BO = cast<BinaryOperator>(S);
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000466 if (BO->getOpcode() == BO_LAnd)
467 return PGOHash::BinaryOperatorLAnd;
468 if (BO->getOpcode() == BO_LOr)
469 return PGOHash::BinaryOperatorLOr;
Bob Wilsond8931422014-04-11 17:16:13 +0000470 break;
471 }
472 }
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000473 return PGOHash::None;
Justin Bogneref512b92014-01-06 22:27:43 +0000474 }
475 };
Bob Wilsonbf854f02014-02-17 19:21:09 +0000476
477 /// A StmtVisitor that propagates the raw counts through the AST and
478 /// records the count at statements where the value may change.
479 struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
480 /// PGO state.
481 CodeGenPGO &PGO;
482
483 /// A flag that is set when the current count should be recorded on the
484 /// next statement, such as at the exit of a loop.
485 bool RecordNextStmtCount;
486
487 /// The map of statements to count values.
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000488 llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000489
490 /// BreakContinueStack - Keep counts of breaks and continues inside loops.
491 struct BreakContinue {
492 uint64_t BreakCount;
493 uint64_t ContinueCount;
494 BreakContinue() : BreakCount(0), ContinueCount(0) {}
495 };
496 SmallVector<BreakContinue, 8> BreakContinueStack;
497
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000498 ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
499 CodeGenPGO &PGO)
500 : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
Bob Wilsonbf854f02014-02-17 19:21:09 +0000501
502 void RecordStmtCount(const Stmt *S) {
503 if (RecordNextStmtCount) {
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000504 CountMap[S] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000505 RecordNextStmtCount = false;
506 }
507 }
508
509 void VisitStmt(const Stmt *S) {
510 RecordStmtCount(S);
511 for (Stmt::const_child_range I = S->children(); I; ++I) {
512 if (*I)
513 this->Visit(*I);
514 }
515 }
516
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000517 void VisitFunctionDecl(const FunctionDecl *D) {
Bob Wilsond8931422014-04-11 17:16:13 +0000518 // Counter tracks entry to the function body.
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000519 RegionCounter Cnt(PGO, D->getBody());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000520 Cnt.beginRegion();
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000521 CountMap[D->getBody()] = PGO.getCurrentRegionCount();
522 Visit(D->getBody());
Bob Wilsonbf854f02014-02-17 19:21:09 +0000523 }
524
Justin Bogner191ec632014-04-11 23:06:35 +0000525 // Skip lambda expressions. We visit these as FunctionDecls when we're
526 // generating them and aren't interested in the body when generating a
527 // parent context.
528 void VisitLambdaExpr(const LambdaExpr *LE) {}
529
Justin Bogner81ab90f2014-04-15 00:50:54 +0000530 void VisitCapturedDecl(const CapturedDecl *D) {
531 // Counter tracks entry to the capture body.
532 RegionCounter Cnt(PGO, D->getBody());
533 Cnt.beginRegion();
534 CountMap[D->getBody()] = PGO.getCurrentRegionCount();
535 Visit(D->getBody());
536 }
537
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000538 void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
Bob Wilsond8931422014-04-11 17:16:13 +0000539 // Counter tracks entry to the method body.
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000540 RegionCounter Cnt(PGO, D->getBody());
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000541 Cnt.beginRegion();
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000542 CountMap[D->getBody()] = PGO.getCurrentRegionCount();
543 Visit(D->getBody());
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000544 }
545
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000546 void VisitBlockDecl(const BlockDecl *D) {
Bob Wilsond8931422014-04-11 17:16:13 +0000547 // Counter tracks entry to the block body.
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000548 RegionCounter Cnt(PGO, D->getBody());
Bob Wilsonc845c002014-03-06 20:24:27 +0000549 Cnt.beginRegion();
Duncan P. N. Exon Smith4a2f5ae2014-04-10 23:37:36 +0000550 CountMap[D->getBody()] = PGO.getCurrentRegionCount();
551 Visit(D->getBody());
Bob Wilsonc845c002014-03-06 20:24:27 +0000552 }
553
Bob Wilsonbf854f02014-02-17 19:21:09 +0000554 void VisitReturnStmt(const ReturnStmt *S) {
555 RecordStmtCount(S);
556 if (S->getRetValue())
557 Visit(S->getRetValue());
558 PGO.setCurrentRegionUnreachable();
559 RecordNextStmtCount = true;
560 }
561
562 void VisitGotoStmt(const GotoStmt *S) {
563 RecordStmtCount(S);
564 PGO.setCurrentRegionUnreachable();
565 RecordNextStmtCount = true;
566 }
567
568 void VisitLabelStmt(const LabelStmt *S) {
569 RecordNextStmtCount = false;
Bob Wilsond8931422014-04-11 17:16:13 +0000570 // Counter tracks the block following the label.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000571 RegionCounter Cnt(PGO, S);
572 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000573 CountMap[S] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000574 Visit(S->getSubStmt());
575 }
576
577 void VisitBreakStmt(const BreakStmt *S) {
578 RecordStmtCount(S);
579 assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
580 BreakContinueStack.back().BreakCount += PGO.getCurrentRegionCount();
581 PGO.setCurrentRegionUnreachable();
582 RecordNextStmtCount = true;
583 }
584
585 void VisitContinueStmt(const ContinueStmt *S) {
586 RecordStmtCount(S);
587 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
588 BreakContinueStack.back().ContinueCount += PGO.getCurrentRegionCount();
589 PGO.setCurrentRegionUnreachable();
590 RecordNextStmtCount = true;
591 }
592
593 void VisitWhileStmt(const WhileStmt *S) {
594 RecordStmtCount(S);
Bob Wilsond8931422014-04-11 17:16:13 +0000595 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000596 RegionCounter Cnt(PGO, S);
597 BreakContinueStack.push_back(BreakContinue());
598 // Visit the body region first so the break/continue adjustments can be
599 // included when visiting the condition.
600 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000601 CountMap[S->getBody()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000602 Visit(S->getBody());
603 Cnt.adjustForControlFlow();
604
605 // ...then go back and propagate counts through the condition. The count
606 // at the start of the condition is the sum of the incoming edges,
607 // the backedge from the end of the loop body, and the edges from
608 // continue statements.
609 BreakContinue BC = BreakContinueStack.pop_back_val();
610 Cnt.setCurrentRegionCount(Cnt.getParentCount() +
611 Cnt.getAdjustedCount() + BC.ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000612 CountMap[S->getCond()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000613 Visit(S->getCond());
614 Cnt.adjustForControlFlow();
615 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
616 RecordNextStmtCount = true;
617 }
618
619 void VisitDoStmt(const DoStmt *S) {
620 RecordStmtCount(S);
Bob Wilsond8931422014-04-11 17:16:13 +0000621 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000622 RegionCounter Cnt(PGO, S);
623 BreakContinueStack.push_back(BreakContinue());
624 Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000625 CountMap[S->getBody()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000626 Visit(S->getBody());
627 Cnt.adjustForControlFlow();
628
629 BreakContinue BC = BreakContinueStack.pop_back_val();
630 // The count at the start of the condition is equal to the count at the
631 // end of the body. The adjusted count does not include either the
632 // fall-through count coming into the loop or the continue count, so add
633 // both of those separately. This is coincidentally the same equation as
634 // with while loops but for different reasons.
635 Cnt.setCurrentRegionCount(Cnt.getParentCount() +
636 Cnt.getAdjustedCount() + BC.ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000637 CountMap[S->getCond()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000638 Visit(S->getCond());
639 Cnt.adjustForControlFlow();
640 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
641 RecordNextStmtCount = true;
642 }
643
644 void VisitForStmt(const ForStmt *S) {
645 RecordStmtCount(S);
646 if (S->getInit())
647 Visit(S->getInit());
Bob Wilsond8931422014-04-11 17:16:13 +0000648 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000649 RegionCounter Cnt(PGO, S);
650 BreakContinueStack.push_back(BreakContinue());
651 // Visit the body region first. (This is basically the same as a while
652 // loop; see further comments in VisitWhileStmt.)
653 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000654 CountMap[S->getBody()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000655 Visit(S->getBody());
656 Cnt.adjustForControlFlow();
657
658 // The increment is essentially part of the body but it needs to include
659 // the count for all the continue statements.
660 if (S->getInc()) {
661 Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
662 BreakContinueStack.back().ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000663 CountMap[S->getInc()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000664 Visit(S->getInc());
665 Cnt.adjustForControlFlow();
666 }
667
668 BreakContinue BC = BreakContinueStack.pop_back_val();
669
670 // ...then go back and propagate counts through the condition.
671 if (S->getCond()) {
672 Cnt.setCurrentRegionCount(Cnt.getParentCount() +
673 Cnt.getAdjustedCount() +
674 BC.ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000675 CountMap[S->getCond()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000676 Visit(S->getCond());
677 Cnt.adjustForControlFlow();
678 }
679 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
680 RecordNextStmtCount = true;
681 }
682
683 void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
684 RecordStmtCount(S);
685 Visit(S->getRangeStmt());
686 Visit(S->getBeginEndStmt());
Bob Wilsond8931422014-04-11 17:16:13 +0000687 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000688 RegionCounter Cnt(PGO, S);
689 BreakContinueStack.push_back(BreakContinue());
690 // Visit the body region first. (This is basically the same as a while
691 // loop; see further comments in VisitWhileStmt.)
692 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000693 CountMap[S->getLoopVarStmt()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000694 Visit(S->getLoopVarStmt());
695 Visit(S->getBody());
696 Cnt.adjustForControlFlow();
697
698 // The increment is essentially part of the body but it needs to include
699 // the count for all the continue statements.
700 Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
701 BreakContinueStack.back().ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000702 CountMap[S->getInc()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000703 Visit(S->getInc());
704 Cnt.adjustForControlFlow();
705
706 BreakContinue BC = BreakContinueStack.pop_back_val();
707
708 // ...then go back and propagate counts through the condition.
709 Cnt.setCurrentRegionCount(Cnt.getParentCount() +
710 Cnt.getAdjustedCount() +
711 BC.ContinueCount);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000712 CountMap[S->getCond()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000713 Visit(S->getCond());
714 Cnt.adjustForControlFlow();
715 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
716 RecordNextStmtCount = true;
717 }
718
719 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
720 RecordStmtCount(S);
721 Visit(S->getElement());
Bob Wilsond8931422014-04-11 17:16:13 +0000722 // Counter tracks the body of the loop.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000723 RegionCounter Cnt(PGO, S);
724 BreakContinueStack.push_back(BreakContinue());
725 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000726 CountMap[S->getBody()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000727 Visit(S->getBody());
728 BreakContinue BC = BreakContinueStack.pop_back_val();
729 Cnt.adjustForControlFlow();
730 Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
731 RecordNextStmtCount = true;
732 }
733
734 void VisitSwitchStmt(const SwitchStmt *S) {
735 RecordStmtCount(S);
736 Visit(S->getCond());
737 PGO.setCurrentRegionUnreachable();
738 BreakContinueStack.push_back(BreakContinue());
739 Visit(S->getBody());
740 // If the switch is inside a loop, add the continue counts.
741 BreakContinue BC = BreakContinueStack.pop_back_val();
742 if (!BreakContinueStack.empty())
743 BreakContinueStack.back().ContinueCount += BC.ContinueCount;
Bob Wilsond8931422014-04-11 17:16:13 +0000744 // Counter tracks the exit block of the switch.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000745 RegionCounter ExitCnt(PGO, S);
746 ExitCnt.beginRegion();
747 RecordNextStmtCount = true;
748 }
749
750 void VisitCaseStmt(const CaseStmt *S) {
751 RecordNextStmtCount = false;
Bob Wilsond8931422014-04-11 17:16:13 +0000752 // Counter for this particular case. This counts only jumps from the
753 // switch header and does not include fallthrough from the case before
754 // this one.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000755 RegionCounter Cnt(PGO, S);
756 Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000757 CountMap[S] = Cnt.getCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000758 RecordNextStmtCount = true;
759 Visit(S->getSubStmt());
760 }
761
762 void VisitDefaultStmt(const DefaultStmt *S) {
763 RecordNextStmtCount = false;
Bob Wilsond8931422014-04-11 17:16:13 +0000764 // Counter for this default case. This does not include fallthrough from
765 // the previous case.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000766 RegionCounter Cnt(PGO, S);
767 Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000768 CountMap[S] = Cnt.getCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000769 RecordNextStmtCount = true;
770 Visit(S->getSubStmt());
771 }
772
773 void VisitIfStmt(const IfStmt *S) {
774 RecordStmtCount(S);
Bob Wilsond8931422014-04-11 17:16:13 +0000775 // Counter tracks the "then" part of an if statement. The count for
776 // the "else" part, if it exists, will be calculated from this counter.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000777 RegionCounter Cnt(PGO, S);
778 Visit(S->getCond());
779
780 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000781 CountMap[S->getThen()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000782 Visit(S->getThen());
783 Cnt.adjustForControlFlow();
784
785 if (S->getElse()) {
786 Cnt.beginElseRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000787 CountMap[S->getElse()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000788 Visit(S->getElse());
789 Cnt.adjustForControlFlow();
790 }
791 Cnt.applyAdjustmentsToRegion(0);
792 RecordNextStmtCount = true;
793 }
794
795 void VisitCXXTryStmt(const CXXTryStmt *S) {
796 RecordStmtCount(S);
797 Visit(S->getTryBlock());
798 for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
799 Visit(S->getHandler(I));
Bob Wilsond8931422014-04-11 17:16:13 +0000800 // Counter tracks the continuation block of the try statement.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000801 RegionCounter Cnt(PGO, S);
802 Cnt.beginRegion();
803 RecordNextStmtCount = true;
804 }
805
806 void VisitCXXCatchStmt(const CXXCatchStmt *S) {
807 RecordNextStmtCount = false;
Bob Wilsond8931422014-04-11 17:16:13 +0000808 // Counter tracks the catch statement's handler block.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000809 RegionCounter Cnt(PGO, S);
810 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000811 CountMap[S] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000812 Visit(S->getHandlerBlock());
813 }
814
Justin Bogner53c55d92014-04-11 06:10:10 +0000815 void VisitAbstractConditionalOperator(
816 const AbstractConditionalOperator *E) {
Bob Wilsonbf854f02014-02-17 19:21:09 +0000817 RecordStmtCount(E);
Bob Wilsond8931422014-04-11 17:16:13 +0000818 // Counter tracks the "true" part of a conditional operator. The
819 // count in the "false" part will be calculated from this counter.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000820 RegionCounter Cnt(PGO, E);
821 Visit(E->getCond());
822
823 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000824 CountMap[E->getTrueExpr()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000825 Visit(E->getTrueExpr());
826 Cnt.adjustForControlFlow();
827
828 Cnt.beginElseRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000829 CountMap[E->getFalseExpr()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000830 Visit(E->getFalseExpr());
831 Cnt.adjustForControlFlow();
832
833 Cnt.applyAdjustmentsToRegion(0);
834 RecordNextStmtCount = true;
835 }
836
837 void VisitBinLAnd(const BinaryOperator *E) {
838 RecordStmtCount(E);
Bob Wilsond8931422014-04-11 17:16:13 +0000839 // Counter tracks the right hand side of a logical and operator.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000840 RegionCounter Cnt(PGO, E);
841 Visit(E->getLHS());
842 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000843 CountMap[E->getRHS()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000844 Visit(E->getRHS());
845 Cnt.adjustForControlFlow();
846 Cnt.applyAdjustmentsToRegion(0);
847 RecordNextStmtCount = true;
848 }
849
850 void VisitBinLOr(const BinaryOperator *E) {
851 RecordStmtCount(E);
Bob Wilsond8931422014-04-11 17:16:13 +0000852 // Counter tracks the right hand side of a logical or operator.
Bob Wilsonbf854f02014-02-17 19:21:09 +0000853 RegionCounter Cnt(PGO, E);
854 Visit(E->getLHS());
855 Cnt.beginRegion();
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000856 CountMap[E->getRHS()] = PGO.getCurrentRegionCount();
Bob Wilsonbf854f02014-02-17 19:21:09 +0000857 Visit(E->getRHS());
858 Cnt.adjustForControlFlow();
859 Cnt.applyAdjustmentsToRegion(0);
860 RecordNextStmtCount = true;
861 }
862 };
Justin Bogneref512b92014-01-06 22:27:43 +0000863}
864
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000865void PGOHash::combine(HashType Type) {
866 // Check that we never combine 0 and only have six bits.
867 assert(Type && "Hash is invalid: unexpected type 0");
868 assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
869
870 // Pass through MD5 if enough work has built up.
871 if (Count && Count % NumTypesPerWord == 0) {
872 using namespace llvm::support;
873 uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
874 MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
875 Working = 0;
876 }
877
878 // Accumulate the current type.
879 ++Count;
880 Working = Working << NumBitsPerType | Type;
881}
882
883uint64_t PGOHash::finalize() {
884 // Use Working as the hash directly if we never used MD5.
885 if (Count <= NumTypesPerWord)
886 // No need to byte swap here, since none of the math was endian-dependent.
887 // This number will be byte-swapped as required on endianness transitions,
888 // so we will see the same value on the other side.
889 return Working;
890
891 // Check for remaining work in Working.
892 if (Working)
893 MD5.update(Working);
894
895 // Finalize the MD5 and return the hash.
896 llvm::MD5::MD5Result Result;
897 MD5.final(Result);
898 using namespace llvm::support;
899 return endian::read<uint64_t, little, unaligned>(Result);
900}
901
Duncan P. N. Exon Smithd971cd12014-03-28 17:53:22 +0000902static void emitRuntimeHook(CodeGenModule &CGM) {
Duncan P. N. Exon Smith3fefedb2014-04-11 00:43:16 +0000903 const char *const RuntimeVarName = "__llvm_profile_runtime";
904 const char *const RuntimeUserName = "__llvm_profile_runtime_user";
Duncan P. N. Exon Smithd971cd12014-03-28 17:53:22 +0000905 if (CGM.getModule().getGlobalVariable(RuntimeVarName))
906 return;
907
908 // Declare the runtime hook.
909 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
910 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
911 auto *Var = new llvm::GlobalVariable(CGM.getModule(), Int32Ty, false,
912 llvm::GlobalValue::ExternalLinkage,
913 nullptr, RuntimeVarName);
914
915 // Make a function that uses it.
916 auto *User = llvm::Function::Create(llvm::FunctionType::get(Int32Ty, false),
917 llvm::GlobalValue::LinkOnceODRLinkage,
918 RuntimeUserName, &CGM.getModule());
919 User->addFnAttr(llvm::Attribute::NoInline);
920 if (CGM.getCodeGenOpts().DisableRedZone)
921 User->addFnAttr(llvm::Attribute::NoRedZone);
922 CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", User));
923 auto *Load = Builder.CreateLoad(Var);
924 Builder.CreateRet(Load);
925
926 // Create a use of the function. Now the definition of the runtime variable
927 // should get pulled in, along with any static initializears.
928 CGM.addUsedGlobal(User);
929}
930
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000931void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
Justin Bogneref512b92014-01-06 22:27:43 +0000932 bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
Justin Bognerd66a17d2014-03-12 21:06:31 +0000933 PGOProfileData *PGOData = CGM.getPGOData();
934 if (!InstrumentRegions && !PGOData)
Justin Bogneref512b92014-01-06 22:27:43 +0000935 return;
Justin Bogneref512b92014-01-06 22:27:43 +0000936 if (!D)
937 return;
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000938 setFuncName(Fn);
Duncan P. N. Exon Smith7c414512014-03-20 22:50:08 +0000939
940 // Set the linkage for variables based on the function linkage. Usually, we
941 // want to match it, but available_externally and extern_weak both have the
942 // wrong semantics.
Duncan P. N. Exon Smith73f78622014-03-20 22:49:50 +0000943 VarLinkage = Fn->getLinkage();
Duncan P. N. Exon Smith7c414512014-03-20 22:50:08 +0000944 switch (VarLinkage) {
945 case llvm::GlobalValue::ExternalWeakLinkage:
946 VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;
947 break;
948 case llvm::GlobalValue::AvailableExternallyLinkage:
949 VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage;
950 break;
951 default:
952 break;
953 }
954
Justin Bogneref512b92014-01-06 22:27:43 +0000955 mapRegionCounters(D);
Duncan P. N. Exon Smithd971cd12014-03-28 17:53:22 +0000956 if (InstrumentRegions) {
957 emitRuntimeHook(CGM);
Justin Bogneref512b92014-01-06 22:27:43 +0000958 emitCounterVariables();
Duncan P. N. Exon Smithd971cd12014-03-28 17:53:22 +0000959 }
Justin Bognerd66a17d2014-03-12 21:06:31 +0000960 if (PGOData) {
961 loadRegionCounts(PGOData);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000962 computeRegionCounts(D);
Justin Bognerd66a17d2014-03-12 21:06:31 +0000963 applyFunctionAttributes(PGOData, Fn);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000964 }
Justin Bogneref512b92014-01-06 22:27:43 +0000965}
966
967void CodeGenPGO::mapRegionCounters(const Decl *D) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000968 RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000969 MapRegionCounters Walker(*RegionCounterMap);
Justin Bogneref512b92014-01-06 22:27:43 +0000970 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000971 Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000972 else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000973 Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
Bob Wilsonc845c002014-03-06 20:24:27 +0000974 else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
Bob Wilsond8931422014-04-11 17:16:13 +0000975 Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
Justin Bogner81ab90f2014-04-15 00:50:54 +0000976 else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
977 Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
Justin Bogneref512b92014-01-06 22:27:43 +0000978 NumRegionCounters = Walker.NextCounter;
Duncan P. N. Exon Smith4bc77312014-04-16 16:03:27 +0000979 FunctionHash = Walker.Hash.finalize();
Justin Bogneref512b92014-01-06 22:27:43 +0000980}
981
Bob Wilsonbf854f02014-02-17 19:21:09 +0000982void CodeGenPGO::computeRegionCounts(const Decl *D) {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +0000983 StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
Duncan P. N. Exon Smith3586be72014-03-26 19:26:02 +0000984 ComputeRegionCounts Walker(*StmtCountMap, *this);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000985 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
986 Walker.VisitFunctionDecl(FD);
Bob Wilson5ec8fe12014-03-06 06:10:02 +0000987 else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
988 Walker.VisitObjCMethodDecl(MD);
Bob Wilsonc845c002014-03-06 20:24:27 +0000989 else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
990 Walker.VisitBlockDecl(BD);
Justin Bogner81ab90f2014-04-15 00:50:54 +0000991 else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
992 Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
Bob Wilsonbf854f02014-02-17 19:21:09 +0000993}
994
Justin Bognerd66a17d2014-03-12 21:06:31 +0000995void CodeGenPGO::applyFunctionAttributes(PGOProfileData *PGOData,
Justin Bogner4c9c45c2014-03-12 18:14:32 +0000996 llvm::Function *Fn) {
997 if (!haveRegionCounts())
998 return;
999
Justin Bognerd66a17d2014-03-12 21:06:31 +00001000 uint64_t MaxFunctionCount = PGOData->getMaximumFunctionCount();
Justin Bogner4c9c45c2014-03-12 18:14:32 +00001001 uint64_t FunctionCount = getRegionCount(0);
1002 if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount))
1003 // Turn on InlineHint attribute for hot functions.
1004 // FIXME: 30% is from preliminary tuning on SPEC, it may not be optimal.
1005 Fn->addFnAttr(llvm::Attribute::InlineHint);
1006 else if (FunctionCount <= (uint64_t)(0.01 * (double)MaxFunctionCount))
1007 // Turn on Cold attribute for cold functions.
1008 // FIXME: 1% is from preliminary tuning on SPEC, it may not be optimal.
1009 Fn->addFnAttr(llvm::Attribute::Cold);
1010}
1011
Justin Bogneref512b92014-01-06 22:27:43 +00001012void CodeGenPGO::emitCounterVariables() {
1013 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
1014 llvm::ArrayType *CounterTy = llvm::ArrayType::get(llvm::Type::getInt64Ty(Ctx),
1015 NumRegionCounters);
1016 RegionCounters =
Duncan P. N. Exon Smith73f78622014-03-20 22:49:50 +00001017 new llvm::GlobalVariable(CGM.getModule(), CounterTy, false, VarLinkage,
Justin Bogneref512b92014-01-06 22:27:43 +00001018 llvm::Constant::getNullValue(CounterTy),
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +00001019 getFuncVarName("counters"));
1020 RegionCounters->setAlignment(8);
1021 RegionCounters->setSection(getCountersSection(CGM));
Justin Bogneref512b92014-01-06 22:27:43 +00001022}
1023
1024void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) {
Bob Wilson749ebc72014-03-06 04:55:28 +00001025 if (!RegionCounters)
Justin Bogneref512b92014-01-06 22:27:43 +00001026 return;
1027 llvm::Value *Addr =
1028 Builder.CreateConstInBoundsGEP2_64(RegionCounters, 0, Counter);
1029 llvm::Value *Count = Builder.CreateLoad(Addr, "pgocount");
1030 Count = Builder.CreateAdd(Count, Builder.getInt64(1));
1031 Builder.CreateStore(Count, Addr);
1032}
1033
Justin Bognerd66a17d2014-03-12 21:06:31 +00001034void CodeGenPGO::loadRegionCounts(PGOProfileData *PGOData) {
Justin Bognere2ef2a02014-04-15 21:22:35 +00001035 CGM.getPGOStats().Visited++;
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +00001036 RegionCounts.reset(new std::vector<uint64_t>);
Justin Bognerb4416f52014-03-18 21:58:06 +00001037 uint64_t Hash;
Justin Bognere2ef2a02014-04-15 21:22:35 +00001038 if (PGOData->getFunctionCounts(getFuncName(), Hash, *RegionCounts)) {
1039 CGM.getPGOStats().Missing++;
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +00001040 RegionCounts.reset();
Justin Bognere2ef2a02014-04-15 21:22:35 +00001041 } else if (Hash != FunctionHash ||
1042 RegionCounts->size() != NumRegionCounters) {
1043 CGM.getPGOStats().Mismatched++;
1044 RegionCounts.reset();
1045 }
Justin Bogneref512b92014-01-06 22:27:43 +00001046}
1047
1048void CodeGenPGO::destroyRegionCounters() {
Duncan P. N. Exon Smith1b67cfd2014-03-26 19:26:05 +00001049 RegionCounterMap.reset();
1050 StmtCountMap.reset();
1051 RegionCounts.reset();
Justin Bogneref512b92014-01-06 22:27:43 +00001052}
1053
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001054/// \brief Calculate what to divide by to scale weights.
1055///
1056/// Given the maximum weight, calculate a divisor that will scale all the
1057/// weights to strictly less than UINT32_MAX.
1058static uint64_t calculateWeightScale(uint64_t MaxWeight) {
1059 return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
1060}
1061
1062/// \brief Scale an individual branch weight (and add 1).
1063///
1064/// Scale a 64-bit weight down to 32-bits using \c Scale.
1065///
1066/// According to Laplace's Rule of Succession, it is better to compute the
1067/// weight based on the count plus 1, so universally add 1 to the value.
1068///
1069/// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
1070/// greater than \c Weight.
1071static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
1072 assert(Scale && "scale by 0?");
1073 uint64_t Scaled = Weight / Scale + 1;
1074 assert(Scaled <= UINT32_MAX && "overflow 32-bits");
1075 return Scaled;
1076}
1077
Justin Bogneref512b92014-01-06 22:27:43 +00001078llvm::MDNode *CodeGenPGO::createBranchWeights(uint64_t TrueCount,
1079 uint64_t FalseCount) {
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001080 // Check for empty weights.
Justin Bogneref512b92014-01-06 22:27:43 +00001081 if (!TrueCount && !FalseCount)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +00001082 return nullptr;
Justin Bogneref512b92014-01-06 22:27:43 +00001083
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001084 // Calculate how to scale down to 32-bits.
1085 uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
1086
Justin Bogneref512b92014-01-06 22:27:43 +00001087 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001088 return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
1089 scaleBranchWeight(FalseCount, Scale));
Justin Bogneref512b92014-01-06 22:27:43 +00001090}
1091
Bob Wilson95a27b02014-02-17 19:20:59 +00001092llvm::MDNode *CodeGenPGO::createBranchWeights(ArrayRef<uint64_t> Weights) {
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001093 // We need at least two elements to create meaningful weights.
1094 if (Weights.size() < 2)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +00001095 return nullptr;
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001096
Justin Bognerf3aefca2014-04-04 02:48:51 +00001097 // Check for empty weights.
1098 uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
1099 if (MaxWeight == 0)
1100 return nullptr;
1101
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001102 // Calculate how to scale down to 32-bits.
Justin Bognerf3aefca2014-04-04 02:48:51 +00001103 uint64_t Scale = calculateWeightScale(MaxWeight);
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001104
Justin Bogneref512b92014-01-06 22:27:43 +00001105 SmallVector<uint32_t, 16> ScaledWeights;
1106 ScaledWeights.reserve(Weights.size());
Duncan P. N. Exon Smith38402dc2014-03-11 18:18:10 +00001107 for (uint64_t W : Weights)
1108 ScaledWeights.push_back(scaleBranchWeight(W, Scale));
1109
1110 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
Justin Bogneref512b92014-01-06 22:27:43 +00001111 return MDHelper.createBranchWeights(ScaledWeights);
1112}
Bob Wilsonbf854f02014-02-17 19:21:09 +00001113
1114llvm::MDNode *CodeGenPGO::createLoopWeights(const Stmt *Cond,
1115 RegionCounter &Cnt) {
1116 if (!haveRegionCounts())
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +00001117 return nullptr;
Bob Wilsonbf854f02014-02-17 19:21:09 +00001118 uint64_t LoopCount = Cnt.getCount();
1119 uint64_t CondCount = 0;
1120 bool Found = getStmtCount(Cond, CondCount);
1121 assert(Found && "missing expected loop condition count");
1122 (void)Found;
1123 if (CondCount == 0)
Duncan P. N. Exon Smitha5f804a2014-03-20 18:40:55 +00001124 return nullptr;
Bob Wilsonbf854f02014-02-17 19:21:09 +00001125 return createBranchWeights(LoopCount,
1126 std::max(CondCount, LoopCount) - LoopCount);
1127}