1ef512b99SJustin Bogner //===--- CodeGenPGO.cpp - PGO Instrumentation for LLVM CodeGen --*- C++ -*-===//
2ef512b99SJustin Bogner //
3ef512b99SJustin Bogner //                     The LLVM Compiler Infrastructure
4ef512b99SJustin Bogner //
5ef512b99SJustin Bogner // This file is distributed under the University of Illinois Open Source
6ef512b99SJustin Bogner // License. See LICENSE.TXT for details.
7ef512b99SJustin Bogner //
8ef512b99SJustin Bogner //===----------------------------------------------------------------------===//
9ef512b99SJustin Bogner //
10ef512b99SJustin Bogner // Instrumentation-based profile-guided optimization
11ef512b99SJustin Bogner //
12ef512b99SJustin Bogner //===----------------------------------------------------------------------===//
13ef512b99SJustin Bogner 
14ef512b99SJustin Bogner #include "CodeGenPGO.h"
15ef512b99SJustin Bogner #include "CodeGenFunction.h"
16ef512b99SJustin Bogner #include "clang/AST/RecursiveASTVisitor.h"
17ef512b99SJustin Bogner #include "clang/AST/StmtVisitor.h"
18529f6dd8SJustin Bogner #include "llvm/Config/config.h" // for strtoull()/strtoll() define
19ef512b99SJustin Bogner #include "llvm/IR/MDBuilder.h"
20ef512b99SJustin Bogner #include "llvm/Support/FileSystem.h"
21ef512b99SJustin Bogner 
22ef512b99SJustin Bogner using namespace clang;
23ef512b99SJustin Bogner using namespace CodeGen;
24ef512b99SJustin Bogner 
25d66a17d0SJustin Bogner static void ReportBadPGOData(CodeGenModule &CGM, const char *Message) {
26d66a17d0SJustin Bogner   DiagnosticsEngine &Diags = CGM.getDiags();
27d66a17d0SJustin Bogner   unsigned diagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0");
28d66a17d0SJustin Bogner   Diags.Report(diagID) << Message;
29d66a17d0SJustin Bogner }
30d66a17d0SJustin Bogner 
31d66a17d0SJustin Bogner PGOProfileData::PGOProfileData(CodeGenModule &CGM, std::string Path)
32d66a17d0SJustin Bogner   : CGM(CGM) {
33d66a17d0SJustin Bogner   if (llvm::MemoryBuffer::getFile(Path, DataBuffer)) {
34d66a17d0SJustin Bogner     ReportBadPGOData(CGM, "failed to open pgo data file");
35d66a17d0SJustin Bogner     return;
36d66a17d0SJustin Bogner   }
37d66a17d0SJustin Bogner 
38d66a17d0SJustin Bogner   if (DataBuffer->getBufferSize() > std::numeric_limits<unsigned>::max()) {
39d66a17d0SJustin Bogner     ReportBadPGOData(CGM, "pgo data file too big");
40d66a17d0SJustin Bogner     return;
41d66a17d0SJustin Bogner   }
42d66a17d0SJustin Bogner 
43d66a17d0SJustin Bogner   // Scan through the data file and map each function to the corresponding
44d66a17d0SJustin Bogner   // file offset where its counts are stored.
45d66a17d0SJustin Bogner   const char *BufferStart = DataBuffer->getBufferStart();
46d66a17d0SJustin Bogner   const char *BufferEnd = DataBuffer->getBufferEnd();
47d66a17d0SJustin Bogner   const char *CurPtr = BufferStart;
48d66a17d0SJustin Bogner   uint64_t MaxCount = 0;
49d66a17d0SJustin Bogner   while (CurPtr < BufferEnd) {
50d66a17d0SJustin Bogner     // Read the function name.
51d66a17d0SJustin Bogner     const char *FuncStart = CurPtr;
52d66a17d0SJustin Bogner     // For Objective-C methods, the name may include whitespace, so search
53d66a17d0SJustin Bogner     // backward from the end of the line to find the space that separates the
54d66a17d0SJustin Bogner     // name from the number of counters. (This is a temporary hack since we are
55d66a17d0SJustin Bogner     // going to completely replace this file format in the near future.)
56d66a17d0SJustin Bogner     CurPtr = strchr(CurPtr, '\n');
57d66a17d0SJustin Bogner     if (!CurPtr) {
58d66a17d0SJustin Bogner       ReportBadPGOData(CGM, "pgo data file has malformed function entry");
59d66a17d0SJustin Bogner       return;
60d66a17d0SJustin Bogner     }
61d66a17d0SJustin Bogner     StringRef FuncName(FuncStart, CurPtr - FuncStart);
62d66a17d0SJustin Bogner 
63b4416f58SJustin Bogner     // Skip over the function hash.
64b4416f58SJustin Bogner     CurPtr = strchr(++CurPtr, '\n');
65b4416f58SJustin Bogner     if (!CurPtr) {
66b4416f58SJustin Bogner       ReportBadPGOData(CGM, "pgo data file is missing the function hash");
67b4416f58SJustin Bogner       return;
68b4416f58SJustin Bogner     }
69b4416f58SJustin Bogner 
70d66a17d0SJustin Bogner     // Read the number of counters.
71d66a17d0SJustin Bogner     char *EndPtr;
72d66a17d0SJustin Bogner     unsigned NumCounters = strtol(++CurPtr, &EndPtr, 10);
73d66a17d0SJustin Bogner     if (EndPtr == CurPtr || *EndPtr != '\n' || NumCounters <= 0) {
74d66a17d0SJustin Bogner       ReportBadPGOData(CGM, "pgo data file has unexpected number of counters");
75d66a17d0SJustin Bogner       return;
76d66a17d0SJustin Bogner     }
77d66a17d0SJustin Bogner     CurPtr = EndPtr;
78d66a17d0SJustin Bogner 
79d66a17d0SJustin Bogner     // Read function count.
80d66a17d0SJustin Bogner     uint64_t Count = strtoll(CurPtr, &EndPtr, 10);
81d66a17d0SJustin Bogner     if (EndPtr == CurPtr || *EndPtr != '\n') {
82d66a17d0SJustin Bogner       ReportBadPGOData(CGM, "pgo-data file has bad count value");
83d66a17d0SJustin Bogner       return;
84d66a17d0SJustin Bogner     }
85d66a17d0SJustin Bogner     CurPtr = EndPtr; // Point to '\n'.
86d66a17d0SJustin Bogner     FunctionCounts[FuncName] = Count;
87d66a17d0SJustin Bogner     MaxCount = Count > MaxCount ? Count : MaxCount;
88d66a17d0SJustin Bogner 
89d66a17d0SJustin Bogner     // There is one line for each counter; skip over those lines.
90d66a17d0SJustin Bogner     // Since function count is already read, we start the loop from 1.
91d66a17d0SJustin Bogner     for (unsigned N = 1; N < NumCounters; ++N) {
92d66a17d0SJustin Bogner       CurPtr = strchr(++CurPtr, '\n');
93d66a17d0SJustin Bogner       if (!CurPtr) {
94d66a17d0SJustin Bogner         ReportBadPGOData(CGM, "pgo data file is missing some counter info");
95d66a17d0SJustin Bogner         return;
96d66a17d0SJustin Bogner       }
97d66a17d0SJustin Bogner     }
98d66a17d0SJustin Bogner 
99d66a17d0SJustin Bogner     // Skip over the blank line separating functions.
100d66a17d0SJustin Bogner     CurPtr += 2;
101d66a17d0SJustin Bogner 
102d66a17d0SJustin Bogner     DataOffsets[FuncName] = FuncStart - BufferStart;
103d66a17d0SJustin Bogner   }
104d66a17d0SJustin Bogner   MaxFunctionCount = MaxCount;
105d66a17d0SJustin Bogner }
106d66a17d0SJustin Bogner 
107b4416f58SJustin Bogner bool PGOProfileData::getFunctionCounts(StringRef FuncName, uint64_t &FuncHash,
108d66a17d0SJustin Bogner                                        std::vector<uint64_t> &Counts) {
109d66a17d0SJustin Bogner   // Find the relevant section of the pgo-data file.
110d66a17d0SJustin Bogner   llvm::StringMap<unsigned>::const_iterator OffsetIter =
111d66a17d0SJustin Bogner     DataOffsets.find(FuncName);
112d66a17d0SJustin Bogner   if (OffsetIter == DataOffsets.end())
113d66a17d0SJustin Bogner     return true;
114d66a17d0SJustin Bogner   const char *CurPtr = DataBuffer->getBufferStart() + OffsetIter->getValue();
115d66a17d0SJustin Bogner 
116d66a17d0SJustin Bogner   // Skip over the function name.
117d66a17d0SJustin Bogner   CurPtr = strchr(CurPtr, '\n');
118d66a17d0SJustin Bogner   assert(CurPtr && "pgo-data has corrupted function entry");
119b4416f58SJustin Bogner 
120b4416f58SJustin Bogner   char *EndPtr;
121b4416f58SJustin Bogner   // Read the function hash.
122b4416f58SJustin Bogner   FuncHash = strtoll(++CurPtr, &EndPtr, 10);
123b4416f58SJustin Bogner   assert(EndPtr != CurPtr && *EndPtr == '\n' &&
124b4416f58SJustin Bogner          "pgo-data file has corrupted function hash");
125b4416f58SJustin Bogner   CurPtr = EndPtr;
126d66a17d0SJustin Bogner 
127d66a17d0SJustin Bogner   // Read the number of counters.
128d66a17d0SJustin Bogner   unsigned NumCounters = strtol(++CurPtr, &EndPtr, 10);
129d66a17d0SJustin Bogner   assert(EndPtr != CurPtr && *EndPtr == '\n' && NumCounters > 0 &&
130d66a17d0SJustin Bogner          "pgo-data file has corrupted number of counters");
131d66a17d0SJustin Bogner   CurPtr = EndPtr;
132d66a17d0SJustin Bogner 
133d66a17d0SJustin Bogner   Counts.reserve(NumCounters);
134d66a17d0SJustin Bogner 
135d66a17d0SJustin Bogner   for (unsigned N = 0; N < NumCounters; ++N) {
136d66a17d0SJustin Bogner     // Read the count value.
137d66a17d0SJustin Bogner     uint64_t Count = strtoll(CurPtr, &EndPtr, 10);
138d66a17d0SJustin Bogner     if (EndPtr == CurPtr || *EndPtr != '\n') {
139d66a17d0SJustin Bogner       ReportBadPGOData(CGM, "pgo-data file has bad count value");
140d66a17d0SJustin Bogner       return true;
141d66a17d0SJustin Bogner     }
142d66a17d0SJustin Bogner     Counts.push_back(Count);
143d66a17d0SJustin Bogner     CurPtr = EndPtr + 1;
144d66a17d0SJustin Bogner   }
145d66a17d0SJustin Bogner 
146d66a17d0SJustin Bogner   // Make sure the number of counters matches up.
147d66a17d0SJustin Bogner   if (Counts.size() != NumCounters) {
148d66a17d0SJustin Bogner     ReportBadPGOData(CGM, "pgo-data file has inconsistent counters");
149d66a17d0SJustin Bogner     return true;
150d66a17d0SJustin Bogner   }
151d66a17d0SJustin Bogner 
152d66a17d0SJustin Bogner   return false;
153d66a17d0SJustin Bogner }
154d66a17d0SJustin Bogner 
155da1ebedeSBob Wilson void CodeGenPGO::setFuncName(llvm::Function *Fn) {
1562fe531cbSDuncan P. N. Exon Smith   RawFuncName = Fn->getName();
157da1ebedeSBob Wilson 
158da1ebedeSBob Wilson   // Function names may be prefixed with a binary '1' to indicate
159da1ebedeSBob Wilson   // that the backend should not modify the symbols due to any platform
160da1ebedeSBob Wilson   // naming convention. Do not include that '1' in the PGO profile name.
1612fe531cbSDuncan P. N. Exon Smith   if (RawFuncName[0] == '\1')
1622fe531cbSDuncan P. N. Exon Smith     RawFuncName = RawFuncName.substr(1);
163da1ebedeSBob Wilson 
164da1ebedeSBob Wilson   if (!Fn->hasLocalLinkage()) {
1651b67cfd4SDuncan P. N. Exon Smith     PrefixedFuncName.reset(new std::string(RawFuncName));
166da1ebedeSBob Wilson     return;
167da1ebedeSBob Wilson   }
168da1ebedeSBob Wilson 
169da1ebedeSBob Wilson   // For local symbols, prepend the main file name to distinguish them.
170da1ebedeSBob Wilson   // Do not include the full path in the file name since there's no guarantee
171da1ebedeSBob Wilson   // that it will stay the same, e.g., if the files are checked out from
172da1ebedeSBob Wilson   // version control in different locations.
1731b67cfd4SDuncan P. N. Exon Smith   PrefixedFuncName.reset(new std::string(CGM.getCodeGenOpts().MainFileName));
1742fe531cbSDuncan P. N. Exon Smith   if (PrefixedFuncName->empty())
1752fe531cbSDuncan P. N. Exon Smith     PrefixedFuncName->assign("<unknown>");
1762fe531cbSDuncan P. N. Exon Smith   PrefixedFuncName->append(":");
1772fe531cbSDuncan P. N. Exon Smith   PrefixedFuncName->append(RawFuncName);
178da1ebedeSBob Wilson }
179da1ebedeSBob Wilson 
1802fe531cbSDuncan P. N. Exon Smith static llvm::Function *getRegisterFunc(CodeGenModule &CGM) {
181a7807637SDuncan P. N. Exon Smith   return CGM.getModule().getFunction("__llvm_profile_register_functions");
1822fe531cbSDuncan P. N. Exon Smith }
1832fe531cbSDuncan P. N. Exon Smith 
1842fe531cbSDuncan P. N. Exon Smith static llvm::BasicBlock *getOrInsertRegisterBB(CodeGenModule &CGM) {
185780443e8SDuncan P. N. Exon Smith   // Don't do this for Darwin.  compiler-rt uses linker magic.
186780443e8SDuncan P. N. Exon Smith   if (CGM.getTarget().getTriple().isOSDarwin())
187780443e8SDuncan P. N. Exon Smith     return nullptr;
188780443e8SDuncan P. N. Exon Smith 
1892fe531cbSDuncan P. N. Exon Smith   // Only need to insert this once per module.
1902fe531cbSDuncan P. N. Exon Smith   if (llvm::Function *RegisterF = getRegisterFunc(CGM))
1912fe531cbSDuncan P. N. Exon Smith     return &RegisterF->getEntryBlock();
1922fe531cbSDuncan P. N. Exon Smith 
1932fe531cbSDuncan P. N. Exon Smith   // Construct the function.
1942fe531cbSDuncan P. N. Exon Smith   auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
1952fe531cbSDuncan P. N. Exon Smith   auto *RegisterFTy = llvm::FunctionType::get(VoidTy, false);
1962fe531cbSDuncan P. N. Exon Smith   auto *RegisterF = llvm::Function::Create(RegisterFTy,
1972fe531cbSDuncan P. N. Exon Smith                                            llvm::GlobalValue::InternalLinkage,
198a7807637SDuncan P. N. Exon Smith                                            "__llvm_profile_register_functions",
1992fe531cbSDuncan P. N. Exon Smith                                            &CGM.getModule());
2002fe531cbSDuncan P. N. Exon Smith   RegisterF->setUnnamedAddr(true);
2012fe531cbSDuncan P. N. Exon Smith   if (CGM.getCodeGenOpts().DisableRedZone)
2022fe531cbSDuncan P. N. Exon Smith     RegisterF->addFnAttr(llvm::Attribute::NoRedZone);
2032fe531cbSDuncan P. N. Exon Smith 
2042fe531cbSDuncan P. N. Exon Smith   // Construct and return the entry block.
2052fe531cbSDuncan P. N. Exon Smith   auto *BB = llvm::BasicBlock::Create(CGM.getLLVMContext(), "", RegisterF);
2062fe531cbSDuncan P. N. Exon Smith   CGBuilderTy Builder(BB);
2072fe531cbSDuncan P. N. Exon Smith   Builder.CreateRetVoid();
2082fe531cbSDuncan P. N. Exon Smith   return BB;
2092fe531cbSDuncan P. N. Exon Smith }
2102fe531cbSDuncan P. N. Exon Smith 
2112fe531cbSDuncan P. N. Exon Smith static llvm::Constant *getOrInsertRuntimeRegister(CodeGenModule &CGM) {
2122fe531cbSDuncan P. N. Exon Smith   auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
2132fe531cbSDuncan P. N. Exon Smith   auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
2142fe531cbSDuncan P. N. Exon Smith   auto *RuntimeRegisterTy = llvm::FunctionType::get(VoidTy, VoidPtrTy, false);
215a7807637SDuncan P. N. Exon Smith   return CGM.getModule().getOrInsertFunction("__llvm_profile_register_function",
2162fe531cbSDuncan P. N. Exon Smith                                              RuntimeRegisterTy);
2172fe531cbSDuncan P. N. Exon Smith }
2182fe531cbSDuncan P. N. Exon Smith 
2197134d47dSDuncan P. N. Exon Smith static bool isMachO(const CodeGenModule &CGM) {
2207134d47dSDuncan P. N. Exon Smith   return CGM.getTarget().getTriple().isOSBinFormatMachO();
2217134d47dSDuncan P. N. Exon Smith }
2227134d47dSDuncan P. N. Exon Smith 
2232fe531cbSDuncan P. N. Exon Smith static StringRef getCountersSection(const CodeGenModule &CGM) {
224a7807637SDuncan P. N. Exon Smith   return isMachO(CGM) ? "__DATA,__llvm_prf_cnts" : "__llvm_prf_cnts";
2252fe531cbSDuncan P. N. Exon Smith }
2262fe531cbSDuncan P. N. Exon Smith 
2272fe531cbSDuncan P. N. Exon Smith static StringRef getNameSection(const CodeGenModule &CGM) {
228a7807637SDuncan P. N. Exon Smith   return isMachO(CGM) ? "__DATA,__llvm_prf_names" : "__llvm_prf_names";
2292fe531cbSDuncan P. N. Exon Smith }
2302fe531cbSDuncan P. N. Exon Smith 
2312fe531cbSDuncan P. N. Exon Smith static StringRef getDataSection(const CodeGenModule &CGM) {
232a7807637SDuncan P. N. Exon Smith   return isMachO(CGM) ? "__DATA,__llvm_prf_data" : "__llvm_prf_data";
2332fe531cbSDuncan P. N. Exon Smith }
2342fe531cbSDuncan P. N. Exon Smith 
2352fe531cbSDuncan P. N. Exon Smith llvm::GlobalVariable *CodeGenPGO::buildDataVar() {
2362fe531cbSDuncan P. N. Exon Smith   // Create name variable.
2372fe531cbSDuncan P. N. Exon Smith   llvm::LLVMContext &Ctx = CGM.getLLVMContext();
2382fe531cbSDuncan P. N. Exon Smith   auto *VarName = llvm::ConstantDataArray::getString(Ctx, getFuncName(),
2392fe531cbSDuncan P. N. Exon Smith                                                      false);
2402fe531cbSDuncan P. N. Exon Smith   auto *Name = new llvm::GlobalVariable(CGM.getModule(), VarName->getType(),
24173f78627SDuncan P. N. Exon Smith                                         true, VarLinkage, VarName,
2422fe531cbSDuncan P. N. Exon Smith                                         getFuncVarName("name"));
2432fe531cbSDuncan P. N. Exon Smith   Name->setSection(getNameSection(CGM));
2442fe531cbSDuncan P. N. Exon Smith   Name->setAlignment(1);
2452fe531cbSDuncan P. N. Exon Smith 
2462fe531cbSDuncan P. N. Exon Smith   // Create data variable.
2472fe531cbSDuncan P. N. Exon Smith   auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
248b4416f58SJustin Bogner   auto *Int64Ty = llvm::Type::getInt64Ty(Ctx);
2492fe531cbSDuncan P. N. Exon Smith   auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
2502fe531cbSDuncan P. N. Exon Smith   auto *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);
2512fe531cbSDuncan P. N. Exon Smith   llvm::Type *DataTypes[] = {
252b4416f58SJustin Bogner     Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy
2532fe531cbSDuncan P. N. Exon Smith   };
2542fe531cbSDuncan P. N. Exon Smith   auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes));
2552fe531cbSDuncan P. N. Exon Smith   llvm::Constant *DataVals[] = {
2562fe531cbSDuncan P. N. Exon Smith     llvm::ConstantInt::get(Int32Ty, getFuncName().size()),
2572fe531cbSDuncan P. N. Exon Smith     llvm::ConstantInt::get(Int32Ty, NumRegionCounters),
258b4416f58SJustin Bogner     llvm::ConstantInt::get(Int64Ty, FunctionHash),
2592fe531cbSDuncan P. N. Exon Smith     llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),
2602fe531cbSDuncan P. N. Exon Smith     llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)
2612fe531cbSDuncan P. N. Exon Smith   };
2622fe531cbSDuncan P. N. Exon Smith   auto *Data =
26373f78627SDuncan P. N. Exon Smith     new llvm::GlobalVariable(CGM.getModule(), DataTy, true, VarLinkage,
2642fe531cbSDuncan P. N. Exon Smith                              llvm::ConstantStruct::get(DataTy, DataVals),
2652fe531cbSDuncan P. N. Exon Smith                              getFuncVarName("data"));
2662fe531cbSDuncan P. N. Exon Smith 
2672fe531cbSDuncan P. N. Exon Smith   // All the data should be packed into an array in its own section.
2682fe531cbSDuncan P. N. Exon Smith   Data->setSection(getDataSection(CGM));
2692fe531cbSDuncan P. N. Exon Smith   Data->setAlignment(8);
2702fe531cbSDuncan P. N. Exon Smith 
2712fe531cbSDuncan P. N. Exon Smith   // Make sure the data doesn't get deleted.
2722fe531cbSDuncan P. N. Exon Smith   CGM.addUsedGlobal(Data);
2732fe531cbSDuncan P. N. Exon Smith   return Data;
2742fe531cbSDuncan P. N. Exon Smith }
2752fe531cbSDuncan P. N. Exon Smith 
2762fe531cbSDuncan P. N. Exon Smith void CodeGenPGO::emitInstrumentationData() {
277ef512b99SJustin Bogner   if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
278ef512b99SJustin Bogner     return;
279ef512b99SJustin Bogner 
2802fe531cbSDuncan P. N. Exon Smith   // Build the data.
2812fe531cbSDuncan P. N. Exon Smith   auto *Data = buildDataVar();
282ef512b99SJustin Bogner 
2832fe531cbSDuncan P. N. Exon Smith   // Register the data.
284780443e8SDuncan P. N. Exon Smith   auto *RegisterBB = getOrInsertRegisterBB(CGM);
285780443e8SDuncan P. N. Exon Smith   if (!RegisterBB)
286780443e8SDuncan P. N. Exon Smith     return;
287780443e8SDuncan P. N. Exon Smith   CGBuilderTy Builder(RegisterBB->getTerminator());
2882fe531cbSDuncan P. N. Exon Smith   auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
2892fe531cbSDuncan P. N. Exon Smith   Builder.CreateCall(getOrInsertRuntimeRegister(CGM),
2902fe531cbSDuncan P. N. Exon Smith                      Builder.CreateBitCast(Data, VoidPtrTy));
291ef512b99SJustin Bogner }
292ef512b99SJustin Bogner 
293ef512b99SJustin Bogner llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) {
2942fe531cbSDuncan P. N. Exon Smith   if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
295a5f804a7SDuncan P. N. Exon Smith     return nullptr;
296ef512b99SJustin Bogner 
297*f2ea775eSJustin Bogner   assert(CGM.getModule().getFunction("__llvm_profile_init") == nullptr &&
298*f2ea775eSJustin Bogner          "profile initialization already emitted");
299ef512b99SJustin Bogner 
3005188e91cSDuncan P. N. Exon Smith   // Get the function to call at initialization.
3012fe531cbSDuncan P. N. Exon Smith   llvm::Constant *RegisterF = getRegisterFunc(CGM);
3025188e91cSDuncan P. N. Exon Smith   if (!RegisterF)
303a5f804a7SDuncan P. N. Exon Smith     return nullptr;
3042fe531cbSDuncan P. N. Exon Smith 
3052fe531cbSDuncan P. N. Exon Smith   // Create the initialization function.
3062fe531cbSDuncan P. N. Exon Smith   auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
3072fe531cbSDuncan P. N. Exon Smith   auto *F = llvm::Function::Create(llvm::FunctionType::get(VoidTy, false),
3082fe531cbSDuncan P. N. Exon Smith                                    llvm::GlobalValue::InternalLinkage,
309a7807637SDuncan P. N. Exon Smith                                    "__llvm_profile_init", &CGM.getModule());
310ef512b99SJustin Bogner   F->setUnnamedAddr(true);
311ef512b99SJustin Bogner   F->addFnAttr(llvm::Attribute::NoInline);
312ef512b99SJustin Bogner   if (CGM.getCodeGenOpts().DisableRedZone)
313ef512b99SJustin Bogner     F->addFnAttr(llvm::Attribute::NoRedZone);
314ef512b99SJustin Bogner 
3152fe531cbSDuncan P. N. Exon Smith   // Add the basic block and the necessary calls.
3162fe531cbSDuncan P. N. Exon Smith   CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", F));
3172fe531cbSDuncan P. N. Exon Smith   Builder.CreateCall(RegisterF);
3182fe531cbSDuncan P. N. Exon Smith   Builder.CreateRetVoid();
319ef512b99SJustin Bogner 
320ef512b99SJustin Bogner   return F;
321ef512b99SJustin Bogner }
322ef512b99SJustin Bogner 
323ef512b99SJustin Bogner namespace {
324ef512b99SJustin Bogner   /// A StmtVisitor that fills a map of statements to PGO counters.
325ef512b99SJustin Bogner   struct MapRegionCounters : public ConstStmtVisitor<MapRegionCounters> {
326ef512b99SJustin Bogner     /// The next counter value to assign.
327ef512b99SJustin Bogner     unsigned NextCounter;
328ef512b99SJustin Bogner     /// The map of statements to counters.
3293586be72SDuncan P. N. Exon Smith     llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
330ef512b99SJustin Bogner 
3313586be72SDuncan P. N. Exon Smith     MapRegionCounters(llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
3323586be72SDuncan P. N. Exon Smith         : NextCounter(0), CounterMap(CounterMap) {}
333ef512b99SJustin Bogner 
334ef512b99SJustin Bogner     void VisitChildren(const Stmt *S) {
335ef512b99SJustin Bogner       for (Stmt::const_child_range I = S->children(); I; ++I)
336ef512b99SJustin Bogner         if (*I)
337ef512b99SJustin Bogner          this->Visit(*I);
338ef512b99SJustin Bogner     }
339ef512b99SJustin Bogner     void VisitStmt(const Stmt *S) { VisitChildren(S); }
340ef512b99SJustin Bogner 
341ea278c32SJustin Bogner     /// Assign a counter to track entry to the function body.
342ef512b99SJustin Bogner     void VisitFunctionDecl(const FunctionDecl *S) {
3433586be72SDuncan P. N. Exon Smith       CounterMap[S->getBody()] = NextCounter++;
344ef512b99SJustin Bogner       Visit(S->getBody());
345ef512b99SJustin Bogner     }
3465ec8fe19SBob Wilson     void VisitObjCMethodDecl(const ObjCMethodDecl *S) {
3473586be72SDuncan P. N. Exon Smith       CounterMap[S->getBody()] = NextCounter++;
3485ec8fe19SBob Wilson       Visit(S->getBody());
3495ec8fe19SBob Wilson     }
350c845c00aSBob Wilson     void VisitBlockDecl(const BlockDecl *S) {
3513586be72SDuncan P. N. Exon Smith       CounterMap[S->getBody()] = NextCounter++;
352c845c00aSBob Wilson       Visit(S->getBody());
353c845c00aSBob Wilson     }
354ea278c32SJustin Bogner     /// Assign a counter to track the block following a label.
355ef512b99SJustin Bogner     void VisitLabelStmt(const LabelStmt *S) {
3563586be72SDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
357ef512b99SJustin Bogner       Visit(S->getSubStmt());
358ef512b99SJustin Bogner     }
359bf854f0fSBob Wilson     /// Assign a counter for the body of a while loop.
360ef512b99SJustin Bogner     void VisitWhileStmt(const WhileStmt *S) {
3613586be72SDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
362ef512b99SJustin Bogner       Visit(S->getCond());
363ef512b99SJustin Bogner       Visit(S->getBody());
364ef512b99SJustin Bogner     }
365bf854f0fSBob Wilson     /// Assign a counter for the body of a do-while loop.
366ef512b99SJustin Bogner     void VisitDoStmt(const DoStmt *S) {
3673586be72SDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
368ef512b99SJustin Bogner       Visit(S->getBody());
369ef512b99SJustin Bogner       Visit(S->getCond());
370ef512b99SJustin Bogner     }
371bf854f0fSBob Wilson     /// Assign a counter for the body of a for loop.
372ef512b99SJustin Bogner     void VisitForStmt(const ForStmt *S) {
3733586be72SDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
374bf854f0fSBob Wilson       if (S->getInit())
375bf854f0fSBob Wilson         Visit(S->getInit());
376ef512b99SJustin Bogner       const Expr *E;
377ef512b99SJustin Bogner       if ((E = S->getCond()))
378ef512b99SJustin Bogner         Visit(E);
379ef512b99SJustin Bogner       if ((E = S->getInc()))
380ef512b99SJustin Bogner         Visit(E);
381bf854f0fSBob Wilson       Visit(S->getBody());
382ef512b99SJustin Bogner     }
383bf854f0fSBob Wilson     /// Assign a counter for the body of a for-range loop.
384ef512b99SJustin Bogner     void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
3853586be72SDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
386bf854f0fSBob Wilson       Visit(S->getRangeStmt());
387bf854f0fSBob Wilson       Visit(S->getBeginEndStmt());
388bf854f0fSBob Wilson       Visit(S->getCond());
389bf854f0fSBob Wilson       Visit(S->getLoopVarStmt());
390ef512b99SJustin Bogner       Visit(S->getBody());
391bf854f0fSBob Wilson       Visit(S->getInc());
392ef512b99SJustin Bogner     }
393bf854f0fSBob Wilson     /// Assign a counter for the body of a for-collection loop.
394ef512b99SJustin Bogner     void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
3953586be72SDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
396ef512b99SJustin Bogner       Visit(S->getElement());
397ef512b99SJustin Bogner       Visit(S->getBody());
398ef512b99SJustin Bogner     }
399ef512b99SJustin Bogner     /// Assign a counter for the exit block of the switch statement.
400ef512b99SJustin Bogner     void VisitSwitchStmt(const SwitchStmt *S) {
4013586be72SDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
402ef512b99SJustin Bogner       Visit(S->getCond());
403ef512b99SJustin Bogner       Visit(S->getBody());
404ef512b99SJustin Bogner     }
405ef512b99SJustin Bogner     /// Assign a counter for a particular case in a switch. This counts jumps
406ef512b99SJustin Bogner     /// from the switch header as well as fallthrough from the case before this
407ef512b99SJustin Bogner     /// one.
408ef512b99SJustin Bogner     void VisitCaseStmt(const CaseStmt *S) {
4093586be72SDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
410ef512b99SJustin Bogner       Visit(S->getSubStmt());
411ef512b99SJustin Bogner     }
412ef512b99SJustin Bogner     /// Assign a counter for the default case of a switch statement. The count
413ef512b99SJustin Bogner     /// is the number of branches from the loop header to the default, and does
414ef512b99SJustin Bogner     /// not include fallthrough from previous cases. If we have multiple
415ef512b99SJustin Bogner     /// conditional branch blocks from the switch instruction to the default
416ef512b99SJustin Bogner     /// block, as with large GNU case ranges, this is the counter for the last
417ef512b99SJustin Bogner     /// edge in that series, rather than the first.
418ef512b99SJustin Bogner     void VisitDefaultStmt(const DefaultStmt *S) {
4193586be72SDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
420ef512b99SJustin Bogner       Visit(S->getSubStmt());
421ef512b99SJustin Bogner     }
422ef512b99SJustin Bogner     /// Assign a counter for the "then" part of an if statement. The count for
423ef512b99SJustin Bogner     /// the "else" part, if it exists, will be calculated from this counter.
424ef512b99SJustin Bogner     void VisitIfStmt(const IfStmt *S) {
4253586be72SDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
426ef512b99SJustin Bogner       Visit(S->getCond());
427ef512b99SJustin Bogner       Visit(S->getThen());
428ef512b99SJustin Bogner       if (S->getElse())
429ef512b99SJustin Bogner         Visit(S->getElse());
430ef512b99SJustin Bogner     }
431ef512b99SJustin Bogner     /// Assign a counter for the continuation block of a C++ try statement.
432ef512b99SJustin Bogner     void VisitCXXTryStmt(const CXXTryStmt *S) {
4333586be72SDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
434ef512b99SJustin Bogner       Visit(S->getTryBlock());
435ef512b99SJustin Bogner       for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
436ef512b99SJustin Bogner         Visit(S->getHandler(I));
437ef512b99SJustin Bogner     }
438ef512b99SJustin Bogner     /// Assign a counter for a catch statement's handler block.
439ef512b99SJustin Bogner     void VisitCXXCatchStmt(const CXXCatchStmt *S) {
4403586be72SDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
441ef512b99SJustin Bogner       Visit(S->getHandlerBlock());
442ef512b99SJustin Bogner     }
443ef512b99SJustin Bogner     /// Assign a counter for the "true" part of a conditional operator. The
444ef512b99SJustin Bogner     /// count in the "false" part will be calculated from this counter.
445ef512b99SJustin Bogner     void VisitConditionalOperator(const ConditionalOperator *E) {
4463586be72SDuncan P. N. Exon Smith       CounterMap[E] = NextCounter++;
447ef512b99SJustin Bogner       Visit(E->getCond());
448ef512b99SJustin Bogner       Visit(E->getTrueExpr());
449ef512b99SJustin Bogner       Visit(E->getFalseExpr());
450ef512b99SJustin Bogner     }
451ef512b99SJustin Bogner     /// Assign a counter for the right hand side of a logical and operator.
452ef512b99SJustin Bogner     void VisitBinLAnd(const BinaryOperator *E) {
4533586be72SDuncan P. N. Exon Smith       CounterMap[E] = NextCounter++;
454ef512b99SJustin Bogner       Visit(E->getLHS());
455ef512b99SJustin Bogner       Visit(E->getRHS());
456ef512b99SJustin Bogner     }
457ef512b99SJustin Bogner     /// Assign a counter for the right hand side of a logical or operator.
458ef512b99SJustin Bogner     void VisitBinLOr(const BinaryOperator *E) {
4593586be72SDuncan P. N. Exon Smith       CounterMap[E] = NextCounter++;
460ef512b99SJustin Bogner       Visit(E->getLHS());
461ef512b99SJustin Bogner       Visit(E->getRHS());
462ef512b99SJustin Bogner     }
463ef512b99SJustin Bogner   };
464bf854f0fSBob Wilson 
465bf854f0fSBob Wilson   /// A StmtVisitor that propagates the raw counts through the AST and
466bf854f0fSBob Wilson   /// records the count at statements where the value may change.
467bf854f0fSBob Wilson   struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
468bf854f0fSBob Wilson     /// PGO state.
469bf854f0fSBob Wilson     CodeGenPGO &PGO;
470bf854f0fSBob Wilson 
471bf854f0fSBob Wilson     /// A flag that is set when the current count should be recorded on the
472bf854f0fSBob Wilson     /// next statement, such as at the exit of a loop.
473bf854f0fSBob Wilson     bool RecordNextStmtCount;
474bf854f0fSBob Wilson 
475bf854f0fSBob Wilson     /// The map of statements to count values.
4763586be72SDuncan P. N. Exon Smith     llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
477bf854f0fSBob Wilson 
478bf854f0fSBob Wilson     /// BreakContinueStack - Keep counts of breaks and continues inside loops.
479bf854f0fSBob Wilson     struct BreakContinue {
480bf854f0fSBob Wilson       uint64_t BreakCount;
481bf854f0fSBob Wilson       uint64_t ContinueCount;
482bf854f0fSBob Wilson       BreakContinue() : BreakCount(0), ContinueCount(0) {}
483bf854f0fSBob Wilson     };
484bf854f0fSBob Wilson     SmallVector<BreakContinue, 8> BreakContinueStack;
485bf854f0fSBob Wilson 
4863586be72SDuncan P. N. Exon Smith     ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
4873586be72SDuncan P. N. Exon Smith                         CodeGenPGO &PGO)
4883586be72SDuncan P. N. Exon Smith         : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
489bf854f0fSBob Wilson 
490bf854f0fSBob Wilson     void RecordStmtCount(const Stmt *S) {
491bf854f0fSBob Wilson       if (RecordNextStmtCount) {
4923586be72SDuncan P. N. Exon Smith         CountMap[S] = PGO.getCurrentRegionCount();
493bf854f0fSBob Wilson         RecordNextStmtCount = false;
494bf854f0fSBob Wilson       }
495bf854f0fSBob Wilson     }
496bf854f0fSBob Wilson 
497bf854f0fSBob Wilson     void VisitStmt(const Stmt *S) {
498bf854f0fSBob Wilson       RecordStmtCount(S);
499bf854f0fSBob Wilson       for (Stmt::const_child_range I = S->children(); I; ++I) {
500bf854f0fSBob Wilson         if (*I)
501bf854f0fSBob Wilson          this->Visit(*I);
502bf854f0fSBob Wilson       }
503bf854f0fSBob Wilson     }
504bf854f0fSBob Wilson 
505bf854f0fSBob Wilson     void VisitFunctionDecl(const FunctionDecl *S) {
506bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S->getBody());
507bf854f0fSBob Wilson       Cnt.beginRegion();
5083586be72SDuncan P. N. Exon Smith       CountMap[S->getBody()] = PGO.getCurrentRegionCount();
509bf854f0fSBob Wilson       Visit(S->getBody());
510bf854f0fSBob Wilson     }
511bf854f0fSBob Wilson 
5125ec8fe19SBob Wilson     void VisitObjCMethodDecl(const ObjCMethodDecl *S) {
5135ec8fe19SBob Wilson       RegionCounter Cnt(PGO, S->getBody());
5145ec8fe19SBob Wilson       Cnt.beginRegion();
5153586be72SDuncan P. N. Exon Smith       CountMap[S->getBody()] = PGO.getCurrentRegionCount();
5165ec8fe19SBob Wilson       Visit(S->getBody());
5175ec8fe19SBob Wilson     }
5185ec8fe19SBob Wilson 
519c845c00aSBob Wilson     void VisitBlockDecl(const BlockDecl *S) {
520c845c00aSBob Wilson       RegionCounter Cnt(PGO, S->getBody());
521c845c00aSBob Wilson       Cnt.beginRegion();
5223586be72SDuncan P. N. Exon Smith       CountMap[S->getBody()] = PGO.getCurrentRegionCount();
523c845c00aSBob Wilson       Visit(S->getBody());
524c845c00aSBob Wilson     }
525c845c00aSBob Wilson 
526bf854f0fSBob Wilson     void VisitReturnStmt(const ReturnStmt *S) {
527bf854f0fSBob Wilson       RecordStmtCount(S);
528bf854f0fSBob Wilson       if (S->getRetValue())
529bf854f0fSBob Wilson         Visit(S->getRetValue());
530bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
531bf854f0fSBob Wilson       RecordNextStmtCount = true;
532bf854f0fSBob Wilson     }
533bf854f0fSBob Wilson 
534bf854f0fSBob Wilson     void VisitGotoStmt(const GotoStmt *S) {
535bf854f0fSBob Wilson       RecordStmtCount(S);
536bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
537bf854f0fSBob Wilson       RecordNextStmtCount = true;
538bf854f0fSBob Wilson     }
539bf854f0fSBob Wilson 
540bf854f0fSBob Wilson     void VisitLabelStmt(const LabelStmt *S) {
541bf854f0fSBob Wilson       RecordNextStmtCount = false;
542bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
543bf854f0fSBob Wilson       Cnt.beginRegion();
5443586be72SDuncan P. N. Exon Smith       CountMap[S] = PGO.getCurrentRegionCount();
545bf854f0fSBob Wilson       Visit(S->getSubStmt());
546bf854f0fSBob Wilson     }
547bf854f0fSBob Wilson 
548bf854f0fSBob Wilson     void VisitBreakStmt(const BreakStmt *S) {
549bf854f0fSBob Wilson       RecordStmtCount(S);
550bf854f0fSBob Wilson       assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
551bf854f0fSBob Wilson       BreakContinueStack.back().BreakCount += PGO.getCurrentRegionCount();
552bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
553bf854f0fSBob Wilson       RecordNextStmtCount = true;
554bf854f0fSBob Wilson     }
555bf854f0fSBob Wilson 
556bf854f0fSBob Wilson     void VisitContinueStmt(const ContinueStmt *S) {
557bf854f0fSBob Wilson       RecordStmtCount(S);
558bf854f0fSBob Wilson       assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
559bf854f0fSBob Wilson       BreakContinueStack.back().ContinueCount += PGO.getCurrentRegionCount();
560bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
561bf854f0fSBob Wilson       RecordNextStmtCount = true;
562bf854f0fSBob Wilson     }
563bf854f0fSBob Wilson 
564bf854f0fSBob Wilson     void VisitWhileStmt(const WhileStmt *S) {
565bf854f0fSBob Wilson       RecordStmtCount(S);
566bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
567bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
568bf854f0fSBob Wilson       // Visit the body region first so the break/continue adjustments can be
569bf854f0fSBob Wilson       // included when visiting the condition.
570bf854f0fSBob Wilson       Cnt.beginRegion();
5713586be72SDuncan P. N. Exon Smith       CountMap[S->getBody()] = PGO.getCurrentRegionCount();
572bf854f0fSBob Wilson       Visit(S->getBody());
573bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
574bf854f0fSBob Wilson 
575bf854f0fSBob Wilson       // ...then go back and propagate counts through the condition. The count
576bf854f0fSBob Wilson       // at the start of the condition is the sum of the incoming edges,
577bf854f0fSBob Wilson       // the backedge from the end of the loop body, and the edges from
578bf854f0fSBob Wilson       // continue statements.
579bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
580bf854f0fSBob Wilson       Cnt.setCurrentRegionCount(Cnt.getParentCount() +
581bf854f0fSBob Wilson                                 Cnt.getAdjustedCount() + BC.ContinueCount);
5823586be72SDuncan P. N. Exon Smith       CountMap[S->getCond()] = PGO.getCurrentRegionCount();
583bf854f0fSBob Wilson       Visit(S->getCond());
584bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
585bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
586bf854f0fSBob Wilson       RecordNextStmtCount = true;
587bf854f0fSBob Wilson     }
588bf854f0fSBob Wilson 
589bf854f0fSBob Wilson     void VisitDoStmt(const DoStmt *S) {
590bf854f0fSBob Wilson       RecordStmtCount(S);
591bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
592bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
593bf854f0fSBob Wilson       Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
5943586be72SDuncan P. N. Exon Smith       CountMap[S->getBody()] = PGO.getCurrentRegionCount();
595bf854f0fSBob Wilson       Visit(S->getBody());
596bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
597bf854f0fSBob Wilson 
598bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
599bf854f0fSBob Wilson       // The count at the start of the condition is equal to the count at the
600bf854f0fSBob Wilson       // end of the body. The adjusted count does not include either the
601bf854f0fSBob Wilson       // fall-through count coming into the loop or the continue count, so add
602bf854f0fSBob Wilson       // both of those separately. This is coincidentally the same equation as
603bf854f0fSBob Wilson       // with while loops but for different reasons.
604bf854f0fSBob Wilson       Cnt.setCurrentRegionCount(Cnt.getParentCount() +
605bf854f0fSBob Wilson                                 Cnt.getAdjustedCount() + BC.ContinueCount);
6063586be72SDuncan P. N. Exon Smith       CountMap[S->getCond()] = PGO.getCurrentRegionCount();
607bf854f0fSBob Wilson       Visit(S->getCond());
608bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
609bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
610bf854f0fSBob Wilson       RecordNextStmtCount = true;
611bf854f0fSBob Wilson     }
612bf854f0fSBob Wilson 
613bf854f0fSBob Wilson     void VisitForStmt(const ForStmt *S) {
614bf854f0fSBob Wilson       RecordStmtCount(S);
615bf854f0fSBob Wilson       if (S->getInit())
616bf854f0fSBob Wilson         Visit(S->getInit());
617bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
618bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
619bf854f0fSBob Wilson       // Visit the body region first. (This is basically the same as a while
620bf854f0fSBob Wilson       // loop; see further comments in VisitWhileStmt.)
621bf854f0fSBob Wilson       Cnt.beginRegion();
6223586be72SDuncan P. N. Exon Smith       CountMap[S->getBody()] = PGO.getCurrentRegionCount();
623bf854f0fSBob Wilson       Visit(S->getBody());
624bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
625bf854f0fSBob Wilson 
626bf854f0fSBob Wilson       // The increment is essentially part of the body but it needs to include
627bf854f0fSBob Wilson       // the count for all the continue statements.
628bf854f0fSBob Wilson       if (S->getInc()) {
629bf854f0fSBob Wilson         Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
630bf854f0fSBob Wilson                                   BreakContinueStack.back().ContinueCount);
6313586be72SDuncan P. N. Exon Smith         CountMap[S->getInc()] = PGO.getCurrentRegionCount();
632bf854f0fSBob Wilson         Visit(S->getInc());
633bf854f0fSBob Wilson         Cnt.adjustForControlFlow();
634bf854f0fSBob Wilson       }
635bf854f0fSBob Wilson 
636bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
637bf854f0fSBob Wilson 
638bf854f0fSBob Wilson       // ...then go back and propagate counts through the condition.
639bf854f0fSBob Wilson       if (S->getCond()) {
640bf854f0fSBob Wilson         Cnt.setCurrentRegionCount(Cnt.getParentCount() +
641bf854f0fSBob Wilson                                   Cnt.getAdjustedCount() +
642bf854f0fSBob Wilson                                   BC.ContinueCount);
6433586be72SDuncan P. N. Exon Smith         CountMap[S->getCond()] = PGO.getCurrentRegionCount();
644bf854f0fSBob Wilson         Visit(S->getCond());
645bf854f0fSBob Wilson         Cnt.adjustForControlFlow();
646bf854f0fSBob Wilson       }
647bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
648bf854f0fSBob Wilson       RecordNextStmtCount = true;
649bf854f0fSBob Wilson     }
650bf854f0fSBob Wilson 
651bf854f0fSBob Wilson     void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
652bf854f0fSBob Wilson       RecordStmtCount(S);
653bf854f0fSBob Wilson       Visit(S->getRangeStmt());
654bf854f0fSBob Wilson       Visit(S->getBeginEndStmt());
655bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
656bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
657bf854f0fSBob Wilson       // Visit the body region first. (This is basically the same as a while
658bf854f0fSBob Wilson       // loop; see further comments in VisitWhileStmt.)
659bf854f0fSBob Wilson       Cnt.beginRegion();
6603586be72SDuncan P. N. Exon Smith       CountMap[S->getLoopVarStmt()] = PGO.getCurrentRegionCount();
661bf854f0fSBob Wilson       Visit(S->getLoopVarStmt());
662bf854f0fSBob Wilson       Visit(S->getBody());
663bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
664bf854f0fSBob Wilson 
665bf854f0fSBob Wilson       // The increment is essentially part of the body but it needs to include
666bf854f0fSBob Wilson       // the count for all the continue statements.
667bf854f0fSBob Wilson       Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
668bf854f0fSBob Wilson                                 BreakContinueStack.back().ContinueCount);
6693586be72SDuncan P. N. Exon Smith       CountMap[S->getInc()] = PGO.getCurrentRegionCount();
670bf854f0fSBob Wilson       Visit(S->getInc());
671bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
672bf854f0fSBob Wilson 
673bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
674bf854f0fSBob Wilson 
675bf854f0fSBob Wilson       // ...then go back and propagate counts through the condition.
676bf854f0fSBob Wilson       Cnt.setCurrentRegionCount(Cnt.getParentCount() +
677bf854f0fSBob Wilson                                 Cnt.getAdjustedCount() +
678bf854f0fSBob Wilson                                 BC.ContinueCount);
6793586be72SDuncan P. N. Exon Smith       CountMap[S->getCond()] = PGO.getCurrentRegionCount();
680bf854f0fSBob Wilson       Visit(S->getCond());
681bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
682bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
683bf854f0fSBob Wilson       RecordNextStmtCount = true;
684bf854f0fSBob Wilson     }
685bf854f0fSBob Wilson 
686bf854f0fSBob Wilson     void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
687bf854f0fSBob Wilson       RecordStmtCount(S);
688bf854f0fSBob Wilson       Visit(S->getElement());
689bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
690bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
691bf854f0fSBob Wilson       Cnt.beginRegion();
6923586be72SDuncan P. N. Exon Smith       CountMap[S->getBody()] = PGO.getCurrentRegionCount();
693bf854f0fSBob Wilson       Visit(S->getBody());
694bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
695bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
696bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
697bf854f0fSBob Wilson       RecordNextStmtCount = true;
698bf854f0fSBob Wilson     }
699bf854f0fSBob Wilson 
700bf854f0fSBob Wilson     void VisitSwitchStmt(const SwitchStmt *S) {
701bf854f0fSBob Wilson       RecordStmtCount(S);
702bf854f0fSBob Wilson       Visit(S->getCond());
703bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
704bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
705bf854f0fSBob Wilson       Visit(S->getBody());
706bf854f0fSBob Wilson       // If the switch is inside a loop, add the continue counts.
707bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
708bf854f0fSBob Wilson       if (!BreakContinueStack.empty())
709bf854f0fSBob Wilson         BreakContinueStack.back().ContinueCount += BC.ContinueCount;
710bf854f0fSBob Wilson       RegionCounter ExitCnt(PGO, S);
711bf854f0fSBob Wilson       ExitCnt.beginRegion();
712bf854f0fSBob Wilson       RecordNextStmtCount = true;
713bf854f0fSBob Wilson     }
714bf854f0fSBob Wilson 
715bf854f0fSBob Wilson     void VisitCaseStmt(const CaseStmt *S) {
716bf854f0fSBob Wilson       RecordNextStmtCount = false;
717bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
718bf854f0fSBob Wilson       Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
7193586be72SDuncan P. N. Exon Smith       CountMap[S] = Cnt.getCount();
720bf854f0fSBob Wilson       RecordNextStmtCount = true;
721bf854f0fSBob Wilson       Visit(S->getSubStmt());
722bf854f0fSBob Wilson     }
723bf854f0fSBob Wilson 
724bf854f0fSBob Wilson     void VisitDefaultStmt(const DefaultStmt *S) {
725bf854f0fSBob Wilson       RecordNextStmtCount = false;
726bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
727bf854f0fSBob Wilson       Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
7283586be72SDuncan P. N. Exon Smith       CountMap[S] = Cnt.getCount();
729bf854f0fSBob Wilson       RecordNextStmtCount = true;
730bf854f0fSBob Wilson       Visit(S->getSubStmt());
731bf854f0fSBob Wilson     }
732bf854f0fSBob Wilson 
733bf854f0fSBob Wilson     void VisitIfStmt(const IfStmt *S) {
734bf854f0fSBob Wilson       RecordStmtCount(S);
735bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
736bf854f0fSBob Wilson       Visit(S->getCond());
737bf854f0fSBob Wilson 
738bf854f0fSBob Wilson       Cnt.beginRegion();
7393586be72SDuncan P. N. Exon Smith       CountMap[S->getThen()] = PGO.getCurrentRegionCount();
740bf854f0fSBob Wilson       Visit(S->getThen());
741bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
742bf854f0fSBob Wilson 
743bf854f0fSBob Wilson       if (S->getElse()) {
744bf854f0fSBob Wilson         Cnt.beginElseRegion();
7453586be72SDuncan P. N. Exon Smith         CountMap[S->getElse()] = PGO.getCurrentRegionCount();
746bf854f0fSBob Wilson         Visit(S->getElse());
747bf854f0fSBob Wilson         Cnt.adjustForControlFlow();
748bf854f0fSBob Wilson       }
749bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(0);
750bf854f0fSBob Wilson       RecordNextStmtCount = true;
751bf854f0fSBob Wilson     }
752bf854f0fSBob Wilson 
753bf854f0fSBob Wilson     void VisitCXXTryStmt(const CXXTryStmt *S) {
754bf854f0fSBob Wilson       RecordStmtCount(S);
755bf854f0fSBob Wilson       Visit(S->getTryBlock());
756bf854f0fSBob Wilson       for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
757bf854f0fSBob Wilson         Visit(S->getHandler(I));
758bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
759bf854f0fSBob Wilson       Cnt.beginRegion();
760bf854f0fSBob Wilson       RecordNextStmtCount = true;
761bf854f0fSBob Wilson     }
762bf854f0fSBob Wilson 
763bf854f0fSBob Wilson     void VisitCXXCatchStmt(const CXXCatchStmt *S) {
764bf854f0fSBob Wilson       RecordNextStmtCount = false;
765bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
766bf854f0fSBob Wilson       Cnt.beginRegion();
7673586be72SDuncan P. N. Exon Smith       CountMap[S] = PGO.getCurrentRegionCount();
768bf854f0fSBob Wilson       Visit(S->getHandlerBlock());
769bf854f0fSBob Wilson     }
770bf854f0fSBob Wilson 
771bf854f0fSBob Wilson     void VisitConditionalOperator(const ConditionalOperator *E) {
772bf854f0fSBob Wilson       RecordStmtCount(E);
773bf854f0fSBob Wilson       RegionCounter Cnt(PGO, E);
774bf854f0fSBob Wilson       Visit(E->getCond());
775bf854f0fSBob Wilson 
776bf854f0fSBob Wilson       Cnt.beginRegion();
7773586be72SDuncan P. N. Exon Smith       CountMap[E->getTrueExpr()] = PGO.getCurrentRegionCount();
778bf854f0fSBob Wilson       Visit(E->getTrueExpr());
779bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
780bf854f0fSBob Wilson 
781bf854f0fSBob Wilson       Cnt.beginElseRegion();
7823586be72SDuncan P. N. Exon Smith       CountMap[E->getFalseExpr()] = PGO.getCurrentRegionCount();
783bf854f0fSBob Wilson       Visit(E->getFalseExpr());
784bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
785bf854f0fSBob Wilson 
786bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(0);
787bf854f0fSBob Wilson       RecordNextStmtCount = true;
788bf854f0fSBob Wilson     }
789bf854f0fSBob Wilson 
790bf854f0fSBob Wilson     void VisitBinLAnd(const BinaryOperator *E) {
791bf854f0fSBob Wilson       RecordStmtCount(E);
792bf854f0fSBob Wilson       RegionCounter Cnt(PGO, E);
793bf854f0fSBob Wilson       Visit(E->getLHS());
794bf854f0fSBob Wilson       Cnt.beginRegion();
7953586be72SDuncan P. N. Exon Smith       CountMap[E->getRHS()] = PGO.getCurrentRegionCount();
796bf854f0fSBob Wilson       Visit(E->getRHS());
797bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
798bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(0);
799bf854f0fSBob Wilson       RecordNextStmtCount = true;
800bf854f0fSBob Wilson     }
801bf854f0fSBob Wilson 
802bf854f0fSBob Wilson     void VisitBinLOr(const BinaryOperator *E) {
803bf854f0fSBob Wilson       RecordStmtCount(E);
804bf854f0fSBob Wilson       RegionCounter Cnt(PGO, E);
805bf854f0fSBob Wilson       Visit(E->getLHS());
806bf854f0fSBob Wilson       Cnt.beginRegion();
8073586be72SDuncan P. N. Exon Smith       CountMap[E->getRHS()] = PGO.getCurrentRegionCount();
808bf854f0fSBob Wilson       Visit(E->getRHS());
809bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
810bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(0);
811bf854f0fSBob Wilson       RecordNextStmtCount = true;
812bf854f0fSBob Wilson     }
813bf854f0fSBob Wilson   };
814ef512b99SJustin Bogner }
815ef512b99SJustin Bogner 
816d971cd1bSDuncan P. N. Exon Smith static void emitRuntimeHook(CodeGenModule &CGM) {
817966e3206SDuncan P. N. Exon Smith   LLVM_CONSTEXPR const char *RuntimeVarName = "__llvm_profile_runtime";
818966e3206SDuncan P. N. Exon Smith   LLVM_CONSTEXPR const char *RuntimeUserName = "__llvm_profile_runtime_user";
819d971cd1bSDuncan P. N. Exon Smith   if (CGM.getModule().getGlobalVariable(RuntimeVarName))
820d971cd1bSDuncan P. N. Exon Smith     return;
821d971cd1bSDuncan P. N. Exon Smith 
822d971cd1bSDuncan P. N. Exon Smith   // Declare the runtime hook.
823d971cd1bSDuncan P. N. Exon Smith   llvm::LLVMContext &Ctx = CGM.getLLVMContext();
824d971cd1bSDuncan P. N. Exon Smith   auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
825d971cd1bSDuncan P. N. Exon Smith   auto *Var = new llvm::GlobalVariable(CGM.getModule(), Int32Ty, false,
826d971cd1bSDuncan P. N. Exon Smith                                        llvm::GlobalValue::ExternalLinkage,
827d971cd1bSDuncan P. N. Exon Smith                                        nullptr, RuntimeVarName);
828d971cd1bSDuncan P. N. Exon Smith 
829d971cd1bSDuncan P. N. Exon Smith   // Make a function that uses it.
830d971cd1bSDuncan P. N. Exon Smith   auto *User = llvm::Function::Create(llvm::FunctionType::get(Int32Ty, false),
831d971cd1bSDuncan P. N. Exon Smith                                       llvm::GlobalValue::LinkOnceODRLinkage,
832d971cd1bSDuncan P. N. Exon Smith                                       RuntimeUserName, &CGM.getModule());
833d971cd1bSDuncan P. N. Exon Smith   User->addFnAttr(llvm::Attribute::NoInline);
834d971cd1bSDuncan P. N. Exon Smith   if (CGM.getCodeGenOpts().DisableRedZone)
835d971cd1bSDuncan P. N. Exon Smith     User->addFnAttr(llvm::Attribute::NoRedZone);
836d971cd1bSDuncan P. N. Exon Smith   CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", User));
837d971cd1bSDuncan P. N. Exon Smith   auto *Load = Builder.CreateLoad(Var);
838d971cd1bSDuncan P. N. Exon Smith   Builder.CreateRet(Load);
839d971cd1bSDuncan P. N. Exon Smith 
840d971cd1bSDuncan P. N. Exon Smith   // Create a use of the function.  Now the definition of the runtime variable
841d971cd1bSDuncan P. N. Exon Smith   // should get pulled in, along with any static initializears.
842d971cd1bSDuncan P. N. Exon Smith   CGM.addUsedGlobal(User);
843d971cd1bSDuncan P. N. Exon Smith }
844d971cd1bSDuncan P. N. Exon Smith 
845da1ebedeSBob Wilson void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
846ef512b99SJustin Bogner   bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
847d66a17d0SJustin Bogner   PGOProfileData *PGOData = CGM.getPGOData();
848d66a17d0SJustin Bogner   if (!InstrumentRegions && !PGOData)
849ef512b99SJustin Bogner     return;
850ef512b99SJustin Bogner   if (!D)
851ef512b99SJustin Bogner     return;
852da1ebedeSBob Wilson   setFuncName(Fn);
8537c41451bSDuncan P. N. Exon Smith 
8547c41451bSDuncan P. N. Exon Smith   // Set the linkage for variables based on the function linkage.  Usually, we
8557c41451bSDuncan P. N. Exon Smith   // want to match it, but available_externally and extern_weak both have the
8567c41451bSDuncan P. N. Exon Smith   // wrong semantics.
85773f78627SDuncan P. N. Exon Smith   VarLinkage = Fn->getLinkage();
8587c41451bSDuncan P. N. Exon Smith   switch (VarLinkage) {
8597c41451bSDuncan P. N. Exon Smith   case llvm::GlobalValue::ExternalWeakLinkage:
8607c41451bSDuncan P. N. Exon Smith     VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;
8617c41451bSDuncan P. N. Exon Smith     break;
8627c41451bSDuncan P. N. Exon Smith   case llvm::GlobalValue::AvailableExternallyLinkage:
8637c41451bSDuncan P. N. Exon Smith     VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage;
8647c41451bSDuncan P. N. Exon Smith     break;
8657c41451bSDuncan P. N. Exon Smith   default:
8667c41451bSDuncan P. N. Exon Smith     break;
8677c41451bSDuncan P. N. Exon Smith   }
8687c41451bSDuncan P. N. Exon Smith 
869ef512b99SJustin Bogner   mapRegionCounters(D);
870d971cd1bSDuncan P. N. Exon Smith   if (InstrumentRegions) {
871d971cd1bSDuncan P. N. Exon Smith     emitRuntimeHook(CGM);
872ef512b99SJustin Bogner     emitCounterVariables();
873d971cd1bSDuncan P. N. Exon Smith   }
874d66a17d0SJustin Bogner   if (PGOData) {
875d66a17d0SJustin Bogner     loadRegionCounts(PGOData);
876bf854f0fSBob Wilson     computeRegionCounts(D);
877d66a17d0SJustin Bogner     applyFunctionAttributes(PGOData, Fn);
878bf854f0fSBob Wilson   }
879ef512b99SJustin Bogner }
880ef512b99SJustin Bogner 
881ef512b99SJustin Bogner void CodeGenPGO::mapRegionCounters(const Decl *D) {
8821b67cfd4SDuncan P. N. Exon Smith   RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
8833586be72SDuncan P. N. Exon Smith   MapRegionCounters Walker(*RegionCounterMap);
884ef512b99SJustin Bogner   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
885ef512b99SJustin Bogner     Walker.VisitFunctionDecl(FD);
8865ec8fe19SBob Wilson   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
8875ec8fe19SBob Wilson     Walker.VisitObjCMethodDecl(MD);
888c845c00aSBob Wilson   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
889c845c00aSBob Wilson     Walker.VisitBlockDecl(BD);
890ef512b99SJustin Bogner   NumRegionCounters = Walker.NextCounter;
891b4416f58SJustin Bogner   // FIXME: The number of counters isn't sufficient for the hash
892b4416f58SJustin Bogner   FunctionHash = NumRegionCounters;
893ef512b99SJustin Bogner }
894ef512b99SJustin Bogner 
895bf854f0fSBob Wilson void CodeGenPGO::computeRegionCounts(const Decl *D) {
8961b67cfd4SDuncan P. N. Exon Smith   StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
8973586be72SDuncan P. N. Exon Smith   ComputeRegionCounts Walker(*StmtCountMap, *this);
898bf854f0fSBob Wilson   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
899bf854f0fSBob Wilson     Walker.VisitFunctionDecl(FD);
9005ec8fe19SBob Wilson   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
9015ec8fe19SBob Wilson     Walker.VisitObjCMethodDecl(MD);
902c845c00aSBob Wilson   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
903c845c00aSBob Wilson     Walker.VisitBlockDecl(BD);
904bf854f0fSBob Wilson }
905bf854f0fSBob Wilson 
906d66a17d0SJustin Bogner void CodeGenPGO::applyFunctionAttributes(PGOProfileData *PGOData,
9074c9c45c0SJustin Bogner                                          llvm::Function *Fn) {
9084c9c45c0SJustin Bogner   if (!haveRegionCounts())
9094c9c45c0SJustin Bogner     return;
9104c9c45c0SJustin Bogner 
911d66a17d0SJustin Bogner   uint64_t MaxFunctionCount = PGOData->getMaximumFunctionCount();
9124c9c45c0SJustin Bogner   uint64_t FunctionCount = getRegionCount(0);
9134c9c45c0SJustin Bogner   if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount))
9144c9c45c0SJustin Bogner     // Turn on InlineHint attribute for hot functions.
9154c9c45c0SJustin Bogner     // FIXME: 30% is from preliminary tuning on SPEC, it may not be optimal.
9164c9c45c0SJustin Bogner     Fn->addFnAttr(llvm::Attribute::InlineHint);
9174c9c45c0SJustin Bogner   else if (FunctionCount <= (uint64_t)(0.01 * (double)MaxFunctionCount))
9184c9c45c0SJustin Bogner     // Turn on Cold attribute for cold functions.
9194c9c45c0SJustin Bogner     // FIXME: 1% is from preliminary tuning on SPEC, it may not be optimal.
9204c9c45c0SJustin Bogner     Fn->addFnAttr(llvm::Attribute::Cold);
9214c9c45c0SJustin Bogner }
9224c9c45c0SJustin Bogner 
923ef512b99SJustin Bogner void CodeGenPGO::emitCounterVariables() {
924ef512b99SJustin Bogner   llvm::LLVMContext &Ctx = CGM.getLLVMContext();
925ef512b99SJustin Bogner   llvm::ArrayType *CounterTy = llvm::ArrayType::get(llvm::Type::getInt64Ty(Ctx),
926ef512b99SJustin Bogner                                                     NumRegionCounters);
927ef512b99SJustin Bogner   RegionCounters =
92873f78627SDuncan P. N. Exon Smith     new llvm::GlobalVariable(CGM.getModule(), CounterTy, false, VarLinkage,
929ef512b99SJustin Bogner                              llvm::Constant::getNullValue(CounterTy),
9302fe531cbSDuncan P. N. Exon Smith                              getFuncVarName("counters"));
9312fe531cbSDuncan P. N. Exon Smith   RegionCounters->setAlignment(8);
9322fe531cbSDuncan P. N. Exon Smith   RegionCounters->setSection(getCountersSection(CGM));
933ef512b99SJustin Bogner }
934ef512b99SJustin Bogner 
935ef512b99SJustin Bogner void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) {
936749ebc7fSBob Wilson   if (!RegionCounters)
937ef512b99SJustin Bogner     return;
938ef512b99SJustin Bogner   llvm::Value *Addr =
939ef512b99SJustin Bogner     Builder.CreateConstInBoundsGEP2_64(RegionCounters, 0, Counter);
940ef512b99SJustin Bogner   llvm::Value *Count = Builder.CreateLoad(Addr, "pgocount");
941ef512b99SJustin Bogner   Count = Builder.CreateAdd(Count, Builder.getInt64(1));
942ef512b99SJustin Bogner   Builder.CreateStore(Count, Addr);
943ef512b99SJustin Bogner }
944ef512b99SJustin Bogner 
945d66a17d0SJustin Bogner void CodeGenPGO::loadRegionCounts(PGOProfileData *PGOData) {
946ef512b99SJustin Bogner   // For now, ignore the counts from the PGO data file only if the number of
947ef512b99SJustin Bogner   // counters does not match. This could be tightened down in the future to
948ef512b99SJustin Bogner   // ignore counts when the input changes in various ways, e.g., by comparing a
949ef512b99SJustin Bogner   // hash value based on some characteristics of the input.
9501b67cfd4SDuncan P. N. Exon Smith   RegionCounts.reset(new std::vector<uint64_t>);
951b4416f58SJustin Bogner   uint64_t Hash;
952b4416f58SJustin Bogner   if (PGOData->getFunctionCounts(getFuncName(), Hash, *RegionCounts) ||
9531b67cfd4SDuncan P. N. Exon Smith       Hash != FunctionHash || RegionCounts->size() != NumRegionCounters)
9541b67cfd4SDuncan P. N. Exon Smith     RegionCounts.reset();
955ef512b99SJustin Bogner }
956ef512b99SJustin Bogner 
957ef512b99SJustin Bogner void CodeGenPGO::destroyRegionCounters() {
9581b67cfd4SDuncan P. N. Exon Smith   RegionCounterMap.reset();
9591b67cfd4SDuncan P. N. Exon Smith   StmtCountMap.reset();
9601b67cfd4SDuncan P. N. Exon Smith   RegionCounts.reset();
961ef512b99SJustin Bogner }
962ef512b99SJustin Bogner 
96338402dc9SDuncan P. N. Exon Smith /// \brief Calculate what to divide by to scale weights.
96438402dc9SDuncan P. N. Exon Smith ///
96538402dc9SDuncan P. N. Exon Smith /// Given the maximum weight, calculate a divisor that will scale all the
96638402dc9SDuncan P. N. Exon Smith /// weights to strictly less than UINT32_MAX.
96738402dc9SDuncan P. N. Exon Smith static uint64_t calculateWeightScale(uint64_t MaxWeight) {
96838402dc9SDuncan P. N. Exon Smith   return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
96938402dc9SDuncan P. N. Exon Smith }
97038402dc9SDuncan P. N. Exon Smith 
97138402dc9SDuncan P. N. Exon Smith /// \brief Scale an individual branch weight (and add 1).
97238402dc9SDuncan P. N. Exon Smith ///
97338402dc9SDuncan P. N. Exon Smith /// Scale a 64-bit weight down to 32-bits using \c Scale.
97438402dc9SDuncan P. N. Exon Smith ///
97538402dc9SDuncan P. N. Exon Smith /// According to Laplace's Rule of Succession, it is better to compute the
97638402dc9SDuncan P. N. Exon Smith /// weight based on the count plus 1, so universally add 1 to the value.
97738402dc9SDuncan P. N. Exon Smith ///
97838402dc9SDuncan P. N. Exon Smith /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
97938402dc9SDuncan P. N. Exon Smith /// greater than \c Weight.
98038402dc9SDuncan P. N. Exon Smith static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
98138402dc9SDuncan P. N. Exon Smith   assert(Scale && "scale by 0?");
98238402dc9SDuncan P. N. Exon Smith   uint64_t Scaled = Weight / Scale + 1;
98338402dc9SDuncan P. N. Exon Smith   assert(Scaled <= UINT32_MAX && "overflow 32-bits");
98438402dc9SDuncan P. N. Exon Smith   return Scaled;
98538402dc9SDuncan P. N. Exon Smith }
98638402dc9SDuncan P. N. Exon Smith 
987ef512b99SJustin Bogner llvm::MDNode *CodeGenPGO::createBranchWeights(uint64_t TrueCount,
988ef512b99SJustin Bogner                                               uint64_t FalseCount) {
98938402dc9SDuncan P. N. Exon Smith   // Check for empty weights.
990ef512b99SJustin Bogner   if (!TrueCount && !FalseCount)
991a5f804a7SDuncan P. N. Exon Smith     return nullptr;
992ef512b99SJustin Bogner 
99338402dc9SDuncan P. N. Exon Smith   // Calculate how to scale down to 32-bits.
99438402dc9SDuncan P. N. Exon Smith   uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
99538402dc9SDuncan P. N. Exon Smith 
996ef512b99SJustin Bogner   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
99738402dc9SDuncan P. N. Exon Smith   return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
99838402dc9SDuncan P. N. Exon Smith                                       scaleBranchWeight(FalseCount, Scale));
999ef512b99SJustin Bogner }
1000ef512b99SJustin Bogner 
100195a27b0eSBob Wilson llvm::MDNode *CodeGenPGO::createBranchWeights(ArrayRef<uint64_t> Weights) {
100238402dc9SDuncan P. N. Exon Smith   // We need at least two elements to create meaningful weights.
100338402dc9SDuncan P. N. Exon Smith   if (Weights.size() < 2)
1004a5f804a7SDuncan P. N. Exon Smith     return nullptr;
100538402dc9SDuncan P. N. Exon Smith 
1006f3aefca7SJustin Bogner   // Check for empty weights.
1007f3aefca7SJustin Bogner   uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
1008f3aefca7SJustin Bogner   if (MaxWeight == 0)
1009f3aefca7SJustin Bogner     return nullptr;
1010f3aefca7SJustin Bogner 
101138402dc9SDuncan P. N. Exon Smith   // Calculate how to scale down to 32-bits.
1012f3aefca7SJustin Bogner   uint64_t Scale = calculateWeightScale(MaxWeight);
101338402dc9SDuncan P. N. Exon Smith 
1014ef512b99SJustin Bogner   SmallVector<uint32_t, 16> ScaledWeights;
1015ef512b99SJustin Bogner   ScaledWeights.reserve(Weights.size());
101638402dc9SDuncan P. N. Exon Smith   for (uint64_t W : Weights)
101738402dc9SDuncan P. N. Exon Smith     ScaledWeights.push_back(scaleBranchWeight(W, Scale));
101838402dc9SDuncan P. N. Exon Smith 
101938402dc9SDuncan P. N. Exon Smith   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
1020ef512b99SJustin Bogner   return MDHelper.createBranchWeights(ScaledWeights);
1021ef512b99SJustin Bogner }
1022bf854f0fSBob Wilson 
1023bf854f0fSBob Wilson llvm::MDNode *CodeGenPGO::createLoopWeights(const Stmt *Cond,
1024bf854f0fSBob Wilson                                             RegionCounter &Cnt) {
1025bf854f0fSBob Wilson   if (!haveRegionCounts())
1026a5f804a7SDuncan P. N. Exon Smith     return nullptr;
1027bf854f0fSBob Wilson   uint64_t LoopCount = Cnt.getCount();
1028bf854f0fSBob Wilson   uint64_t CondCount = 0;
1029bf854f0fSBob Wilson   bool Found = getStmtCount(Cond, CondCount);
1030bf854f0fSBob Wilson   assert(Found && "missing expected loop condition count");
1031bf854f0fSBob Wilson   (void)Found;
1032bf854f0fSBob Wilson   if (CondCount == 0)
1033a5f804a7SDuncan P. N. Exon Smith     return nullptr;
1034bf854f0fSBob Wilson   return createBranchWeights(LoopCount,
1035bf854f0fSBob Wilson                              std::max(CondCount, LoopCount) - LoopCount);
1036bf854f0fSBob Wilson }
1037