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     while (*--CurPtr != ' ')
62d66a17d0SJustin Bogner       ;
63d66a17d0SJustin Bogner     StringRef FuncName(FuncStart, CurPtr - FuncStart);
64d66a17d0SJustin Bogner 
65d66a17d0SJustin Bogner     // Read the number of counters.
66d66a17d0SJustin Bogner     char *EndPtr;
67d66a17d0SJustin Bogner     unsigned NumCounters = strtol(++CurPtr, &EndPtr, 10);
68d66a17d0SJustin Bogner     if (EndPtr == CurPtr || *EndPtr != '\n' || NumCounters <= 0) {
69d66a17d0SJustin Bogner       ReportBadPGOData(CGM, "pgo data file has unexpected number of counters");
70d66a17d0SJustin Bogner       return;
71d66a17d0SJustin Bogner     }
72d66a17d0SJustin Bogner     CurPtr = EndPtr;
73d66a17d0SJustin Bogner 
74d66a17d0SJustin Bogner     // Read function count.
75d66a17d0SJustin Bogner     uint64_t Count = strtoll(CurPtr, &EndPtr, 10);
76d66a17d0SJustin Bogner     if (EndPtr == CurPtr || *EndPtr != '\n') {
77d66a17d0SJustin Bogner       ReportBadPGOData(CGM, "pgo-data file has bad count value");
78d66a17d0SJustin Bogner       return;
79d66a17d0SJustin Bogner     }
80d66a17d0SJustin Bogner     CurPtr = EndPtr; // Point to '\n'.
81d66a17d0SJustin Bogner     FunctionCounts[FuncName] = Count;
82d66a17d0SJustin Bogner     MaxCount = Count > MaxCount ? Count : MaxCount;
83d66a17d0SJustin Bogner 
84d66a17d0SJustin Bogner     // There is one line for each counter; skip over those lines.
85d66a17d0SJustin Bogner     // Since function count is already read, we start the loop from 1.
86d66a17d0SJustin Bogner     for (unsigned N = 1; N < NumCounters; ++N) {
87d66a17d0SJustin Bogner       CurPtr = strchr(++CurPtr, '\n');
88d66a17d0SJustin Bogner       if (!CurPtr) {
89d66a17d0SJustin Bogner         ReportBadPGOData(CGM, "pgo data file is missing some counter info");
90d66a17d0SJustin Bogner         return;
91d66a17d0SJustin Bogner       }
92d66a17d0SJustin Bogner     }
93d66a17d0SJustin Bogner 
94d66a17d0SJustin Bogner     // Skip over the blank line separating functions.
95d66a17d0SJustin Bogner     CurPtr += 2;
96d66a17d0SJustin Bogner 
97d66a17d0SJustin Bogner     DataOffsets[FuncName] = FuncStart - BufferStart;
98d66a17d0SJustin Bogner   }
99d66a17d0SJustin Bogner   MaxFunctionCount = MaxCount;
100d66a17d0SJustin Bogner }
101d66a17d0SJustin Bogner 
102d66a17d0SJustin Bogner bool PGOProfileData::getFunctionCounts(StringRef FuncName,
103d66a17d0SJustin Bogner                                        std::vector<uint64_t> &Counts) {
104d66a17d0SJustin Bogner   // Find the relevant section of the pgo-data file.
105d66a17d0SJustin Bogner   llvm::StringMap<unsigned>::const_iterator OffsetIter =
106d66a17d0SJustin Bogner     DataOffsets.find(FuncName);
107d66a17d0SJustin Bogner   if (OffsetIter == DataOffsets.end())
108d66a17d0SJustin Bogner     return true;
109d66a17d0SJustin Bogner   const char *CurPtr = DataBuffer->getBufferStart() + OffsetIter->getValue();
110d66a17d0SJustin Bogner 
111d66a17d0SJustin Bogner   // Skip over the function name.
112d66a17d0SJustin Bogner   CurPtr = strchr(CurPtr, '\n');
113d66a17d0SJustin Bogner   assert(CurPtr && "pgo-data has corrupted function entry");
114d66a17d0SJustin Bogner   while (*--CurPtr != ' ')
115d66a17d0SJustin Bogner     ;
116d66a17d0SJustin Bogner 
117d66a17d0SJustin Bogner   // Read the number of counters.
118d66a17d0SJustin Bogner   char *EndPtr;
119d66a17d0SJustin Bogner   unsigned NumCounters = strtol(++CurPtr, &EndPtr, 10);
120d66a17d0SJustin Bogner   assert(EndPtr != CurPtr && *EndPtr == '\n' && NumCounters > 0 &&
121d66a17d0SJustin Bogner          "pgo-data file has corrupted number of counters");
122d66a17d0SJustin Bogner   CurPtr = EndPtr;
123d66a17d0SJustin Bogner 
124d66a17d0SJustin Bogner   Counts.reserve(NumCounters);
125d66a17d0SJustin Bogner 
126d66a17d0SJustin Bogner   for (unsigned N = 0; N < NumCounters; ++N) {
127d66a17d0SJustin Bogner     // Read the count value.
128d66a17d0SJustin Bogner     uint64_t Count = strtoll(CurPtr, &EndPtr, 10);
129d66a17d0SJustin Bogner     if (EndPtr == CurPtr || *EndPtr != '\n') {
130d66a17d0SJustin Bogner       ReportBadPGOData(CGM, "pgo-data file has bad count value");
131d66a17d0SJustin Bogner       return true;
132d66a17d0SJustin Bogner     }
133d66a17d0SJustin Bogner     Counts.push_back(Count);
134d66a17d0SJustin Bogner     CurPtr = EndPtr + 1;
135d66a17d0SJustin Bogner   }
136d66a17d0SJustin Bogner 
137d66a17d0SJustin Bogner   // Make sure the number of counters matches up.
138d66a17d0SJustin Bogner   if (Counts.size() != NumCounters) {
139d66a17d0SJustin Bogner     ReportBadPGOData(CGM, "pgo-data file has inconsistent counters");
140d66a17d0SJustin Bogner     return true;
141d66a17d0SJustin Bogner   }
142d66a17d0SJustin Bogner 
143d66a17d0SJustin Bogner   return false;
144d66a17d0SJustin Bogner }
145d66a17d0SJustin Bogner 
146da1ebedeSBob Wilson void CodeGenPGO::setFuncName(llvm::Function *Fn) {
147*2fe531cbSDuncan P. N. Exon Smith   RawFuncName = Fn->getName();
148da1ebedeSBob Wilson 
149da1ebedeSBob Wilson   // Function names may be prefixed with a binary '1' to indicate
150da1ebedeSBob Wilson   // that the backend should not modify the symbols due to any platform
151da1ebedeSBob Wilson   // naming convention. Do not include that '1' in the PGO profile name.
152*2fe531cbSDuncan P. N. Exon Smith   if (RawFuncName[0] == '\1')
153*2fe531cbSDuncan P. N. Exon Smith     RawFuncName = RawFuncName.substr(1);
154da1ebedeSBob Wilson 
155da1ebedeSBob Wilson   if (!Fn->hasLocalLinkage()) {
156*2fe531cbSDuncan P. N. Exon Smith     PrefixedFuncName = new std::string(RawFuncName);
157da1ebedeSBob Wilson     return;
158da1ebedeSBob Wilson   }
159da1ebedeSBob Wilson 
160da1ebedeSBob Wilson   // For local symbols, prepend the main file name to distinguish them.
161da1ebedeSBob Wilson   // Do not include the full path in the file name since there's no guarantee
162da1ebedeSBob Wilson   // that it will stay the same, e.g., if the files are checked out from
163da1ebedeSBob Wilson   // version control in different locations.
164*2fe531cbSDuncan P. N. Exon Smith   PrefixedFuncName = new std::string(CGM.getCodeGenOpts().MainFileName);
165*2fe531cbSDuncan P. N. Exon Smith   if (PrefixedFuncName->empty())
166*2fe531cbSDuncan P. N. Exon Smith     PrefixedFuncName->assign("<unknown>");
167*2fe531cbSDuncan P. N. Exon Smith   PrefixedFuncName->append(":");
168*2fe531cbSDuncan P. N. Exon Smith   PrefixedFuncName->append(RawFuncName);
169da1ebedeSBob Wilson }
170da1ebedeSBob Wilson 
171*2fe531cbSDuncan P. N. Exon Smith static llvm::Function *getRegisterFunc(CodeGenModule &CGM) {
172*2fe531cbSDuncan P. N. Exon Smith   return CGM.getModule().getFunction("__llvm_pgo_register_functions");
173*2fe531cbSDuncan P. N. Exon Smith }
174*2fe531cbSDuncan P. N. Exon Smith 
175*2fe531cbSDuncan P. N. Exon Smith static llvm::BasicBlock *getOrInsertRegisterBB(CodeGenModule &CGM) {
176*2fe531cbSDuncan P. N. Exon Smith   // Only need to insert this once per module.
177*2fe531cbSDuncan P. N. Exon Smith   if (llvm::Function *RegisterF = getRegisterFunc(CGM))
178*2fe531cbSDuncan P. N. Exon Smith     return &RegisterF->getEntryBlock();
179*2fe531cbSDuncan P. N. Exon Smith 
180*2fe531cbSDuncan P. N. Exon Smith   // Construct the function.
181*2fe531cbSDuncan P. N. Exon Smith   auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
182*2fe531cbSDuncan P. N. Exon Smith   auto *RegisterFTy = llvm::FunctionType::get(VoidTy, false);
183*2fe531cbSDuncan P. N. Exon Smith   auto *RegisterF = llvm::Function::Create(RegisterFTy,
184*2fe531cbSDuncan P. N. Exon Smith                                            llvm::GlobalValue::InternalLinkage,
185*2fe531cbSDuncan P. N. Exon Smith                                            "__llvm_pgo_register_functions",
186*2fe531cbSDuncan P. N. Exon Smith                                            &CGM.getModule());
187*2fe531cbSDuncan P. N. Exon Smith   RegisterF->setUnnamedAddr(true);
188*2fe531cbSDuncan P. N. Exon Smith   RegisterF->addFnAttr(llvm::Attribute::NoInline);
189*2fe531cbSDuncan P. N. Exon Smith   if (CGM.getCodeGenOpts().DisableRedZone)
190*2fe531cbSDuncan P. N. Exon Smith     RegisterF->addFnAttr(llvm::Attribute::NoRedZone);
191*2fe531cbSDuncan P. N. Exon Smith 
192*2fe531cbSDuncan P. N. Exon Smith   // Construct and return the entry block.
193*2fe531cbSDuncan P. N. Exon Smith   auto *BB = llvm::BasicBlock::Create(CGM.getLLVMContext(), "", RegisterF);
194*2fe531cbSDuncan P. N. Exon Smith   CGBuilderTy Builder(BB);
195*2fe531cbSDuncan P. N. Exon Smith   Builder.CreateRetVoid();
196*2fe531cbSDuncan P. N. Exon Smith   return BB;
197*2fe531cbSDuncan P. N. Exon Smith }
198*2fe531cbSDuncan P. N. Exon Smith 
199*2fe531cbSDuncan P. N. Exon Smith static llvm::Constant *getOrInsertRuntimeRegister(CodeGenModule &CGM) {
200*2fe531cbSDuncan P. N. Exon Smith   auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
201*2fe531cbSDuncan P. N. Exon Smith   auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
202*2fe531cbSDuncan P. N. Exon Smith   auto *RuntimeRegisterTy = llvm::FunctionType::get(VoidTy, VoidPtrTy, false);
203*2fe531cbSDuncan P. N. Exon Smith   return CGM.getModule().getOrInsertFunction("__llvm_pgo_register_function",
204*2fe531cbSDuncan P. N. Exon Smith                                              RuntimeRegisterTy);
205*2fe531cbSDuncan P. N. Exon Smith }
206*2fe531cbSDuncan P. N. Exon Smith 
207*2fe531cbSDuncan P. N. Exon Smith static llvm::Constant *getOrInsertRuntimeWriteAtExit(CodeGenModule &CGM) {
208*2fe531cbSDuncan P. N. Exon Smith   // TODO: make this depend on a command-line option.
209*2fe531cbSDuncan P. N. Exon Smith   auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
210*2fe531cbSDuncan P. N. Exon Smith   auto *WriteAtExitTy = llvm::FunctionType::get(VoidTy, false);
211*2fe531cbSDuncan P. N. Exon Smith   return CGM.getModule().getOrInsertFunction("__llvm_pgo_register_write_atexit",
212*2fe531cbSDuncan P. N. Exon Smith                                              WriteAtExitTy);
213*2fe531cbSDuncan P. N. Exon Smith }
214*2fe531cbSDuncan P. N. Exon Smith 
215*2fe531cbSDuncan P. N. Exon Smith static StringRef getCountersSection(const CodeGenModule &CGM) {
216*2fe531cbSDuncan P. N. Exon Smith   if (CGM.getTarget().getTriple().getObjectFormat() == llvm::Triple::MachO)
217*2fe531cbSDuncan P. N. Exon Smith     return "__DATA,__llvm_pgo_cnts";
218*2fe531cbSDuncan P. N. Exon Smith   else
219*2fe531cbSDuncan P. N. Exon Smith     return "__llvm_pgo_cnts";
220*2fe531cbSDuncan P. N. Exon Smith }
221*2fe531cbSDuncan P. N. Exon Smith 
222*2fe531cbSDuncan P. N. Exon Smith static StringRef getNameSection(const CodeGenModule &CGM) {
223*2fe531cbSDuncan P. N. Exon Smith   if (CGM.getTarget().getTriple().getObjectFormat() == llvm::Triple::MachO)
224*2fe531cbSDuncan P. N. Exon Smith     return "__DATA,__llvm_pgo_names";
225*2fe531cbSDuncan P. N. Exon Smith   else
226*2fe531cbSDuncan P. N. Exon Smith     return "__llvm_pgo_names";
227*2fe531cbSDuncan P. N. Exon Smith }
228*2fe531cbSDuncan P. N. Exon Smith 
229*2fe531cbSDuncan P. N. Exon Smith static StringRef getDataSection(const CodeGenModule &CGM) {
230*2fe531cbSDuncan P. N. Exon Smith   if (CGM.getTarget().getTriple().getObjectFormat() == llvm::Triple::MachO)
231*2fe531cbSDuncan P. N. Exon Smith     return "__DATA,__llvm_pgo_data";
232*2fe531cbSDuncan P. N. Exon Smith   else
233*2fe531cbSDuncan P. N. Exon Smith     return "__llvm_pgo_data";
234*2fe531cbSDuncan P. N. Exon Smith }
235*2fe531cbSDuncan P. N. Exon Smith 
236*2fe531cbSDuncan P. N. Exon Smith llvm::GlobalVariable *CodeGenPGO::buildDataVar() {
237*2fe531cbSDuncan P. N. Exon Smith   // Create name variable.
238*2fe531cbSDuncan P. N. Exon Smith   llvm::LLVMContext &Ctx = CGM.getLLVMContext();
239*2fe531cbSDuncan P. N. Exon Smith   auto *VarName = llvm::ConstantDataArray::getString(Ctx, getFuncName(),
240*2fe531cbSDuncan P. N. Exon Smith                                                      false);
241*2fe531cbSDuncan P. N. Exon Smith   auto *Name = new llvm::GlobalVariable(CGM.getModule(), VarName->getType(),
242*2fe531cbSDuncan P. N. Exon Smith                                         true, FuncLinkage, VarName,
243*2fe531cbSDuncan P. N. Exon Smith                                         getFuncVarName("name"));
244*2fe531cbSDuncan P. N. Exon Smith   Name->setSection(getNameSection(CGM));
245*2fe531cbSDuncan P. N. Exon Smith   Name->setAlignment(1);
246*2fe531cbSDuncan P. N. Exon Smith 
247*2fe531cbSDuncan P. N. Exon Smith   // Create data variable.
248*2fe531cbSDuncan P. N. Exon Smith   auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
249*2fe531cbSDuncan P. N. Exon Smith   auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
250*2fe531cbSDuncan P. N. Exon Smith   auto *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);
251*2fe531cbSDuncan P. N. Exon Smith   llvm::Type *DataTypes[] = {
252*2fe531cbSDuncan P. N. Exon Smith     Int32Ty, Int32Ty, Int8PtrTy, Int64PtrTy
253*2fe531cbSDuncan P. N. Exon Smith   };
254*2fe531cbSDuncan P. N. Exon Smith   auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes));
255*2fe531cbSDuncan P. N. Exon Smith   llvm::Constant *DataVals[] = {
256*2fe531cbSDuncan P. N. Exon Smith     llvm::ConstantInt::get(Int32Ty, getFuncName().size()),
257*2fe531cbSDuncan P. N. Exon Smith     llvm::ConstantInt::get(Int32Ty, NumRegionCounters),
258*2fe531cbSDuncan P. N. Exon Smith     llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),
259*2fe531cbSDuncan P. N. Exon Smith     llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)
260*2fe531cbSDuncan P. N. Exon Smith   };
261*2fe531cbSDuncan P. N. Exon Smith   auto *Data =
262*2fe531cbSDuncan P. N. Exon Smith     new llvm::GlobalVariable(CGM.getModule(), DataTy, true, FuncLinkage,
263*2fe531cbSDuncan P. N. Exon Smith                              llvm::ConstantStruct::get(DataTy, DataVals),
264*2fe531cbSDuncan P. N. Exon Smith                              getFuncVarName("data"));
265*2fe531cbSDuncan P. N. Exon Smith 
266*2fe531cbSDuncan P. N. Exon Smith   // All the data should be packed into an array in its own section.
267*2fe531cbSDuncan P. N. Exon Smith   Data->setSection(getDataSection(CGM));
268*2fe531cbSDuncan P. N. Exon Smith   Data->setAlignment(8);
269*2fe531cbSDuncan P. N. Exon Smith 
270*2fe531cbSDuncan P. N. Exon Smith   // Make sure the data doesn't get deleted.
271*2fe531cbSDuncan P. N. Exon Smith   CGM.addUsedGlobal(Data);
272*2fe531cbSDuncan P. N. Exon Smith   return Data;
273*2fe531cbSDuncan P. N. Exon Smith }
274*2fe531cbSDuncan P. N. Exon Smith 
275*2fe531cbSDuncan P. N. Exon Smith void CodeGenPGO::emitInstrumentationData() {
276ef512b99SJustin Bogner   if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
277ef512b99SJustin Bogner     return;
278ef512b99SJustin Bogner 
279*2fe531cbSDuncan P. N. Exon Smith   // Build the data.
280*2fe531cbSDuncan P. N. Exon Smith   auto *Data = buildDataVar();
281ef512b99SJustin Bogner 
282*2fe531cbSDuncan P. N. Exon Smith   // Register the data.
283*2fe531cbSDuncan P. N. Exon Smith   //
284*2fe531cbSDuncan P. N. Exon Smith   // TODO: only register when static initialization is required.
285*2fe531cbSDuncan P. N. Exon Smith   CGBuilderTy Builder(getOrInsertRegisterBB(CGM)->getTerminator());
286*2fe531cbSDuncan P. N. Exon Smith   auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
287*2fe531cbSDuncan P. N. Exon Smith   Builder.CreateCall(getOrInsertRuntimeRegister(CGM),
288*2fe531cbSDuncan P. N. Exon Smith                      Builder.CreateBitCast(Data, VoidPtrTy));
289ef512b99SJustin Bogner }
290ef512b99SJustin Bogner 
291ef512b99SJustin Bogner llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) {
292*2fe531cbSDuncan P. N. Exon Smith   if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
293*2fe531cbSDuncan P. N. Exon Smith     return 0;
294ef512b99SJustin Bogner 
295*2fe531cbSDuncan P. N. Exon Smith   // Only need to create this once per module.
296*2fe531cbSDuncan P. N. Exon Smith   if (CGM.getModule().getFunction("__llvm_pgo_init"))
297*2fe531cbSDuncan P. N. Exon Smith     return 0;
298ef512b99SJustin Bogner 
299*2fe531cbSDuncan P. N. Exon Smith   // Get the functions to call at initialization.
300*2fe531cbSDuncan P. N. Exon Smith   llvm::Constant *RegisterF = getRegisterFunc(CGM);
301*2fe531cbSDuncan P. N. Exon Smith   llvm::Constant *WriteAtExitF = getOrInsertRuntimeWriteAtExit(CGM);
302*2fe531cbSDuncan P. N. Exon Smith   if (!RegisterF && !WriteAtExitF)
303*2fe531cbSDuncan P. N. Exon Smith     return 0;
304*2fe531cbSDuncan P. N. Exon Smith 
305*2fe531cbSDuncan P. N. Exon Smith   // Create the initialization function.
306*2fe531cbSDuncan P. N. Exon Smith   auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
307*2fe531cbSDuncan P. N. Exon Smith   auto *F = llvm::Function::Create(llvm::FunctionType::get(VoidTy, false),
308*2fe531cbSDuncan P. N. Exon Smith                                    llvm::GlobalValue::InternalLinkage,
309ef512b99SJustin Bogner                                    "__llvm_pgo_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 
315*2fe531cbSDuncan P. N. Exon Smith   // Add the basic block and the necessary calls.
316*2fe531cbSDuncan P. N. Exon Smith   CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", F));
317*2fe531cbSDuncan P. N. Exon Smith   if (RegisterF)
318*2fe531cbSDuncan P. N. Exon Smith     Builder.CreateCall(RegisterF);
319*2fe531cbSDuncan P. N. Exon Smith   if (WriteAtExitF)
320*2fe531cbSDuncan P. N. Exon Smith     Builder.CreateCall(WriteAtExitF);
321*2fe531cbSDuncan P. N. Exon Smith   Builder.CreateRetVoid();
322ef512b99SJustin Bogner 
323ef512b99SJustin Bogner   return F;
324ef512b99SJustin Bogner }
325ef512b99SJustin Bogner 
326ef512b99SJustin Bogner namespace {
327ef512b99SJustin Bogner   /// A StmtVisitor that fills a map of statements to PGO counters.
328ef512b99SJustin Bogner   struct MapRegionCounters : public ConstStmtVisitor<MapRegionCounters> {
329ef512b99SJustin Bogner     /// The next counter value to assign.
330ef512b99SJustin Bogner     unsigned NextCounter;
331ef512b99SJustin Bogner     /// The map of statements to counters.
332ef512b99SJustin Bogner     llvm::DenseMap<const Stmt*, unsigned> *CounterMap;
333ef512b99SJustin Bogner 
334ef512b99SJustin Bogner     MapRegionCounters(llvm::DenseMap<const Stmt*, unsigned> *CounterMap) :
335ef512b99SJustin Bogner       NextCounter(0), CounterMap(CounterMap) {
336ef512b99SJustin Bogner     }
337ef512b99SJustin Bogner 
338ef512b99SJustin Bogner     void VisitChildren(const Stmt *S) {
339ef512b99SJustin Bogner       for (Stmt::const_child_range I = S->children(); I; ++I)
340ef512b99SJustin Bogner         if (*I)
341ef512b99SJustin Bogner          this->Visit(*I);
342ef512b99SJustin Bogner     }
343ef512b99SJustin Bogner     void VisitStmt(const Stmt *S) { VisitChildren(S); }
344ef512b99SJustin Bogner 
345ea278c32SJustin Bogner     /// Assign a counter to track entry to the function body.
346ef512b99SJustin Bogner     void VisitFunctionDecl(const FunctionDecl *S) {
347ef512b99SJustin Bogner       (*CounterMap)[S->getBody()] = NextCounter++;
348ef512b99SJustin Bogner       Visit(S->getBody());
349ef512b99SJustin Bogner     }
3505ec8fe19SBob Wilson     void VisitObjCMethodDecl(const ObjCMethodDecl *S) {
3515ec8fe19SBob Wilson       (*CounterMap)[S->getBody()] = NextCounter++;
3525ec8fe19SBob Wilson       Visit(S->getBody());
3535ec8fe19SBob Wilson     }
354c845c00aSBob Wilson     void VisitBlockDecl(const BlockDecl *S) {
355c845c00aSBob Wilson       (*CounterMap)[S->getBody()] = NextCounter++;
356c845c00aSBob Wilson       Visit(S->getBody());
357c845c00aSBob Wilson     }
358ea278c32SJustin Bogner     /// Assign a counter to track the block following a label.
359ef512b99SJustin Bogner     void VisitLabelStmt(const LabelStmt *S) {
360ef512b99SJustin Bogner       (*CounterMap)[S] = NextCounter++;
361ef512b99SJustin Bogner       Visit(S->getSubStmt());
362ef512b99SJustin Bogner     }
363bf854f0fSBob Wilson     /// Assign a counter for the body of a while loop.
364ef512b99SJustin Bogner     void VisitWhileStmt(const WhileStmt *S) {
365bf854f0fSBob Wilson       (*CounterMap)[S] = NextCounter++;
366ef512b99SJustin Bogner       Visit(S->getCond());
367ef512b99SJustin Bogner       Visit(S->getBody());
368ef512b99SJustin Bogner     }
369bf854f0fSBob Wilson     /// Assign a counter for the body of a do-while loop.
370ef512b99SJustin Bogner     void VisitDoStmt(const DoStmt *S) {
371bf854f0fSBob Wilson       (*CounterMap)[S] = NextCounter++;
372ef512b99SJustin Bogner       Visit(S->getBody());
373ef512b99SJustin Bogner       Visit(S->getCond());
374ef512b99SJustin Bogner     }
375bf854f0fSBob Wilson     /// Assign a counter for the body of a for loop.
376ef512b99SJustin Bogner     void VisitForStmt(const ForStmt *S) {
377bf854f0fSBob Wilson       (*CounterMap)[S] = NextCounter++;
378bf854f0fSBob Wilson       if (S->getInit())
379bf854f0fSBob Wilson         Visit(S->getInit());
380ef512b99SJustin Bogner       const Expr *E;
381ef512b99SJustin Bogner       if ((E = S->getCond()))
382ef512b99SJustin Bogner         Visit(E);
383ef512b99SJustin Bogner       if ((E = S->getInc()))
384ef512b99SJustin Bogner         Visit(E);
385bf854f0fSBob Wilson       Visit(S->getBody());
386ef512b99SJustin Bogner     }
387bf854f0fSBob Wilson     /// Assign a counter for the body of a for-range loop.
388ef512b99SJustin Bogner     void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
389bf854f0fSBob Wilson       (*CounterMap)[S] = NextCounter++;
390bf854f0fSBob Wilson       Visit(S->getRangeStmt());
391bf854f0fSBob Wilson       Visit(S->getBeginEndStmt());
392bf854f0fSBob Wilson       Visit(S->getCond());
393bf854f0fSBob Wilson       Visit(S->getLoopVarStmt());
394ef512b99SJustin Bogner       Visit(S->getBody());
395bf854f0fSBob Wilson       Visit(S->getInc());
396ef512b99SJustin Bogner     }
397bf854f0fSBob Wilson     /// Assign a counter for the body of a for-collection loop.
398ef512b99SJustin Bogner     void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
399bf854f0fSBob Wilson       (*CounterMap)[S] = NextCounter++;
400ef512b99SJustin Bogner       Visit(S->getElement());
401ef512b99SJustin Bogner       Visit(S->getBody());
402ef512b99SJustin Bogner     }
403ef512b99SJustin Bogner     /// Assign a counter for the exit block of the switch statement.
404ef512b99SJustin Bogner     void VisitSwitchStmt(const SwitchStmt *S) {
405ef512b99SJustin Bogner       (*CounterMap)[S] = NextCounter++;
406ef512b99SJustin Bogner       Visit(S->getCond());
407ef512b99SJustin Bogner       Visit(S->getBody());
408ef512b99SJustin Bogner     }
409ef512b99SJustin Bogner     /// Assign a counter for a particular case in a switch. This counts jumps
410ef512b99SJustin Bogner     /// from the switch header as well as fallthrough from the case before this
411ef512b99SJustin Bogner     /// one.
412ef512b99SJustin Bogner     void VisitCaseStmt(const CaseStmt *S) {
413ef512b99SJustin Bogner       (*CounterMap)[S] = NextCounter++;
414ef512b99SJustin Bogner       Visit(S->getSubStmt());
415ef512b99SJustin Bogner     }
416ef512b99SJustin Bogner     /// Assign a counter for the default case of a switch statement. The count
417ef512b99SJustin Bogner     /// is the number of branches from the loop header to the default, and does
418ef512b99SJustin Bogner     /// not include fallthrough from previous cases. If we have multiple
419ef512b99SJustin Bogner     /// conditional branch blocks from the switch instruction to the default
420ef512b99SJustin Bogner     /// block, as with large GNU case ranges, this is the counter for the last
421ef512b99SJustin Bogner     /// edge in that series, rather than the first.
422ef512b99SJustin Bogner     void VisitDefaultStmt(const DefaultStmt *S) {
423ef512b99SJustin Bogner       (*CounterMap)[S] = NextCounter++;
424ef512b99SJustin Bogner       Visit(S->getSubStmt());
425ef512b99SJustin Bogner     }
426ef512b99SJustin Bogner     /// Assign a counter for the "then" part of an if statement. The count for
427ef512b99SJustin Bogner     /// the "else" part, if it exists, will be calculated from this counter.
428ef512b99SJustin Bogner     void VisitIfStmt(const IfStmt *S) {
429ef512b99SJustin Bogner       (*CounterMap)[S] = NextCounter++;
430ef512b99SJustin Bogner       Visit(S->getCond());
431ef512b99SJustin Bogner       Visit(S->getThen());
432ef512b99SJustin Bogner       if (S->getElse())
433ef512b99SJustin Bogner         Visit(S->getElse());
434ef512b99SJustin Bogner     }
435ef512b99SJustin Bogner     /// Assign a counter for the continuation block of a C++ try statement.
436ef512b99SJustin Bogner     void VisitCXXTryStmt(const CXXTryStmt *S) {
437ef512b99SJustin Bogner       (*CounterMap)[S] = NextCounter++;
438ef512b99SJustin Bogner       Visit(S->getTryBlock());
439ef512b99SJustin Bogner       for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
440ef512b99SJustin Bogner         Visit(S->getHandler(I));
441ef512b99SJustin Bogner     }
442ef512b99SJustin Bogner     /// Assign a counter for a catch statement's handler block.
443ef512b99SJustin Bogner     void VisitCXXCatchStmt(const CXXCatchStmt *S) {
444ef512b99SJustin Bogner       (*CounterMap)[S] = NextCounter++;
445ef512b99SJustin Bogner       Visit(S->getHandlerBlock());
446ef512b99SJustin Bogner     }
447ef512b99SJustin Bogner     /// Assign a counter for the "true" part of a conditional operator. The
448ef512b99SJustin Bogner     /// count in the "false" part will be calculated from this counter.
449ef512b99SJustin Bogner     void VisitConditionalOperator(const ConditionalOperator *E) {
450ef512b99SJustin Bogner       (*CounterMap)[E] = NextCounter++;
451ef512b99SJustin Bogner       Visit(E->getCond());
452ef512b99SJustin Bogner       Visit(E->getTrueExpr());
453ef512b99SJustin Bogner       Visit(E->getFalseExpr());
454ef512b99SJustin Bogner     }
455ef512b99SJustin Bogner     /// Assign a counter for the right hand side of a logical and operator.
456ef512b99SJustin Bogner     void VisitBinLAnd(const BinaryOperator *E) {
457ef512b99SJustin Bogner       (*CounterMap)[E] = NextCounter++;
458ef512b99SJustin Bogner       Visit(E->getLHS());
459ef512b99SJustin Bogner       Visit(E->getRHS());
460ef512b99SJustin Bogner     }
461ef512b99SJustin Bogner     /// Assign a counter for the right hand side of a logical or operator.
462ef512b99SJustin Bogner     void VisitBinLOr(const BinaryOperator *E) {
463ef512b99SJustin Bogner       (*CounterMap)[E] = NextCounter++;
464ef512b99SJustin Bogner       Visit(E->getLHS());
465ef512b99SJustin Bogner       Visit(E->getRHS());
466ef512b99SJustin Bogner     }
467ef512b99SJustin Bogner   };
468bf854f0fSBob Wilson 
469bf854f0fSBob Wilson   /// A StmtVisitor that propagates the raw counts through the AST and
470bf854f0fSBob Wilson   /// records the count at statements where the value may change.
471bf854f0fSBob Wilson   struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
472bf854f0fSBob Wilson     /// PGO state.
473bf854f0fSBob Wilson     CodeGenPGO &PGO;
474bf854f0fSBob Wilson 
475bf854f0fSBob Wilson     /// A flag that is set when the current count should be recorded on the
476bf854f0fSBob Wilson     /// next statement, such as at the exit of a loop.
477bf854f0fSBob Wilson     bool RecordNextStmtCount;
478bf854f0fSBob Wilson 
479bf854f0fSBob Wilson     /// The map of statements to count values.
480bf854f0fSBob Wilson     llvm::DenseMap<const Stmt*, uint64_t> *CountMap;
481bf854f0fSBob Wilson 
482bf854f0fSBob Wilson     /// BreakContinueStack - Keep counts of breaks and continues inside loops.
483bf854f0fSBob Wilson     struct BreakContinue {
484bf854f0fSBob Wilson       uint64_t BreakCount;
485bf854f0fSBob Wilson       uint64_t ContinueCount;
486bf854f0fSBob Wilson       BreakContinue() : BreakCount(0), ContinueCount(0) {}
487bf854f0fSBob Wilson     };
488bf854f0fSBob Wilson     SmallVector<BreakContinue, 8> BreakContinueStack;
489bf854f0fSBob Wilson 
490bf854f0fSBob Wilson     ComputeRegionCounts(llvm::DenseMap<const Stmt*, uint64_t> *CountMap,
491bf854f0fSBob Wilson                         CodeGenPGO &PGO) :
492bf854f0fSBob Wilson       PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {
493bf854f0fSBob Wilson     }
494bf854f0fSBob Wilson 
495bf854f0fSBob Wilson     void RecordStmtCount(const Stmt *S) {
496bf854f0fSBob Wilson       if (RecordNextStmtCount) {
497bf854f0fSBob Wilson         (*CountMap)[S] = PGO.getCurrentRegionCount();
498bf854f0fSBob Wilson         RecordNextStmtCount = false;
499bf854f0fSBob Wilson       }
500bf854f0fSBob Wilson     }
501bf854f0fSBob Wilson 
502bf854f0fSBob Wilson     void VisitStmt(const Stmt *S) {
503bf854f0fSBob Wilson       RecordStmtCount(S);
504bf854f0fSBob Wilson       for (Stmt::const_child_range I = S->children(); I; ++I) {
505bf854f0fSBob Wilson         if (*I)
506bf854f0fSBob Wilson          this->Visit(*I);
507bf854f0fSBob Wilson       }
508bf854f0fSBob Wilson     }
509bf854f0fSBob Wilson 
510bf854f0fSBob Wilson     void VisitFunctionDecl(const FunctionDecl *S) {
511bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S->getBody());
512bf854f0fSBob Wilson       Cnt.beginRegion();
513bf854f0fSBob Wilson       (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount();
514bf854f0fSBob Wilson       Visit(S->getBody());
515bf854f0fSBob Wilson     }
516bf854f0fSBob Wilson 
5175ec8fe19SBob Wilson     void VisitObjCMethodDecl(const ObjCMethodDecl *S) {
5185ec8fe19SBob Wilson       RegionCounter Cnt(PGO, S->getBody());
5195ec8fe19SBob Wilson       Cnt.beginRegion();
5205ec8fe19SBob Wilson       (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount();
5215ec8fe19SBob Wilson       Visit(S->getBody());
5225ec8fe19SBob Wilson     }
5235ec8fe19SBob Wilson 
524c845c00aSBob Wilson     void VisitBlockDecl(const BlockDecl *S) {
525c845c00aSBob Wilson       RegionCounter Cnt(PGO, S->getBody());
526c845c00aSBob Wilson       Cnt.beginRegion();
527c845c00aSBob Wilson       (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount();
528c845c00aSBob Wilson       Visit(S->getBody());
529c845c00aSBob Wilson     }
530c845c00aSBob Wilson 
531bf854f0fSBob Wilson     void VisitReturnStmt(const ReturnStmt *S) {
532bf854f0fSBob Wilson       RecordStmtCount(S);
533bf854f0fSBob Wilson       if (S->getRetValue())
534bf854f0fSBob Wilson         Visit(S->getRetValue());
535bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
536bf854f0fSBob Wilson       RecordNextStmtCount = true;
537bf854f0fSBob Wilson     }
538bf854f0fSBob Wilson 
539bf854f0fSBob Wilson     void VisitGotoStmt(const GotoStmt *S) {
540bf854f0fSBob Wilson       RecordStmtCount(S);
541bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
542bf854f0fSBob Wilson       RecordNextStmtCount = true;
543bf854f0fSBob Wilson     }
544bf854f0fSBob Wilson 
545bf854f0fSBob Wilson     void VisitLabelStmt(const LabelStmt *S) {
546bf854f0fSBob Wilson       RecordNextStmtCount = false;
547bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
548bf854f0fSBob Wilson       Cnt.beginRegion();
549bf854f0fSBob Wilson       (*CountMap)[S] = PGO.getCurrentRegionCount();
550bf854f0fSBob Wilson       Visit(S->getSubStmt());
551bf854f0fSBob Wilson     }
552bf854f0fSBob Wilson 
553bf854f0fSBob Wilson     void VisitBreakStmt(const BreakStmt *S) {
554bf854f0fSBob Wilson       RecordStmtCount(S);
555bf854f0fSBob Wilson       assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
556bf854f0fSBob Wilson       BreakContinueStack.back().BreakCount += PGO.getCurrentRegionCount();
557bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
558bf854f0fSBob Wilson       RecordNextStmtCount = true;
559bf854f0fSBob Wilson     }
560bf854f0fSBob Wilson 
561bf854f0fSBob Wilson     void VisitContinueStmt(const ContinueStmt *S) {
562bf854f0fSBob Wilson       RecordStmtCount(S);
563bf854f0fSBob Wilson       assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
564bf854f0fSBob Wilson       BreakContinueStack.back().ContinueCount += PGO.getCurrentRegionCount();
565bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
566bf854f0fSBob Wilson       RecordNextStmtCount = true;
567bf854f0fSBob Wilson     }
568bf854f0fSBob Wilson 
569bf854f0fSBob Wilson     void VisitWhileStmt(const WhileStmt *S) {
570bf854f0fSBob Wilson       RecordStmtCount(S);
571bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
572bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
573bf854f0fSBob Wilson       // Visit the body region first so the break/continue adjustments can be
574bf854f0fSBob Wilson       // included when visiting the condition.
575bf854f0fSBob Wilson       Cnt.beginRegion();
576bf854f0fSBob Wilson       (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount();
577bf854f0fSBob Wilson       Visit(S->getBody());
578bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
579bf854f0fSBob Wilson 
580bf854f0fSBob Wilson       // ...then go back and propagate counts through the condition. The count
581bf854f0fSBob Wilson       // at the start of the condition is the sum of the incoming edges,
582bf854f0fSBob Wilson       // the backedge from the end of the loop body, and the edges from
583bf854f0fSBob Wilson       // continue statements.
584bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
585bf854f0fSBob Wilson       Cnt.setCurrentRegionCount(Cnt.getParentCount() +
586bf854f0fSBob Wilson                                 Cnt.getAdjustedCount() + BC.ContinueCount);
587bf854f0fSBob Wilson       (*CountMap)[S->getCond()] = PGO.getCurrentRegionCount();
588bf854f0fSBob Wilson       Visit(S->getCond());
589bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
590bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
591bf854f0fSBob Wilson       RecordNextStmtCount = true;
592bf854f0fSBob Wilson     }
593bf854f0fSBob Wilson 
594bf854f0fSBob Wilson     void VisitDoStmt(const DoStmt *S) {
595bf854f0fSBob Wilson       RecordStmtCount(S);
596bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
597bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
598bf854f0fSBob Wilson       Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
599bf854f0fSBob Wilson       (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount();
600bf854f0fSBob Wilson       Visit(S->getBody());
601bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
602bf854f0fSBob Wilson 
603bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
604bf854f0fSBob Wilson       // The count at the start of the condition is equal to the count at the
605bf854f0fSBob Wilson       // end of the body. The adjusted count does not include either the
606bf854f0fSBob Wilson       // fall-through count coming into the loop or the continue count, so add
607bf854f0fSBob Wilson       // both of those separately. This is coincidentally the same equation as
608bf854f0fSBob Wilson       // with while loops but for different reasons.
609bf854f0fSBob Wilson       Cnt.setCurrentRegionCount(Cnt.getParentCount() +
610bf854f0fSBob Wilson                                 Cnt.getAdjustedCount() + BC.ContinueCount);
611bf854f0fSBob Wilson       (*CountMap)[S->getCond()] = PGO.getCurrentRegionCount();
612bf854f0fSBob Wilson       Visit(S->getCond());
613bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
614bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
615bf854f0fSBob Wilson       RecordNextStmtCount = true;
616bf854f0fSBob Wilson     }
617bf854f0fSBob Wilson 
618bf854f0fSBob Wilson     void VisitForStmt(const ForStmt *S) {
619bf854f0fSBob Wilson       RecordStmtCount(S);
620bf854f0fSBob Wilson       if (S->getInit())
621bf854f0fSBob Wilson         Visit(S->getInit());
622bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
623bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
624bf854f0fSBob Wilson       // Visit the body region first. (This is basically the same as a while
625bf854f0fSBob Wilson       // loop; see further comments in VisitWhileStmt.)
626bf854f0fSBob Wilson       Cnt.beginRegion();
627bf854f0fSBob Wilson       (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount();
628bf854f0fSBob Wilson       Visit(S->getBody());
629bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
630bf854f0fSBob Wilson 
631bf854f0fSBob Wilson       // The increment is essentially part of the body but it needs to include
632bf854f0fSBob Wilson       // the count for all the continue statements.
633bf854f0fSBob Wilson       if (S->getInc()) {
634bf854f0fSBob Wilson         Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
635bf854f0fSBob Wilson                                   BreakContinueStack.back().ContinueCount);
636bf854f0fSBob Wilson         (*CountMap)[S->getInc()] = PGO.getCurrentRegionCount();
637bf854f0fSBob Wilson         Visit(S->getInc());
638bf854f0fSBob Wilson         Cnt.adjustForControlFlow();
639bf854f0fSBob Wilson       }
640bf854f0fSBob Wilson 
641bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
642bf854f0fSBob Wilson 
643bf854f0fSBob Wilson       // ...then go back and propagate counts through the condition.
644bf854f0fSBob Wilson       if (S->getCond()) {
645bf854f0fSBob Wilson         Cnt.setCurrentRegionCount(Cnt.getParentCount() +
646bf854f0fSBob Wilson                                   Cnt.getAdjustedCount() +
647bf854f0fSBob Wilson                                   BC.ContinueCount);
648bf854f0fSBob Wilson         (*CountMap)[S->getCond()] = PGO.getCurrentRegionCount();
649bf854f0fSBob Wilson         Visit(S->getCond());
650bf854f0fSBob Wilson         Cnt.adjustForControlFlow();
651bf854f0fSBob Wilson       }
652bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
653bf854f0fSBob Wilson       RecordNextStmtCount = true;
654bf854f0fSBob Wilson     }
655bf854f0fSBob Wilson 
656bf854f0fSBob Wilson     void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
657bf854f0fSBob Wilson       RecordStmtCount(S);
658bf854f0fSBob Wilson       Visit(S->getRangeStmt());
659bf854f0fSBob Wilson       Visit(S->getBeginEndStmt());
660bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
661bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
662bf854f0fSBob Wilson       // Visit the body region first. (This is basically the same as a while
663bf854f0fSBob Wilson       // loop; see further comments in VisitWhileStmt.)
664bf854f0fSBob Wilson       Cnt.beginRegion();
665bf854f0fSBob Wilson       (*CountMap)[S->getLoopVarStmt()] = PGO.getCurrentRegionCount();
666bf854f0fSBob Wilson       Visit(S->getLoopVarStmt());
667bf854f0fSBob Wilson       Visit(S->getBody());
668bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
669bf854f0fSBob Wilson 
670bf854f0fSBob Wilson       // The increment is essentially part of the body but it needs to include
671bf854f0fSBob Wilson       // the count for all the continue statements.
672bf854f0fSBob Wilson       Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
673bf854f0fSBob Wilson                                 BreakContinueStack.back().ContinueCount);
674bf854f0fSBob Wilson       (*CountMap)[S->getInc()] = PGO.getCurrentRegionCount();
675bf854f0fSBob Wilson       Visit(S->getInc());
676bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
677bf854f0fSBob Wilson 
678bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
679bf854f0fSBob Wilson 
680bf854f0fSBob Wilson       // ...then go back and propagate counts through the condition.
681bf854f0fSBob Wilson       Cnt.setCurrentRegionCount(Cnt.getParentCount() +
682bf854f0fSBob Wilson                                 Cnt.getAdjustedCount() +
683bf854f0fSBob Wilson                                 BC.ContinueCount);
684bf854f0fSBob Wilson       (*CountMap)[S->getCond()] = PGO.getCurrentRegionCount();
685bf854f0fSBob Wilson       Visit(S->getCond());
686bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
687bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
688bf854f0fSBob Wilson       RecordNextStmtCount = true;
689bf854f0fSBob Wilson     }
690bf854f0fSBob Wilson 
691bf854f0fSBob Wilson     void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
692bf854f0fSBob Wilson       RecordStmtCount(S);
693bf854f0fSBob Wilson       Visit(S->getElement());
694bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
695bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
696bf854f0fSBob Wilson       Cnt.beginRegion();
697bf854f0fSBob Wilson       (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount();
698bf854f0fSBob Wilson       Visit(S->getBody());
699bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
700bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
701bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
702bf854f0fSBob Wilson       RecordNextStmtCount = true;
703bf854f0fSBob Wilson     }
704bf854f0fSBob Wilson 
705bf854f0fSBob Wilson     void VisitSwitchStmt(const SwitchStmt *S) {
706bf854f0fSBob Wilson       RecordStmtCount(S);
707bf854f0fSBob Wilson       Visit(S->getCond());
708bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
709bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
710bf854f0fSBob Wilson       Visit(S->getBody());
711bf854f0fSBob Wilson       // If the switch is inside a loop, add the continue counts.
712bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
713bf854f0fSBob Wilson       if (!BreakContinueStack.empty())
714bf854f0fSBob Wilson         BreakContinueStack.back().ContinueCount += BC.ContinueCount;
715bf854f0fSBob Wilson       RegionCounter ExitCnt(PGO, S);
716bf854f0fSBob Wilson       ExitCnt.beginRegion();
717bf854f0fSBob Wilson       RecordNextStmtCount = true;
718bf854f0fSBob Wilson     }
719bf854f0fSBob Wilson 
720bf854f0fSBob Wilson     void VisitCaseStmt(const CaseStmt *S) {
721bf854f0fSBob Wilson       RecordNextStmtCount = false;
722bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
723bf854f0fSBob Wilson       Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
724bf854f0fSBob Wilson       (*CountMap)[S] = Cnt.getCount();
725bf854f0fSBob Wilson       RecordNextStmtCount = true;
726bf854f0fSBob Wilson       Visit(S->getSubStmt());
727bf854f0fSBob Wilson     }
728bf854f0fSBob Wilson 
729bf854f0fSBob Wilson     void VisitDefaultStmt(const DefaultStmt *S) {
730bf854f0fSBob Wilson       RecordNextStmtCount = false;
731bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
732bf854f0fSBob Wilson       Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
733bf854f0fSBob Wilson       (*CountMap)[S] = Cnt.getCount();
734bf854f0fSBob Wilson       RecordNextStmtCount = true;
735bf854f0fSBob Wilson       Visit(S->getSubStmt());
736bf854f0fSBob Wilson     }
737bf854f0fSBob Wilson 
738bf854f0fSBob Wilson     void VisitIfStmt(const IfStmt *S) {
739bf854f0fSBob Wilson       RecordStmtCount(S);
740bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
741bf854f0fSBob Wilson       Visit(S->getCond());
742bf854f0fSBob Wilson 
743bf854f0fSBob Wilson       Cnt.beginRegion();
744bf854f0fSBob Wilson       (*CountMap)[S->getThen()] = PGO.getCurrentRegionCount();
745bf854f0fSBob Wilson       Visit(S->getThen());
746bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
747bf854f0fSBob Wilson 
748bf854f0fSBob Wilson       if (S->getElse()) {
749bf854f0fSBob Wilson         Cnt.beginElseRegion();
750bf854f0fSBob Wilson         (*CountMap)[S->getElse()] = PGO.getCurrentRegionCount();
751bf854f0fSBob Wilson         Visit(S->getElse());
752bf854f0fSBob Wilson         Cnt.adjustForControlFlow();
753bf854f0fSBob Wilson       }
754bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(0);
755bf854f0fSBob Wilson       RecordNextStmtCount = true;
756bf854f0fSBob Wilson     }
757bf854f0fSBob Wilson 
758bf854f0fSBob Wilson     void VisitCXXTryStmt(const CXXTryStmt *S) {
759bf854f0fSBob Wilson       RecordStmtCount(S);
760bf854f0fSBob Wilson       Visit(S->getTryBlock());
761bf854f0fSBob Wilson       for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
762bf854f0fSBob Wilson         Visit(S->getHandler(I));
763bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
764bf854f0fSBob Wilson       Cnt.beginRegion();
765bf854f0fSBob Wilson       RecordNextStmtCount = true;
766bf854f0fSBob Wilson     }
767bf854f0fSBob Wilson 
768bf854f0fSBob Wilson     void VisitCXXCatchStmt(const CXXCatchStmt *S) {
769bf854f0fSBob Wilson       RecordNextStmtCount = false;
770bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
771bf854f0fSBob Wilson       Cnt.beginRegion();
772bf854f0fSBob Wilson       (*CountMap)[S] = PGO.getCurrentRegionCount();
773bf854f0fSBob Wilson       Visit(S->getHandlerBlock());
774bf854f0fSBob Wilson     }
775bf854f0fSBob Wilson 
776bf854f0fSBob Wilson     void VisitConditionalOperator(const ConditionalOperator *E) {
777bf854f0fSBob Wilson       RecordStmtCount(E);
778bf854f0fSBob Wilson       RegionCounter Cnt(PGO, E);
779bf854f0fSBob Wilson       Visit(E->getCond());
780bf854f0fSBob Wilson 
781bf854f0fSBob Wilson       Cnt.beginRegion();
782bf854f0fSBob Wilson       (*CountMap)[E->getTrueExpr()] = PGO.getCurrentRegionCount();
783bf854f0fSBob Wilson       Visit(E->getTrueExpr());
784bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
785bf854f0fSBob Wilson 
786bf854f0fSBob Wilson       Cnt.beginElseRegion();
787bf854f0fSBob Wilson       (*CountMap)[E->getFalseExpr()] = PGO.getCurrentRegionCount();
788bf854f0fSBob Wilson       Visit(E->getFalseExpr());
789bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
790bf854f0fSBob Wilson 
791bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(0);
792bf854f0fSBob Wilson       RecordNextStmtCount = true;
793bf854f0fSBob Wilson     }
794bf854f0fSBob Wilson 
795bf854f0fSBob Wilson     void VisitBinLAnd(const BinaryOperator *E) {
796bf854f0fSBob Wilson       RecordStmtCount(E);
797bf854f0fSBob Wilson       RegionCounter Cnt(PGO, E);
798bf854f0fSBob Wilson       Visit(E->getLHS());
799bf854f0fSBob Wilson       Cnt.beginRegion();
800bf854f0fSBob Wilson       (*CountMap)[E->getRHS()] = PGO.getCurrentRegionCount();
801bf854f0fSBob Wilson       Visit(E->getRHS());
802bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
803bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(0);
804bf854f0fSBob Wilson       RecordNextStmtCount = true;
805bf854f0fSBob Wilson     }
806bf854f0fSBob Wilson 
807bf854f0fSBob Wilson     void VisitBinLOr(const BinaryOperator *E) {
808bf854f0fSBob Wilson       RecordStmtCount(E);
809bf854f0fSBob Wilson       RegionCounter Cnt(PGO, E);
810bf854f0fSBob Wilson       Visit(E->getLHS());
811bf854f0fSBob Wilson       Cnt.beginRegion();
812bf854f0fSBob Wilson       (*CountMap)[E->getRHS()] = PGO.getCurrentRegionCount();
813bf854f0fSBob Wilson       Visit(E->getRHS());
814bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
815bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(0);
816bf854f0fSBob Wilson       RecordNextStmtCount = true;
817bf854f0fSBob Wilson     }
818bf854f0fSBob Wilson   };
819ef512b99SJustin Bogner }
820ef512b99SJustin Bogner 
821da1ebedeSBob Wilson void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
822ef512b99SJustin Bogner   bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
823d66a17d0SJustin Bogner   PGOProfileData *PGOData = CGM.getPGOData();
824d66a17d0SJustin Bogner   if (!InstrumentRegions && !PGOData)
825ef512b99SJustin Bogner     return;
826ef512b99SJustin Bogner   if (!D)
827ef512b99SJustin Bogner     return;
828da1ebedeSBob Wilson   setFuncName(Fn);
829*2fe531cbSDuncan P. N. Exon Smith   FuncLinkage = Fn->getLinkage();
830ef512b99SJustin Bogner   mapRegionCounters(D);
831ef512b99SJustin Bogner   if (InstrumentRegions)
832ef512b99SJustin Bogner     emitCounterVariables();
833d66a17d0SJustin Bogner   if (PGOData) {
834d66a17d0SJustin Bogner     loadRegionCounts(PGOData);
835bf854f0fSBob Wilson     computeRegionCounts(D);
836d66a17d0SJustin Bogner     applyFunctionAttributes(PGOData, Fn);
837bf854f0fSBob Wilson   }
838ef512b99SJustin Bogner }
839ef512b99SJustin Bogner 
840ef512b99SJustin Bogner void CodeGenPGO::mapRegionCounters(const Decl *D) {
841ef512b99SJustin Bogner   RegionCounterMap = new llvm::DenseMap<const Stmt*, unsigned>();
842ef512b99SJustin Bogner   MapRegionCounters Walker(RegionCounterMap);
843ef512b99SJustin Bogner   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
844ef512b99SJustin Bogner     Walker.VisitFunctionDecl(FD);
8455ec8fe19SBob Wilson   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
8465ec8fe19SBob Wilson     Walker.VisitObjCMethodDecl(MD);
847c845c00aSBob Wilson   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
848c845c00aSBob Wilson     Walker.VisitBlockDecl(BD);
849ef512b99SJustin Bogner   NumRegionCounters = Walker.NextCounter;
850ef512b99SJustin Bogner }
851ef512b99SJustin Bogner 
852bf854f0fSBob Wilson void CodeGenPGO::computeRegionCounts(const Decl *D) {
853bf854f0fSBob Wilson   StmtCountMap = new llvm::DenseMap<const Stmt*, uint64_t>();
854bf854f0fSBob Wilson   ComputeRegionCounts Walker(StmtCountMap, *this);
855bf854f0fSBob Wilson   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
856bf854f0fSBob Wilson     Walker.VisitFunctionDecl(FD);
8575ec8fe19SBob Wilson   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
8585ec8fe19SBob Wilson     Walker.VisitObjCMethodDecl(MD);
859c845c00aSBob Wilson   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
860c845c00aSBob Wilson     Walker.VisitBlockDecl(BD);
861bf854f0fSBob Wilson }
862bf854f0fSBob Wilson 
863d66a17d0SJustin Bogner void CodeGenPGO::applyFunctionAttributes(PGOProfileData *PGOData,
8644c9c45c0SJustin Bogner                                          llvm::Function *Fn) {
8654c9c45c0SJustin Bogner   if (!haveRegionCounts())
8664c9c45c0SJustin Bogner     return;
8674c9c45c0SJustin Bogner 
868d66a17d0SJustin Bogner   uint64_t MaxFunctionCount = PGOData->getMaximumFunctionCount();
8694c9c45c0SJustin Bogner   uint64_t FunctionCount = getRegionCount(0);
8704c9c45c0SJustin Bogner   if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount))
8714c9c45c0SJustin Bogner     // Turn on InlineHint attribute for hot functions.
8724c9c45c0SJustin Bogner     // FIXME: 30% is from preliminary tuning on SPEC, it may not be optimal.
8734c9c45c0SJustin Bogner     Fn->addFnAttr(llvm::Attribute::InlineHint);
8744c9c45c0SJustin Bogner   else if (FunctionCount <= (uint64_t)(0.01 * (double)MaxFunctionCount))
8754c9c45c0SJustin Bogner     // Turn on Cold attribute for cold functions.
8764c9c45c0SJustin Bogner     // FIXME: 1% is from preliminary tuning on SPEC, it may not be optimal.
8774c9c45c0SJustin Bogner     Fn->addFnAttr(llvm::Attribute::Cold);
8784c9c45c0SJustin Bogner }
8794c9c45c0SJustin Bogner 
880ef512b99SJustin Bogner void CodeGenPGO::emitCounterVariables() {
881ef512b99SJustin Bogner   llvm::LLVMContext &Ctx = CGM.getLLVMContext();
882ef512b99SJustin Bogner   llvm::ArrayType *CounterTy = llvm::ArrayType::get(llvm::Type::getInt64Ty(Ctx),
883ef512b99SJustin Bogner                                                     NumRegionCounters);
884ef512b99SJustin Bogner   RegionCounters =
885*2fe531cbSDuncan P. N. Exon Smith     new llvm::GlobalVariable(CGM.getModule(), CounterTy, false, FuncLinkage,
886ef512b99SJustin Bogner                              llvm::Constant::getNullValue(CounterTy),
887*2fe531cbSDuncan P. N. Exon Smith                              getFuncVarName("counters"));
888*2fe531cbSDuncan P. N. Exon Smith   RegionCounters->setAlignment(8);
889*2fe531cbSDuncan P. N. Exon Smith   RegionCounters->setSection(getCountersSection(CGM));
890ef512b99SJustin Bogner }
891ef512b99SJustin Bogner 
892ef512b99SJustin Bogner void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) {
893749ebc7fSBob Wilson   if (!RegionCounters)
894ef512b99SJustin Bogner     return;
895ef512b99SJustin Bogner   llvm::Value *Addr =
896ef512b99SJustin Bogner     Builder.CreateConstInBoundsGEP2_64(RegionCounters, 0, Counter);
897ef512b99SJustin Bogner   llvm::Value *Count = Builder.CreateLoad(Addr, "pgocount");
898ef512b99SJustin Bogner   Count = Builder.CreateAdd(Count, Builder.getInt64(1));
899ef512b99SJustin Bogner   Builder.CreateStore(Count, Addr);
900ef512b99SJustin Bogner }
901ef512b99SJustin Bogner 
902d66a17d0SJustin Bogner void CodeGenPGO::loadRegionCounts(PGOProfileData *PGOData) {
903ef512b99SJustin Bogner   // For now, ignore the counts from the PGO data file only if the number of
904ef512b99SJustin Bogner   // counters does not match. This could be tightened down in the future to
905ef512b99SJustin Bogner   // ignore counts when the input changes in various ways, e.g., by comparing a
906ef512b99SJustin Bogner   // hash value based on some characteristics of the input.
907ef512b99SJustin Bogner   RegionCounts = new std::vector<uint64_t>();
908d66a17d0SJustin Bogner   if (PGOData->getFunctionCounts(getFuncName(), *RegionCounts) ||
909ef512b99SJustin Bogner       RegionCounts->size() != NumRegionCounters) {
910ef512b99SJustin Bogner     delete RegionCounts;
911ef512b99SJustin Bogner     RegionCounts = 0;
912ef512b99SJustin Bogner   }
913ef512b99SJustin Bogner }
914ef512b99SJustin Bogner 
915ef512b99SJustin Bogner void CodeGenPGO::destroyRegionCounters() {
916ef512b99SJustin Bogner   if (RegionCounterMap != 0)
917ef512b99SJustin Bogner     delete RegionCounterMap;
918bf854f0fSBob Wilson   if (StmtCountMap != 0)
919bf854f0fSBob Wilson     delete StmtCountMap;
920ef512b99SJustin Bogner   if (RegionCounts != 0)
921ef512b99SJustin Bogner     delete RegionCounts;
922ef512b99SJustin Bogner }
923ef512b99SJustin Bogner 
92438402dc9SDuncan P. N. Exon Smith /// \brief Calculate what to divide by to scale weights.
92538402dc9SDuncan P. N. Exon Smith ///
92638402dc9SDuncan P. N. Exon Smith /// Given the maximum weight, calculate a divisor that will scale all the
92738402dc9SDuncan P. N. Exon Smith /// weights to strictly less than UINT32_MAX.
92838402dc9SDuncan P. N. Exon Smith static uint64_t calculateWeightScale(uint64_t MaxWeight) {
92938402dc9SDuncan P. N. Exon Smith   return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
93038402dc9SDuncan P. N. Exon Smith }
93138402dc9SDuncan P. N. Exon Smith 
93238402dc9SDuncan P. N. Exon Smith /// \brief Scale an individual branch weight (and add 1).
93338402dc9SDuncan P. N. Exon Smith ///
93438402dc9SDuncan P. N. Exon Smith /// Scale a 64-bit weight down to 32-bits using \c Scale.
93538402dc9SDuncan P. N. Exon Smith ///
93638402dc9SDuncan P. N. Exon Smith /// According to Laplace's Rule of Succession, it is better to compute the
93738402dc9SDuncan P. N. Exon Smith /// weight based on the count plus 1, so universally add 1 to the value.
93838402dc9SDuncan P. N. Exon Smith ///
93938402dc9SDuncan P. N. Exon Smith /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
94038402dc9SDuncan P. N. Exon Smith /// greater than \c Weight.
94138402dc9SDuncan P. N. Exon Smith static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
94238402dc9SDuncan P. N. Exon Smith   assert(Scale && "scale by 0?");
94338402dc9SDuncan P. N. Exon Smith   uint64_t Scaled = Weight / Scale + 1;
94438402dc9SDuncan P. N. Exon Smith   assert(Scaled <= UINT32_MAX && "overflow 32-bits");
94538402dc9SDuncan P. N. Exon Smith   return Scaled;
94638402dc9SDuncan P. N. Exon Smith }
94738402dc9SDuncan P. N. Exon Smith 
948ef512b99SJustin Bogner llvm::MDNode *CodeGenPGO::createBranchWeights(uint64_t TrueCount,
949ef512b99SJustin Bogner                                               uint64_t FalseCount) {
95038402dc9SDuncan P. N. Exon Smith   // Check for empty weights.
951ef512b99SJustin Bogner   if (!TrueCount && !FalseCount)
952ef512b99SJustin Bogner     return 0;
953ef512b99SJustin Bogner 
95438402dc9SDuncan P. N. Exon Smith   // Calculate how to scale down to 32-bits.
95538402dc9SDuncan P. N. Exon Smith   uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
95638402dc9SDuncan P. N. Exon Smith 
957ef512b99SJustin Bogner   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
95838402dc9SDuncan P. N. Exon Smith   return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
95938402dc9SDuncan P. N. Exon Smith                                       scaleBranchWeight(FalseCount, Scale));
960ef512b99SJustin Bogner }
961ef512b99SJustin Bogner 
96295a27b0eSBob Wilson llvm::MDNode *CodeGenPGO::createBranchWeights(ArrayRef<uint64_t> Weights) {
96338402dc9SDuncan P. N. Exon Smith   // We need at least two elements to create meaningful weights.
96438402dc9SDuncan P. N. Exon Smith   if (Weights.size() < 2)
96538402dc9SDuncan P. N. Exon Smith     return 0;
96638402dc9SDuncan P. N. Exon Smith 
96738402dc9SDuncan P. N. Exon Smith   // Calculate how to scale down to 32-bits.
96838402dc9SDuncan P. N. Exon Smith   uint64_t Scale = calculateWeightScale(*std::max_element(Weights.begin(),
96938402dc9SDuncan P. N. Exon Smith                                                           Weights.end()));
97038402dc9SDuncan P. N. Exon Smith 
971ef512b99SJustin Bogner   SmallVector<uint32_t, 16> ScaledWeights;
972ef512b99SJustin Bogner   ScaledWeights.reserve(Weights.size());
97338402dc9SDuncan P. N. Exon Smith   for (uint64_t W : Weights)
97438402dc9SDuncan P. N. Exon Smith     ScaledWeights.push_back(scaleBranchWeight(W, Scale));
97538402dc9SDuncan P. N. Exon Smith 
97638402dc9SDuncan P. N. Exon Smith   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
977ef512b99SJustin Bogner   return MDHelper.createBranchWeights(ScaledWeights);
978ef512b99SJustin Bogner }
979bf854f0fSBob Wilson 
980bf854f0fSBob Wilson llvm::MDNode *CodeGenPGO::createLoopWeights(const Stmt *Cond,
981bf854f0fSBob Wilson                                             RegionCounter &Cnt) {
982bf854f0fSBob Wilson   if (!haveRegionCounts())
983bf854f0fSBob Wilson     return 0;
984bf854f0fSBob Wilson   uint64_t LoopCount = Cnt.getCount();
985bf854f0fSBob Wilson   uint64_t CondCount = 0;
986bf854f0fSBob Wilson   bool Found = getStmtCount(Cond, CondCount);
987bf854f0fSBob Wilson   assert(Found && "missing expected loop condition count");
988bf854f0fSBob Wilson   (void)Found;
989bf854f0fSBob Wilson   if (CondCount == 0)
990bf854f0fSBob Wilson     return 0;
991bf854f0fSBob Wilson   return createBranchWeights(LoopCount,
992bf854f0fSBob Wilson                              std::max(CondCount, LoopCount) - LoopCount);
993bf854f0fSBob Wilson }
994